Drago
Drago

Reputation: 1875

Why is DAY_OF_WEEK adding an extra day?

Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(1560049200);

cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY // this returns true

cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.US) // Outputs Monday instead of Sunday.

Why does DAY_OF_WEEK add an extra day? It should return Sunday, but it's returning Monday.

I have tested this in I/System.out, on my Android device, and on Android Emulator. cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY keeps returning true.

-EDIT-

I also tried:

Date date = new Date(1560049200);
date.getDay();

this is returning 1.

Upvotes: 1

Views: 195

Answers (1)

Basil Bourque
Basil Bourque

Reputation: 338256

tl;dr

Instant                          // Represent a moment in UTC.
.ofEpochSecond(                  // Parse a count of whole seconds since 1970-01-01T00:00Z.
    1_560_049_200L               // Contemporary moments are about a billion and a half seconds since 1970-01-01T00:00Z.
)                                // Returns a `Instant` object.
.atZone(                         // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone).
    Zone.of( "Africa/Tunis" )    // Specify the time zone in which you are interested.
)                                // Returns a `ZonedDateTime` object.
.getDayOfWeek()                  // Returns one of the seven pre-defined enum objects, one for each day of the week, Monday-Sunday. Returns a `DayOfWeek` object.
.getDisplayName(                 // Localize the presentation of the name of the day of the week.
    TextStyle.FULL ,             // Specify how long or abbreviated should the name of the day of week be.
    new Locale ( "fr" , "TN" )   // Specify the human language and cultural norms to use in translating the name of the day of week.
)                                // Returns a `String` object.

samedi

Problems

  • Your input is apparently a count of whole seconds, not milliseconds.
  • You are using terrible old date-time classes that were supplanted years ago by the modern java.time classes.
  • You are implicitly introducing time zone issues without addressing them head on. Time zone is crucial in perceiving a date (and day-of-week).

java.time

Your input number 1_560_049_200L is apparently a count of whole seconds since the first moment of 1970 in UTC. Your code was parsing them as a count of milliseconds by mistake.

Parse as an Instant.

Instant instan = Instant.ofEpochSecond( 1_560_049_200L ) ;

instant.toString(): 2019-06-09T03:00:00Z

Adjust to the time zone through which you want to perceive a date, and therefore a day-of-week.

Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

zdt.toString(): 2019-06-08T23:00-04:00[America/Montreal]

Notice the difference in date: the 9th in UTC versus the 8th in Québec. Keep in mind: For any given moment, the date varies around the globe by zone. In the east it is “tomorrow” while still “yesterday” in the west.

A different date means a different day-of-week. While Saturday in Québec, it is simultaneously Sunday in Paris, France. This is why specifying a time zone is crucial.

Extract the day-of-week.

DayOfWeek dow = zdt.getDayOfWeek() ;

dow.toString(): SATURDAY

Localize the name of the day-of-week.

String output = dow.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH );

samedi

Or, Locale.US for the United States.

String output = dow.getDisplayName( TextStyle.FULL , Locale.US );

Saturday

Table of date-time types in Java, both modern and legacy

Upvotes: 1

Related Questions