views:

467

answers:

1

Hello Friends,

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 ?!?!)
+1  A: 

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
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