English 中文(简体)
Joda Time gives wrong time zone
原标题:

I m using the Joda time (1.6) libraries and it keeps returning DateTime objects with the wrong time zone, British Summer Time instead of GMT.

My Windows workstation (running JDK 1.6.0_16) thinks it s in GMT and if I get the default time zone from the JDK date/time classes it is correct (GMT). I get the same behaviour on our Linux servers as well. I thought it could be an error in the time zone database files in Joda so I rebuilt the jar with the latest database but with no change.

import java.util.TimeZone;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;

public class TimeZoneTest {

    public static void main(String[] args) {                
        DateTimeFormatter timeParser = ISODateTimeFormat.timeParser();
        TimeZone timeZone = TimeZone.getDefault();
        System.out.println(timeZone.getID()); // "Europe/London"
        System.out.println(timeZone.getDisplayName()); // "Greenwich Mean Time"

        DateTimeZone defaultTimeZone = DateTimeZone.getDefault();
        System.out.println(defaultTimeZone.getID()); //"Europe/London"
        System.out.println(defaultTimeZone.getName(0L)); //"British Summer Time"

        DateTime currentTime = new DateTime();
        DateTimeZone currentZone = currentTime.getZone();
        System.out.println(currentZone.getID()); //"Europe/London"
        System.out.println(currentZone.getName(0L)); //"British Summer Time"            
    }
}

Debugging through the static initialiser in org.joda.time.DateTimeZone I see that the System.getProperty("user.timezone") call gives "Europe/London" as expected.

最佳回答

Ok, to get to the root of this you have to familiarize with what British Summer Time actually means and when it was in place. To make it short you pass 0L to getName() which is 1970-01-01T00:00:00Z so DefaultTimeZone looks up the name of the timezone at that moment. Which was British Summer Time.

From: http://www.nmm.ac.uk/explore/astronomy-and-time/time-facts/british-summer-time

In 1968 clocks were advanced one hour ahead of GMT on 18 February and remained so until British Standard Time, during which clocks were kept in advance of GMT all year, came into force between 27 October 1968 and 31 October 1971.

If you instead would pass in the right amount of milliseconds since 1970-01-01T00:00:00Z. e.g. by doing

defaultTimeZone.getName(new GregorianCalendar().getTimeInMillis())

You would get the correct string too. Basically you just fed the getName() method the wrong parameter thus ended up with an unexpected result.

If you want to check in detail check the files in org/joda/time/tz/src of joda source to see how joda determines time zones.


Instead of

defaultTimeZone.getName(0L)

you could use

defaultTimeZone.toTimeZone().getDisplayName()

which does it for me.

问题回答

It may interest you to see the static initialiser for the DateTimeZone class in 1.6:

static {
    setProvider0(null);
    setNameProvider0(null);

    try {
        try {
            cDefault = forID(System.getProperty("user.timezone"));
        } catch (RuntimeException ex) {
            // ignored
        }
        if (cDefault == null) {
            cDefault = forTimeZone(TimeZone.getDefault());
        }
    } catch (IllegalArgumentException ex) {
        // ignored
    }

    if (cDefault == null) {
        cDefault = UTC;
    }
}

My guess is that you have a user.timezone property defined (and set to BST). Otherwise, it looks like Joda should create its own timezone instance based on the JDK time zone; and I d expect any bugs in this area, especially converting a GMT zone, would have been picked up by now.





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签