DAY_OF_WEEK always returns 7 in Java GregorianCalendar
So, I want to do something with Java GregorianCalendar which seems to go a lot more complicated than it needs to. I want to get the day of the week from month and date. But it won't. I know people often get the wrong answer to this because they don't know that the month is numbered from 0 and DAY_OF_WEEK is numbered from 1 (for example here and here ). But that's not my problem. My problem is that DAY_OF_WEEK always, always returns 7, no matter what I set the date for. When I convert GregorianCalendar to string, DAY_OF_WEEK appears as ?, although I have set the year, month and dayOfMonth.
Code where this happens:
GregorianCalendar theDate;
public ObservableDate(int year, int month, int dayOfMonth, int hourOfDay, int minute, int second)
{
theDate = new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute, second);
theDate.setFirstDayOfWeek(GregorianCalendar.SUNDAY);
System.out.println("DAY_OF_WEEK = "+theDate.DAY_OF_WEEK);
System.out.println(theDate.toString());
}
The code that calls it:
ObservableDate theDate = new ObservableDate(2001, 3, 24, 9, 00, 00);
Output:
DAY_OF_WEEK = 7
java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=?,YEAR=2001,MONTH=3,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=24,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=9,HOUR_OF_DAY=9,MINUTE=0,SECOND=0,MILLISECOND=?,ZONE_OFFSET=?,DST_OFFSET=?]
Any idea why this is happening?
source to share
TL; DR
For smart object DayOfWeek
enum.
ZonedDateTime.of( 2001 , 3 , 24 , 9 , 0 , 0 , 0 , ZoneId.of( "Pacific/Auckland" ) ) // Moment as seen by people in a certain region (time zone).
.getDayOfWeek() // Extract a `DayOfWeek` enum object to represent that day-of-week of that moment.
For an integer 1-7 for Monday through Sunday.
ZonedDateTime.of( 2001 , 3 , 24 , 9 , 0 , 0 , 0 , ZoneId.of( "Pacific/Auckland" ) )
.getDayOfWeek()
.getValue() // Translate that `DayOfWeek` object into a mere integer 1-7 for Monday-Sunday.
java.time
The modern approach uses java.time classes, which supplant the nasty old obsolete time classes. Calendar
is replaced by ZonedDateTime
.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.of( 2001 , 3 , 24 , 9 , 0 , 0 , 0 , z );
DayOfWeek
enum defines seven objects for each day of the week.
DayOfWeek dow = zdt.getDayOfWeek() ; // Get `DayOfWeek` enum object representing this momentβs day-of-week.
You can queryDayOfWeek
to localize the name of the day.
I suggest using these objects DayOfWeek
across your codebase, not just integers. But if you insist, you can get a number. Unlike GregorianCalendar
numbers, they have a fixed meaning and are not locale dependent. The value is 1-7 for Monday through Sunday, according to the ISO 8601 standard .
int dowNumber = zdt.getDayOfWeek().getValue() ; // 1-7 for Monday-Sunday per ISO 8601.
Immutable object
Please note that java.time uses immutable objects . Instead of changing the member variables on the object ("mutating"), calls to set the value result in a new object, leaving the original object unchanged.
ZonedDateTime zdtTomorrow = zdt.now( z ).plusDays( 1 ) ; // Alterations result in a new object, leaving original intact. Known as *immutable objects*.
Timezone
You were unable to specify the timezone in the arguments to the constructors and in the arguments passed to new GregorianCalendar
. In such cases, the JVMs' current default time zone is implicitly assigned. This default can vary from machine to machine and may even change at any time during runtime. Better to specify the desired / expected time zone.
Specify the name of the time zone in the format continent/region
, for example America/Montreal
, Africa/Casablanca
or Pacific/Auckland
. Never use the 3-4 letter abbreviation, for example EST
or IST
, as they are not real time zones and not standardized and not even unique (!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
Numeric literals
Beware of your literal value 00
. Leading zero means a base-8 octal number , not a decimal number in the Java source code. You're in luck, since octal zero is also decimal zero.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the nasty old legacy time classes such as java.util.Date
, Calendar
and SimpleDateFormat
.
The Joda-Time project , now in maintenance mode , advise moving to the java.time classes .
To learn more, see the Oracle Tutorial . And search Stack Overflow for many examples and explanations. Specification JSR 310 .
Where can I get the java.time classes?
- Java SE 8 , Java SE 9 and then
- Built in.
- Part of the standard Java API with a combined implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6 and Java SE 7
- Most of the java.time functionality goes back to Java 6 and 7 in ThreeTen-Backport .
- Android
- Later versions of the Android package implementations of the java.time classes.
- For earlier Android, the ThreeTenABP project adapts the ThreeTen-Backport (mentioned above). See. How to use ... ThreeTenABP .
The ThreeTen-Extra project extends java.time with additional classes. This project is proof of possible future additions to java.time. Here you can find useful classes, such as Interval
, YearWeek
, YearQuarter
and longer .
source to share