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?

+3


source to share


3 answers


You are accessing the field constant instead of getting its value. I believe you wanted to use something like



System.out.println("DAY_OF_WEEK = " + theDate.get(Calendar.DAY_OF_WEEK));

      

+7


source


Your problem is that you are accessing the constant DAY_OF_WEEK

in class Calendar

( Calendar.DAY_OF_WEEK

).

To get the day of the week correctly, use the theDate

variable method .get()

like this:



theDate.get(Calendar.DAY_OF_WEEK);

      

+3


source


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?

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 .

+1


source







All Articles