0

I have some calculations being done based on the current week of the year. On this current date (4/26/2016), both Python and PHP return the current week as being the 17th week in the year. Java, however, returns 18. How do I ensure that Java returns the same as Python and php?

// Java
Calendar now = Calendar.getInstance();
now.get(Calendar.WEEK_OF_YEAR); // Returns 18

 // Python
 datetime.datetime.now().isocalendar()[1] // Returns 17

// php

$current_date = new DateTime('now');
$current_date->format("W") // Returns 17
pnus
  • 187
  • 1
  • 14
  • April 26, 2016 *is* the 18th week of the year from my count - are the other ones zero based? – stdunbar Apr 26 '16 at 21:01
  • I get 17 in all languages you have posted. Are you running all these commands on the same machine? Also what time zone are you in? – Chris Apr 26 '16 at 21:02
  • @Chris, Python and php are on the same machine. The Java code is actually being run on my Android device. I tried setting the locale as such: Calendar now = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles")); and still get 18. – pnus Apr 26 '16 at 21:06
  • 2
    @stdunbar ISO weeks are a bit weird because this year started on a Friday. The first week of a year is considered to be the week with the first Thursday in it, making this the 17th week of the ISO year, because the first 3 days of the year are considered the last week of 2015. – Chris Apr 26 '16 at 21:06
  • 1
    You have your answer here: http://stackoverflow.com/questions/10893443/understanding-java-util-calendar-week-of-year – geffrak Apr 26 '16 at 21:06
  • Thanks @Chris - didn't know that but I did wonder how a split week works. Now I know. – stdunbar Apr 26 '16 at 21:07
  • @KerbKerb, maybe I'm not understanding correctly but changing the minimal days in first week should adjust the week correctly? I've tried setting it from 1-7 and it still returns 18. I've also tried setting the locale to US, where I am located. – pnus Apr 26 '16 at 21:29
  • Well, changing the minimal days changes it to the correct week number on my machine, but my Android device still returns 18 no matter what the minimal days is set to. – pnus Apr 26 '16 at 21:38
  • Have you set first day of week to Monday? – AniaG Apr 26 '16 at 21:48
  • @AniaG, yes I did what you described below. It works on my machine but still returns 18 on Android. The only thing that seems to be working on Android at the moment is using Local.UK instead of Locale.US. For the time being, it works but I don't understand why Locale.US is always return 18 on Android. – pnus Apr 26 '16 at 22:32
  • The .Calendar and .Date classes are now legacy, supplanted by the java.time framework. The java.time classes define a week according to the ISO 8601 standard. [Back-ported to Java 6 & 7](http://www.threeten.org/) and [adapted to Android](https://github.com/JakeWharton/ThreeTenABP). – Basil Bourque Apr 27 '16 at 17:10

1 Answers1

-1

To implement ISO 8601 first week (Python's isocalendar uses it) you need to set minimal days in first week to 4 and first day of week to Monday (which is iso first day of week). This is enough to satisfy iso definition of first week, as

the week with the year's first Thursday in it.

So all you have to do is:

Calendar now = Calendar.getInstance();
now.setFirstDayOfWeek(Calendar.MONDAY);
now.setMinimalDaysInFirstWeek(4); 
now.get(Calendar.WEEK_OF_YEAR);// Returns 17
AniaG
  • 244
  • 1
  • 5
  • The `minimalDaysInFirstWeek` is 4 by default in Java. – Chris Apr 26 '16 at 21:49
  • According to documentation, it's locale-specific. Without setting it explicitly, I get 1, not 4. – AniaG Apr 26 '16 at 22:00
  • Indeed you are right. From the nasty resource file that sets the default it looks like it might be 4 by default in the UK but 1 in the US. – Chris Apr 26 '16 at 22:19