Joda时间硬编码在不同时区不起作用

时间:2017-01-18 23:36:00

标签: java jodatime

Joda时间硬编码在不同时区不起作用。我通过以下方式对Joda时间进行了硬编码,以便为Junit测试用例提供静态日期时间。

LocalDateTime fixedDateTime = new LocalDateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute, 0, ISOChronology.getInstance("Canada/Pacific")));

DateTimeUtils.setCurrentMillisFixed(fixedDateTime.toDate().getTime());

但是当您尝试使用以下API获取当前日期时间时,可能不会导致上述确切的固定日期。

DateTime.now(DateTimeZone.forID("Canada/Pacific"));

根据您运行代码的时区,此日期甚至可以是固定日期的前一天或下一天。 这可能令人沮丧,因为您的测试用例将在本地传递,但在部署到虚拟云计算机时,它可能会使这些虚拟云计算机上的测试用例失败,因为它们可能位于完全不同的时区。

2 个答案:

答案 0 :(得分:2)

Javadoc of that constructor of LocalDateTime(强调我的):

  

使用指定的年代将其区域设置为指定的日期和时间

使用DateTime代替LocalDateTime

DateTime fixedDateTime = new DateTime(
    year, monthOfYear, dayOfMonth,
    hourOfDay, minuteOfHour, secondOfMinute, 0,
    ISOChronology.getInstance("Canada/Pacific")));

DateTimeUtils.setCurrentMillisFixed(fixedDateTime.getMillis());

答案 1 :(得分:0)

感谢Andy的回复。你是对的LocalDateTime没有使用区域。但我最终使用LocalDateTime,因为我想硬编码日期到第二个。但我确实找到了一个解决方案来处理区域产生的偏移。这是我的代码

private LocalDateTime setJodaTime(int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minuteOfHour, int secondOfMinute) {
        LocalDateTime fixedDateTime = new LocalDateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute, 0, ISOChronology.getInstance(DateTimeZone.forID("Canada/Pacific")));
        long millisWithoutTimeZone = fixedDateTime.toDate().getTime();
        // fixed Joda millis
        DateTimeUtils.setCurrentMillisFixed(millisWithoutTimeZone);
        LocalDateTime localDateTime = DateTime.now(DateTimeZone.forID("Canada/Pacific")).toLocalDateTime();
        // get time zone offset
        long offset = localDateTime.toDate().getTime() - millisWithoutTimeZone;
        // reverse the offset
        offset = (-1) * offset;
        DateTimeUtils.setCurrentMillisFixed(millisWithoutTimeZone + offset);
        LocalDateTime currentDateTime = DateTime.now(DateTimeZone.forID("Canada/Pacific")).toLocalDateTime();
        return currentDateTime;
    }