【问题标题】:Time zone effect on Date to LocalDate conversions for dates far in the future时区对未来日期到 LocalDate 转换的影响
【发布时间】:2015-06-16 17:55:14
【问题描述】:

以下测试说明了我在调查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;
    }
}

【问题讨论】:

    标签: date timezone jodatime


    【解决方案1】:

    您可能会遇到某个时区的 DST 转换。

    来自the docs for LocalDate.toDate

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

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

    【讨论】:

      猜你喜欢
      • 2020-07-01
      • 2017-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多