Maxim Veksler
Maxim Veksler

Reputation: 30232

Joda time week calculation reasoning

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 ?!?!)

Upvotes: 4

Views: 3118

Answers (1)

JodaStephen
JodaStephen

Reputation: 63465

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"));

Upvotes: 2

Related Questions