时区对遥远未来日期的日期到本地日期转换的影响



下面的测试说明了我遇到的一些东西,将调查Date LocalDate转换。

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

对我来说,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;
    }
}

您可能正在遇到其中一个时区的 DST 转换。

来自LocalDate.toDate的文档:

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

请注意,未来的过渡实际上只是基于当前信息的最佳猜测。 时区规则会定期更改。 对于这么远的事情,现在和那时之间很容易发生变化。

相关内容

  • 没有找到相关文章

最新更新