4

The code below demonstrates the problematic joda-time implementation of week calculation. This behavior is not a bug but a design decision Joda-Time uses the ISO standard Monday to Sunday week. (perhaps it should be a bug?)

Given a date I need to calculate the week number, this calculation must be i18n in nature. Meaning I must take into consideration the correct week numbering based on the regional settings of the user.

The demo code below shows wrong calculation by Joda-Time and correct calculation by the JDK, in the application we try to stick with Joda-Time being a superior solution for date manipulations. So, should I be mixing the two Time calculation libraries? I would obviously prefer not to, is this even a safe thing to do or would I come into corner cases (having experience with Date, Calendar I know for a fact that this is a painful issue for Java).

Bottom line: What is the recommended best-practice for the described requirement?

Problem demonstration code

Please see this online calendar displaying week numbers for correct week calculation example.

public class JodaTest {
 static DateTimeFormatter formatter = DateTimeFormat.forPattern("ww yyyy");
 static SimpleDateFormat jdkFormatter = new SimpleDateFormat("ww yyyy");

 public static void main(String[] args) {
  DateTime time = new DateTime(/*year*/2009, /*monthOfYear*/12, /*dayOfMonth*/6, /*hourOfDay*/23, /*minuteOfHour*/0, /*secondOfMinute*/0, /*millisOfSecond*/0);

  StringBuilder buffer = new StringBuilder()
   .append("Testing date ").append(time.toString()).append("\n")
   .append("Joda-Time timezone is ").append(DateTimeZone.getDefault()).append(" yet joda wrongly thinks week is ").append(formatter.print(time)).append("\n")
   .append("JDK timezone is ").append(TimeZone.getDefault().getID()).append(" yet jdk rightfully thinks week is ").append(jdkFormatter.format(time.toDate())).append(" (jdk got it right ?!?!)");

  System.out.println(buffer.toString());
 }
}

Output:

Testing date 2009-12-06T23:00:00.000+02:00
Joda-Time timezone is Asia/Jerusalem yet joda wrongly thinks week is 49 2009
JDK time zone is Asia/Jerusalem yet jdk rightfully thinks week is 50 2009 (jdk got it right ?!?!)
Community
  • 1
  • 1
Maxim Veksler
  • 29,272
  • 38
  • 131
  • 151
  • What's preventing you from presenting the week with a -1 offset? Or converting from joda to JDK classes for that matter whenever needed? – Esko Feb 06 '10 at 22:51
  • It's not actually a -1 week offset. In Jerusalem the week don't start at Monday, but at Sunday. And .. JodaTime is better than JDK Date/Calendar! Only he have had bad luck not living in a country which adheres an ISO datetime standard. I don't think there's more to do than hack this around by adding 1 day before getting the week. – BalusC Feb 06 '10 at 23:08
  • Guys, what you suggest is actually implementing the timezone for myself all over again. Jerusalem is just current example. The code might run in Europe/Amsterdam or even in Africa/Bujumbura you wouldn't expect me to keep track how much days should I be adding / subtracting. – Maxim Veksler Feb 06 '10 at 23:20

1 Answers1

2

The best available solution is to write an implementation of DateTimeField that wraps up the logic to extract the value you need based on a locale. Internally, you'll probably still rely on the JDK data. The aim is to wrap all the JDK code in a single reusable class. You then use it like this:

int value = dateTime.get(new LocaleAwareWeekField("en_GB"));
JodaStephen
  • 60,927
  • 15
  • 95
  • 117
  • Hmmmm... I guess so, though error to feature rate here will be pretty high due to all the "human time" corner cases we have in with the world time measuring system. I'll accept your answer because it's probably the correct path to go. – Maxim Veksler Feb 23 '10 at 23:46