Definition of the day of the week in the Gregoriancalendar

Asked

Viewed 2,369 times

19

I have the following code which is responsible for creating a Gregoriancalendar for handling a date.

TimeZone tz = TimeZone.getTimeZone("America/Sao_Paulo");  
TimeZone.setDefault(tz);  
Calendar calendar = GregorianCalendar.getInstance(tz);
calendar.setTime(new Date());

System.out.println(calendar.getFirstDayOfWeek());

But what is shown is "2", that is, Monday. What is the reason for this happening?

  • 3

    Detail, getInstance is a method defined in Calendar, and not in GregorianCalendar. Java allows calling static methods through "inheritance", but in practice you are calling the method Calendar.

3 answers

11


Up to Java 7

For the purpose of the following discussion, note that France starts the week on Monday while the US starts on Sunday.

The code below is running in Scala REPL, calling the Java libraries with the following import:

scala> import java.util.{Calendar, Locale, TimeZone}
import java.util.{Calendar, Locale, TimeZone}

Timezone does not contain the correct information about the first day of the week

As you can see:

scala> "startDayOfWeek[^,]*".r findFirstIn TimeZone.getTimeZone("Europe/Paris").toString
res0: Option[String] = Some(startDayOfWeek=1)

scala> "startDayOfWeek[^,]*".r findFirstIn TimeZone.getTimeZone("America/Sao_Paulo").toString
res1: Option[String] = Some(startDayOfWeek=1)

scala> "startDayOfWeek[^,]*".r findFirstIn TimeZone.getTimeZone("America/Los_Angeles").toString
res2: Option[String] = Some(startDayOfWeek=1)

There’s no way to extract day of the week from a Timezone

Using tab-Completion to get the available methods:

scala> TimeZone.getTimeZone("Europe/Paris")
res3: java.util.TimeZone = sun.util.calendar.ZoneInfo[id="Europe/Paris",offset=3600000,dstSavings=3600000,useDaylight=true,transit
ions=184,lastRule=java.util.SimpleTimeZone[id=Europe/Paris,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMod
e=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endT
ime=3600000,endTimeMode=2]]

scala> res3.
asInstanceOf           clone                  getDSTSavings          getDisplayName         getID
getOffset              getRawOffset           hasSameRules           inDaylightTime         isInstanceOf
observesDaylightTime   setID                  setRawOffset           toString               useDaylightTime

None of this returns the desired information (which is incorrect anyway)

Locale can be used to set the first day of the week

As we can see:

scala> Calendar.getInstance(Locale.FRANCE).getFirstDayOfWeek
res8: Int = 2

scala> Calendar.getInstance(Locale.US).getFirstDayOfWeek
res9: Int = 1

But it doesn’t work for us Brazilians

scala> Calendar.getInstance(new Locale("pt", "BR")).getFirstDayOfWeek
res10: Int = 2

Ask any Brazilian who is the first day of the week, and he will probably say Sunday. So much so that Monday is the first day useful. Unfortunately, there is no Brazilian standard on this, and the international standard (as is the custom in most parts of the world, excluding the United States) dictates Monday as the first day.

In the ABNT standard that would be the most relevant, NBR 5892:1989, there is no statement of which is the first day of the week, but the days of the week are listed from Monday to Sunday when the standard lists the abbreviations.

On wikipedia, the discussion go far!

Besides, Sunday is part of the "weekend", it’s not?

So, and although we Brazilians use calendars starting with Sunday, I find it hard to change that. But, for those who are sufficiently indignant and motivated, a help:

  • Link to bug submission;
  • A previous bug reporting this kind of problem -- in this case, the bug was invalid, but you can use it as a reference, and copy the program used in it to demonstrate the problem.

Java 8

The new Java 8 time and date facility features the same behavior as Java 7:

import java.time.DayOfWeek;
import java.time.temporal.WeekFields;
import java.util.Locale;

// ...
  WeekFields brWeekFields = WeekFields.of(new Locale("pt", "BR"));
  DayOfWeek brFirstDayOfWeek = brWeekFields.getFirstDayOfWeek(); // MONDAY

But if you want weeks starting on Sunday, use the following:

  WeekFields brWeekFields = WeekFields.SUNDAY_START;
  DayOfWeek brFirstDayOfWeek = brWeekFields.getFirstDayOfWeek(); // SUNDAY

In the same way as in Java 7, dates obtained from Timezone (zoneId in Java 8) has no information regarding the first day of the week. Unlike Java 7, however, there are no methods to do this inquiry in anything derived from the zoneId.

  • "Ask any Brazilian what the first day of the week is, and he’ll probably say Sunday." Will it be? I’d say Monday.

  • @bfavaretto "Probably" is used here to indicate high probability, not certainty. Looking thereabout, I couldn’t find anyone saying Monday.

  • @bfavaretto Since childhood I was taught that the first day of the week is Sunday, perhaps because of Christian tradition where Sunday is the first day of creation.

  • For Jewish and Christian cultures, Saturday is the seventh day of the week. Tip: Don’t want to get into a discussion about it with a Seventh-day Adventist.

  • 1

    For me, the first day is Sunday. The words "Monday, Tuesday, Wednesday, Thursday and Friday" are quite suggestive that Seventh=Saturday and First=Sunday.

  • 1

    For some reason all the apps and Oses I’ve used, and reconfirmed in large part, the week starts on Sunday using Brazil locale. I share the idea of the week starting on Sunday, supported by both the @Victor argument and the vast majority (everything I’ve seen except the bfavaretto comment) indicating that here the week begins on Sunday itself. Anyway, I have not found proof "documentary" in any of the two strands that is specific to Brazil.

  • @Bacco I didn’t find out because and neither whosoever "decided" that it is Sunday for pt_BR, but left an answer detailing where Java gets this information from (a small detail that it didn’t have in the other answers)

  • @Victorstafusa In other languages there is no such association (at least not so direct) between the days of the week and the respective "order"/numbering (in English and Japanese, for example, Sunday is literally "the day of the sun"). If it were only a linguistic issue, the locales en_US and en_GB (respectively British English and American English) would have the same rules, but the first returns Sunday and the second returns Monday: https://ideone.com/cAs8uc :-)

Show 3 more comments

10

The first day of the week, returned by function getFirstDayOfWeek() is defined by the settings of the locale current. For example, in Brazil the convention is that the first day of the week is Monday, while in the US the week begins on Sunday:

Calendário EU Calendário Brasil

Edit: If you want to move the current calendar date to the first day of the week it is on:

calendar.setWeekDate(calendar.get(Calendar.YEAR),
                     calendar.get(Calendar.WEEK_OF_YEAR),
                     calendar.getFirstDayOfWeek())

Or simply:

calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());
  • 1

    Thank you for the reply. What is the convention that says that the first day of the week is Monday?

  • 1

    According to the Article in Wikipédia on Monday, Monday is defined as the first day of the week by the ISO 8601 standard. The text of the ISO standards is not publicly available (it needs to be purchased), but the English wikipedia page on ISO 8601 seems to confirm this information: "The ISO week-numbering year Starts at the first day (Monday) of week 1 (...)"

1

The TimeZone has nothing to do with the definition of the week. This is controlled by Locale. So much so that if you do this:

for (String zone : TimeZone.getAvailableIDs()) {
    TimeZone tz = TimeZone.getTimeZone(zone);
    TimeZone.setDefault(tz);
    Calendar calendar = GregorianCalendar.getInstance(tz);
    System.out.println(zone + "=" + calendar.getFirstDayOfWeek());
}

The result of getFirstDayOfWeek() will be the same for all timezones. Already if you do this:

TimeZone tz = TimeZone.getTimeZone("America/Sao_Paulo");
TimeZone.setDefault(tz);
for (Locale loc : Locale.getAvailableLocales()) {
    Locale.setDefault(loc);
    Calendar calendar = GregorianCalendar.getInstance(tz);
    System.out.println(loc + "=" + calendar.getFirstDayOfWeek());
}

The result of getFirstDayOfWeek() may be 1, 2 or 7, depending on the Locale used. Moreover, the TimeZone makes no difference in this code, I could simply call getInstance() (or getInstance(loc) instead of using Locale.setDefault), that the result would be the same: the locale is what defines the first day of the week, regardless of the Timezone used.

I also removed the line calendar.setTime(new Date()), because it’s redundant: getInstance already picks up the current date/time, and set a new Date() (which is also the current date/time) is unnecessary.


When you create a Calendar, he will seek inside the JVM the information on the first day of the week, based on the locale informed. If none is passed to getInstance, use the default of the JVM (which we changed with Locale.setDefault in the code above).

Basically, the JVM has several files from properties containing the respective information of each locale. But not all the locales have a specific file, and for these there is a default which is used as fallback.

In Java 7, for example, the file default (used as fallback) is that, and see that it has the following content:

firstDayOfWeek=1
minimalDaysInFirstWeek=1

And as there is no specific file for the locale pt_BR, the code below - tested in JDK 1.7.0_80 - print 1 (which corresponds to Sunday):

System.out.println(Calendar.getInstance(new Locale("pt", "BR")).getFirstDayOfWeek());

I just found it curious that in another answer the result was 2, because testing in Java 7 and 8, I got 1.

Already using another locale:

System.out.println(Calendar.getInstance(new Locale("en", "GB")).getFirstDayOfWeek());

In this case the result was 2 (Monday), because in Java 7 there is a file of properties specific to the locale en_GB, in which the value of firstDayOfWeek is 2.

Note: in the above links (which correspond to the Openjdk code) there is no properties for pt_BR, but in the JVM I am using on my machine exists. Anyway, what matters is that this information is always searched in the JVM.


In Java 8 it is similar: there is a properties specific to pt_BR (in which firstDayOfWeek is 1) and there is also another to en_GB (with firstDayOfWeek equal to 2), in addition to a properties default used as fallback (with firstDayOfWeek equal to 1).

By the way, testing in Java 8 (JDK 1.8.0_202) also got a different result than another answer:

WeekFields brWeekFields = WeekFields.of(new Locale("pt", "BR"));
DayOfWeek brFirstDayOfWeek = brWeekFields.getFirstDayOfWeek(); // SUNDAY

In the Ideone.com the above code also returns "Sunday".


Starting from Java 8, the JDK started to seek a greater compatibility with the CLDR - Unicode Common Locale Data Repository, an information repository related to locales. One of the information defined by CLDR is - guess what - the definition of the first day of the week. These settings are stored in the supplementalData:

<firstDay day="mon" territories=" 001 AD AI AL AM AN AT AX AZ BA BE BG BM BN BY CH CL CM CR CY CZ DE DK EC EE ES FI FJ FO FR GB GE GF GP GR HR HU IE IS IT KG KZ LB LI LK LT LU LV MC MD ME MK MN MQ MY NL NO NZ PL RE RO RS RU SE SI SK SM TJ TM TR UA UY UZ VA VN XK"/>    
<firstDay day="fri" territories="MV"/>    
<firstDay day="sat" territories="AE AF BH DJ DZ EG IQ IR JO KW LY OM QA SD SY"/>    
<firstDay day="sun" territories=" AG AR AS AU BD BR BS BT BW BZ CA CN CO DM DO ET GT GU HK HN ID IL IN JM JP KE KH KR LA MH MM MO MT MX MZ NI NP PA PE PH PK PR PT PY SA SG SV TH TT TW UM US VE VI WS YE ZA ZW"/>

I haven’t tested for everyone, but see that for BR (Brazil) the first day of the week is Sunday ("sun") and for GB (United Kingdom), is Monday ("mon"), which match the results of Java. In the case of Java 8, both Calendar how much WeekFields use the same properties and the results match with the suplementalData above.

But it is worth remembering that, as this information is embedded in the JVM, they can change from one version to another, as with some locales in Java 9 - After all, CLDR is always being updated, and Java tries to follow it as far as possible (besides, CLDR has only become the source default of information from locales starting from Java 9).

The only mystery, for me, is how they arrived at these values. Someone had to decide which is the first day of the week for each of these locales.  That is, this answer helps explain where this data comes from, but not because the data are exactly this.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.