时区影响Date to LocalDate转换日期远的日期

时间:2015-04-10 21:44:28

标签: date timezone jodatime

以下测试说明了我遇到的问题,即调查DateLocalDate次转化。

对于我的设置,Java 7& joda-time 2.7,DateLocalDate的转换似乎在2038-3-22左右开始有点偏离。

对我来说,test_2038_3_21通过,但test_2038_3_22没有通过。

这是一个已知的问题,如果有,是否有解决方法?

package com.example;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.junit.Test;

public class TimeZoneTest {

    @Test
    public void test_2038_3_21() {
        exerciseDate(2038, 3, 21);
    }

    @Test
    public void test_2038_3_22() {
        exerciseDate(2038, 3, 22);
    }

    static void exerciseDate(int year, int month, int day) {
        TimeZone defaultTimeZone = TimeZone.getDefault();
        String defaultUserTimezone = System.getProperty("user.timezone");
        DateTimeZone defaultDateTimeZone = DateTimeZone.getDefault();

        try {
            for (String timeZoneId : timeZoneIds()) {
                System.setProperty("user.timezone", timeZoneId);
                TimeZone.setDefault(TimeZone.getTimeZone(timeZoneId));
                DateTimeZone.setDefault(DateTimeZone.forID(timeZoneId));

                LocalDate ld = new LocalDate(year, month, day);
                DateTime dt = ld.toDateTimeAtStartOfDay();
                Date d = ld.toDate();
                Date dd = dt.toDate();

                LocalDate ld2 = LocalDate.fromDateFields(d);
                DateTime dt2 = ld2.toDateTimeAtStartOfDay();
                Date d2 = ld2.toDate();
                Date dd2 = dt2.toDate();

                assertEquals(timeZoneId, ld, ld2);
                assertEquals(timeZoneId, dt, dt2);
                assertEquals(timeZoneId, d, d2);
                assertEquals(timeZoneId, dd, dd2);
                assertEquals(timeZoneId, d, dd);
            }
        } finally {
            DateTimeZone.setDefault(defaultDateTimeZone);
            System.setProperty("user.timezone", defaultUserTimezone);
            TimeZone.setDefault(defaultTimeZone);
        }
    }

    static List<String> timeZoneIds() {
        List<String> timeZones = new ArrayList<>();
        for (String timeZoneId : TimeZone.getAvailableIDs()) {
            try { // only use time zones that DateTimeZone thinks are valid
                DateTimeZone.forID(timeZoneId);
                timeZones.add(timeZoneId);
            } catch (IllegalArgumentException e) {
                // ignore
            }
        }
        return timeZones;
    }
}

1 个答案:

答案 0 :(得分:0)

您可能正在为其中一个时区进行DST转换。

来自the docs for LocalDate.toDate

  

转换为JDK日期充满了复杂性,因为JDK Date构造函数的行为与您在DST转换时的预期不同。此方法的工作原理是先进行猜测,然后调整JDK日期,直到它具有最早的有效时刻。

请注意,未来的过渡实际上只是基于当前信息的最佳猜测。时区规则定期更改。对于远远不够的东西,从现在到现在可能很容易发生变化。