2

The below gives me different results (After) on my laptop than anywhere else.

private static void prindStartOfWeek() 
{
    Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

    System.out.println(" --------- Before : " + cal.getTime());

    cal.set(Calendar.YEAR, 2015);
    cal.set(Calendar.WEEK_OF_YEAR, 1);
    cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
    cal.set(Calendar.HOUR, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);

    System.out.println(" --------- After : " + cal.getTime());
}

I'm using Eclipse Kepler , Windows 7 64bit, Java jdk1.7.0_65. I tested on Eclipse Juno too and from cmd (executable jar). And the same applies.

I've tested the above code on my laptop and it prints

 --------- Before : Fri Nov 20 14:04:07 EET 2015
 --------- After : Sun Jan 04 14:00:00 EET 2015

I've tested on Microsoft Server 2008 running Java 7 and it prints (which is the right value)

 --------- Before : Fri Nov 20 14:09:01 EET 2015
 --------- After : Sun Dec 28 14:00:00 EET 2014

I've tested here too and it prints

 --------- Before : Fri Nov 20 10:54:40 UTC 2015
 --------- After : Sun Dec 28 00:00:00 UTC 2014

Does anyone know what might be going wrong? My laptop timezone is "Europe\Athens", but it shouldn't matter I guess.

Moreover this was tested in another computer and it prints the right value

 --------- Before : Fri Nov 20 14:09:01 EET 2015
 --------- After : Sun Dec 28 14:00:00 EET 2014
Alkis Kalogeris
  • 17,044
  • 15
  • 59
  • 113
  • 1
    `getCalendar(TimeZone)` "Gets a calendar using the specified time zone and default locale." What is the default locale on each of these machines? (Or, at least, on one machine which is "right" and one which is "wrong". – Andy Turner Nov 20 '15 at 12:24
  • 1
    In some places, Sunday is considered as first day of the week, and in other places, Monday is the first day of the week. Can you please verify if it is due to this fact? – Kartic Nov 20 '15 at 12:25
  • @AndyTurner you my friend saved me from insanity. There was different locale. When I hardcoded it, the results were the same. Please add it as an answer so I can accept it – Alkis Kalogeris Nov 20 '15 at 12:32
  • @alkis done, with props to Kartic because I have used his comment in my answer. – Andy Turner Nov 20 '15 at 12:37
  • Maybe this can help you http://stackoverflow.com/questions/344380/why-is-january-month-0-in-java-calendar?rq=1 Java Date is pretty messy. – Jorge Gutiérrez Parejo Nov 20 '15 at 12:28
  • @Kartic thank you for the explanation you provided. – Alkis Kalogeris Nov 20 '15 at 14:47

2 Answers2

1

getCalendar(TimeZone) "Gets a calendar using the specified time zone and default locale."

As @Kartic notes in his comment above, in some places, Sunday is considered as first day of the week, and in other places, Monday is the first day of the week - this would be affected by your locale.

You probably have a different default locale between the machines on which you are running the code.

Community
  • 1
  • 1
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
1

tl;dr

ZonedDateTime.now()                                     // Capture the current moment as seen through the lens of the wall-clock time used by the people of a particular region (time zone).
             .get( IsoFields.WEEK_OF_WEEK_BASED_YEAR )  // Get the week number, with stable results per the ISO 8601 definition of a week that starts on a Monday and considers week # 1 to have the first Thursday of the calendar-year.

Locale

In the Calendar class, the meaning of a “week” changes by locale. If at runtime the JVM’s current default Locale differs, the result of calculating weeks may differ.

For example, in the United States the first day of a week is Sunday. But in much of Europe, and by ISO 8601 standard, the first day of the week is Monday.

That Calendar class is troublesome and confusing. And fortunately, now legacy, supplanted by the industry-leading java.time classes.

java.time

Capture the current moment in UTC.

Instant instant = Instant.now() ;

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-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" ) ;  

If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit.

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

Apply that ZoneId to get a ZonedDateTime object.

ZonedDateTime zdt = instant.atZone( z ) ;

Now get interrogate for the week-based year and week. The IsoFields class provides objects through which we can get the week numbers per the ISO 8601 standard:

  • Week # 1 holds the first Thursday of the calendar-year
  • Monday is the first day of the year
  • A year has either 52 or 53 weeks.
  • The last/first few days of a year may lie in the previous/next week-based year.

Example.

int yearIso = zdt.get( IsoFields.WEEK_BASED_YEAR ) ;
int weekIso = zdt.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;

TIP: Consider adding the ThreeTen-Extra library to your project to gain access to the YearWeek class.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154