In my application there lies a code which works abruptly sometimes, its about getting a week interval using the java calendar object through Calendar.DAY_OF_WEEK.
The code checked for monday as start of week and sunday as end of week like:
fromCal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
toCal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
the toCal is set as the last sunday instead of coming sunday.
Is there any alternate way to do this other then this kind of hard coding.
Appriciate the help in advance.
Thanks,
Vaibhav
I guess you have to set the start of week to monday, otherwise last sunday IS the sunday of the week.
setFirstDayOfWeek
public void setFirstDayOfWeek(int value)
Sets what the first day of the week is; e.g., Sunday in US, Monday in France.
**Parameters:**
value - the given first day of the week.
Java Calender Doc
The issue is in locale. In English(US), Sunday is the first day of the week.
Check this code:
Calendar cal = Calendar.getInstance(Locale.ENGLISH);
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
System.out.println("FirstDayOfWeek="+cal.getFirstDayOfWeek());
System.out.println(cal.getTime().toString());
cal = Calendar.getInstance(Locale.FRANCE);
System.out.println("FirstDayOfWeek="+cal.getFirstDayOfWeek());
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
System.out.println(cal.getTime().toString());
Be very clear on your desired behaviour here. You start with a calendar object whose "now" is some day of the week, perhaps "today". You the call set(DAY_OF_WEEK, ...). What effect do you desire if the Calendar's today is Tuesday? Sunday? Monday?
As observed in other answers, what happens depends upon the Calendar's opinion about what the First day of week is. So first set that to your chosen value. You will then (according to this answer get a Sunday and a Monday in the current week, which may not be what you want - what exactly do you need if today is Sunday? - some systems might actually be "thinking" about the next week.
Personally I might get my Monday according to some business rules and the get the Sunday after by adding 6 days.
Related
I am running the below code on 6/7/2018 in order to omit weekends from any dates returned. However the code seems to determine the below days as the weekend.
13/7/2018 - Friday & 14/7/2018 - Saturday
rather than
14/7/2018 - Saturday & 15/7/2018 - Sunday
I am updating the field indicated to increase / reduce the amount of days in the future I want to select.
If I input 5 days the date returned is 12/7/2018 and if I input 6 days the date returned is 15/7/2018.
Is there something obvious I am missing, any help would be much appreciated.
Date date=new Date();
Calendar calendar = Calendar.getInstance();
date=calendar.getTime();
SimpleDateFormat s;
s=new SimpleDateFormat("dd/MM/yyyy");
System.out.println(s.format(date));
int days = 5; //I am updating this value to increase and decrease days
for(int i=0;i<days;)
{
calendar.add(Calendar.DAY_OF_MONTH, 1);
//here even sat and sun are added
//but at the end it goes to the correct week day.
//because i is only increased if it is week day
if(calendar.get(Calendar.DAY_OF_WEEK)<=5)
{
i++;
}
}
date=calendar.getTime();
s=new SimpleDateFormat("dd/MM/yyyy");
System.out.println(s.format(date));
DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
.withLocale(Locale.UK);
LocalDate date = LocalDate.now(ZoneId.of("Pacific/Truk"));
System.out.println(date.format(dateFormatter));
int days = 5;
int i = 0;
while (i < days) {
date = date.plusDays(1);
DayOfWeek day = date.getDayOfWeek();
if (! day.equals(DayOfWeek.SATURDAY) && ! day.equals(DayOfWeek.SUNDAY)) {
i++;
}
}
System.out.println(date.format(dateFormatter));
Output today (Sunday 8th July):
08/07/2018
13/07/2018
13th July is next Friday, so obviously it didn’t take Friday as weekend.
Is there something obvious I am missing(?)
It don’t think it’s that obvious: The Calendar class numbers the days of the week from 1 for Sunday through 7 for Saturday. This comes from an American understanding of weeks. So when your condition was that the day of week should be less than or equal to 5, you included Sunday (1) through Thursday (5) and filtered out Friday (6) and Saturday.
…if you could point me in the right direction to the documentation…
To find this information in the documentation you would have to look under each constant for day of week, SUNDAY, etc., and there follow the link Constant Field Values. See the links at the bottom of this answer.
The Calendar class has proved poorly designed (despite attempts to fix the problems with Date) and is now long outdated too. Instead I recommend that you use java.time, the modern Java date and time API. Which I of course do in the snippet above.
One of many problems with Calendar is the use of int for day of week (and other items that have names rather than being numbers). It’s unnatural and very easy to confuse. One may say that you reinforced the problem by comparing to 5 rather than to Calendar.FRIDAY, but because of the American numbering the latter wouldn’t have solved your issue either. java.time’s DayOfWeek is an enum and doesn’t invite for comparing using “less than” or “is before” (though you may, and it would work in your case). The code referring to named constants SATURDAY and SUNDAY is not only clearer to read, it is also less error-prone.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Documentation of LocalDate and DayOfWeek
Calendar.SUNDAYdocumentation
Constant Field Values documentation
I'm trying to get the sunday of the same week as a given date.
During this I ran into this problem:
Calendar calendar = Calendar.getInstance(Locale.GERMANY);
calendar.set(2017, 11, 11);
calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
System.out.println(calendar.getTime().toString());
results in "Sun Jan 07 11:18:42 CET 2018"
but
Calendar calendar2 = Calendar.getInstance(Locale.GERMANY);
calendar2.set(2017, 11, 11);
calendar2.getTime();
calendar2.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
System.out.println(calendar2.getTime().toString());
gives me the correct Date "Sun Dec 17 11:18:42 CET 2017"
Can someone explain why the first exmple is behaving this way? Is this really intended?
Thanks
Basically, the Calendar API is horrible, and should be avoided. It's not documented terribly clearly, but I think I see where it's going, and it's behaving as intended in this situation. By that I mean it's following the intention of the API authors, not the intention of you or anyone reading your code...
From the documentation:
The calendar field values can be set by calling the set methods. Any field values set in a Calendar will not be interpreted until it needs to calculate its time value (milliseconds from the Epoch) or values of the calendar fields. Calling the get, getTimeInMillis, getTime, add and roll involves such calculation.
And then:
When computing a date and time from the calendar fields, there may be insufficient information for the computation (such as only year and month with no day of month), or there may be inconsistent information (such as Tuesday, July 15, 1996 (Gregorian) -- July 15, 1996 is actually a Monday). Calendar will resolve calendar field values to determine the date and time in the following way.
If there is any conflict in calendar field values, Calendar gives priorities to calendar fields that have been set more recently. The following are the default combinations of the calendar fields. The most recent combination, as determined by the most recently set single field, will be used.
For the date fields:
YEAR + MONTH + DAY_OF_MONTH
YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
YEAR + DAY_OF_YEAR
YEAR + DAY_OF_WEEK + WEEK_OF_YEAR
In the first example, the fact that the last field set was "day of week" means it will then use the YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK calculation (I think). The year and month have been set to December 2017, but the week-of-month is the current week-of-month, which is the week 5 of January 2018... so when you then say to set the day of week to Sunday, it's finding the Sunday in the "week 5" of December 2017. December only had 4 weeks, so it's effectively rolling it forward... I think. It's all messy and you shouldn't have to think about that, basically.
In the second example, calling getTime() "locks in" the year/month/day you've specified, and computes the other fields. When you set the day of week, that's then adjusting it within the existing computed fields.
Basically, avoid this API as far as you possibly can. Use java.time, which is a far cleaner date/time API.
As Jon Skeet said, avoid Calendar. For your case it is truly horrible, and it’s poorly designed in general. Instead do
WeekFields weekFieldsForLocale = WeekFields.of(Locale.GERMANY);
// To find out which number Sunday has in the locale,
// grab any Sunday and get its weekFieldsForLocale.dayOfWeek()
int dayNumberOfSundayInLocale = LocalDate.now()
.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY))
.get(weekFieldsForLocale.dayOfWeek());
LocalDate date = LocalDate.of(2017, Month.DECEMBER, 11);
LocalDate sunday
= date.with(weekFieldsForLocale.dayOfWeek(), dayNumberOfSundayInLocale);
System.out.println(sunday);
This prints the expected date
2017-12-17
As others have already mentioned, the solution is to use java.time, the modern Java date and time API. Also generally it is so much nicer to work with. One nice feature is the LocalDate class that I am using. It is a date without time of day, which seems to match your requirements more precisely that Calendar did.
If the above looks complicated, it’s because, as I think you are aware, “Sunday of the same week” means different things in different locales. In the international standard that Germany follows, weeks begin on Monday, so Sunday is the last day of the week. In the American standard, for example, Sunday os the first day of the week. WeekFields.dayOfWeek() numbers the days of the week from 1 to 7, so when we want to set the day to Sunday, we first need to find out which number Sunday has got in this numbering (7 in Germany, 1 in the US). So for any Sunday, get its weekFieldsForLocale.dayOfWeek() value and later use this for setting the day of week to Sunday. The reason why this is necessary is that the with() method is so general and therefore has been designed to accept only numeric values; we can’t just pass it a DayOfWeek object.
If I substitute Locale.US into the code, I get 2017-12-10, which is the correct Sunday for a calendar where Sunday is the first day of the week. If you are sure your only want your code to work for Germany, you may of course just hardcode a 7 (please make it a constant with a very explanatory name).
Link: Oracle Tutorial Date Time explaining how to use java.time. There are other resources on the net (just avoid the outdated placed that suggest java.util.Calendar :-)
So this issue I believe is simple enough that I can just give you three lines of code and the problem is likely my understanding of the date class.
public DrawCalendar(GregorianCalendar date){
date.setFirstDayOfWeek(GregorianCalendar.THURSDAY);
System.out.print(date.get(GregorianCalendar.DAY_OF_WEEK));
My problem is that I BELIEVE I'm adjusting the starting day of the week, so today, by default is the 6th day of the week. If I change this to a random day or integer like THURSDAY I'm still getting that today is the 6th day of the week even when thursday is the 1st day of the week.
That is what I BELIEVE is happening, why would the print statement not be returning a different number based on the first day of the week which was adjusted just one line before it?
Use getFirstDayOfWeek() method
System.out.println(calObj.getFirstDayOfWeek());
setFirstDayOfWeek typically is SUNDAY or MONDAY and influences the WEEK_OF_YEAR number. The DAY_OF_WEEK is simply MONDAY, TUESDAY, ...
I'm pretty sure it's because:
date.setFirstDayOfWeek(GregorianCalendar.THURSDAY);
Is used to tell the class which day of the week should be used for date calculations involving weeks, while
date.get(GregorianCalendar.DAY_OF_WEEK);
Is getting the day of the week that the current object represents in time (since the current object represents a specific point in time).
In my application there lies a code which works abruptly sometimes, its about getting a week interval using the java calendar object through Calendar.DAY_OF_WEEK.
The code checked for monday as start of week and sunday as end of week like:
fromCal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
toCal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
the toCal is set as the last sunday instead of coming sunday.
Is there any alternate way to do this other then this kind of hard coding.
Appriciate the help in advance.
Thanks,
Vaibhav
I guess you have to set the start of week to monday, otherwise last sunday IS the sunday of the week.
setFirstDayOfWeek
public void setFirstDayOfWeek(int value)
Sets what the first day of the week is; e.g., Sunday in US, Monday in France.
**Parameters:**
value - the given first day of the week.
Java Calender Doc
The issue is in locale. In English(US), Sunday is the first day of the week.
Check this code:
Calendar cal = Calendar.getInstance(Locale.ENGLISH);
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
System.out.println("FirstDayOfWeek="+cal.getFirstDayOfWeek());
System.out.println(cal.getTime().toString());
cal = Calendar.getInstance(Locale.FRANCE);
System.out.println("FirstDayOfWeek="+cal.getFirstDayOfWeek());
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
System.out.println(cal.getTime().toString());
Be very clear on your desired behaviour here. You start with a calendar object whose "now" is some day of the week, perhaps "today". You the call set(DAY_OF_WEEK, ...). What effect do you desire if the Calendar's today is Tuesday? Sunday? Monday?
As observed in other answers, what happens depends upon the Calendar's opinion about what the First day of week is. So first set that to your chosen value. You will then (according to this answer get a Sunday and a Monday in the current week, which may not be what you want - what exactly do you need if today is Sunday? - some systems might actually be "thinking" about the next week.
Personally I might get my Monday according to some business rules and the get the Sunday after by adding 6 days.
I am new to Joda-Time and was looking at getting the previous working/week day.
My initial try was done on a Monday and I wanted to get the date for T -1 which will be Friday:
DateTimeZone zone = DateTimeZone.forID("Europe/London");
Chronology coptic = GJChronology.getInstance(zone);
DateTime dt = new DateTime(coptic);
DateTime minusOneDay = dt.minusDays(1);
System.out.println(minusOneDay );
But as I expected returns the date on Sunday. Does anyone know how to get the previous week day?
Thanks in advance..
This doesn't look to be handled by Joda time.
There is a sourceforge project that looks to handle it though.
objectlabkit
If the day is Monday or Sunday, then you need to subtract three or two days respectively. In all other cases subtract one day. This assumes a working week from Monday to Friday (which doesn't apply to all cultures).