【问题标题】:Joda-Time strange hourJoda-Time 奇怪的时间
【发布时间】:2014-02-03 10:16:51
【问题描述】:

我正在尝试在 12:00 时初始化一个 Joda-Time DateTime 对象,这是我这样做的方法:

public static final long MINUTE         = 60 * 1000;
public static final long HOUR           = 60 * MINUTE; 

DateTime defaultDate = new DateTime(HOUR * 12);
System.out.print("the hour is: " + defaultDate.getHourOfDay()) // getting 14

为什么我得到 14 而不是 12?也许妈妈没有教我读时钟吧?!

【问题讨论】:

  • 您的问题不清楚。你应该解释你试图做什么,你期望什么,以及什么是错的。您是否尝试在 1970 年的第一天在您当地的时区创建一个中午的日期时间?这就是您的代码似乎所暗示的。我建议您阅读 Joda-Time 文档并在 StackOverflow 中搜索“joda”以找到许多示例。

标签: java date jodatime


【解决方案1】:

您指定了自 Unix 纪元以来的毫秒数,即午夜 UTC

但是,您在 DateTime 中隐式使用系统默认时区,我怀疑在 Unix 时代,您的系统时区是 UTC+2。

如果你想使用特定的时区,你可以在构造函数中传递它:

DateTime defaultDate = new DateTime(HOUR * 12, DateTimeZone.UTC);

此外,您可以使用DateTimeConstants.MILLIS_PER_HOURjava.util.concurrent.TimeUnit 进行转换,而不是使用自己的常量。

【讨论】:

  • 那么没有 UTC 有没有办法做到这一点?
  • @VladIoffe:做什么?我怀疑你没有考虑过你正在创建什么类型的对象。如果您想在当地时区 1970 年 1 月 1 日凌晨 12 点,我建议您先创建一个LocalDateTime
【解决方案2】:

java.time

以下引用来自home page of Joda-Time的通知:

请注意,从 Java SE 8 开始,用户被要求迁移到 java.time (JSR-310) - JDK 的核心部分,它取代了这个项目。

使用现代日期时间 API java.time 的解决方案:

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        ZonedDateTime zdt = ZonedDateTime.of(LocalDateTime.of(LocalDate.EPOCH, LocalTime.of(12, 0)), ZoneOffset.UTC);
        System.out.println(zdt);
    }
}

输出:

1970-01-01T12:00Z

ONLINE DEMO

几个重要说明:

  1. ZonedDateTime#toString 如果秒数和秒数为零,则删除它们。如果要显示它们,可以使用DateTimeFormatter 例如
String formatted = zdt.format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH));
  1. 输出中的Z 是零时区偏移的timezone designator。它代表 Zulu 并指定 Etc/UTC 时区(时区偏移量为 +00:00 小时)。

Trail: Date Time 了解有关现代日期时间 API 的更多信息。

你的代码出了什么问题?

下面引用的是DateTime(long)的描述,我强调:

使用 ISOChronology在默认时区构造一个设置为从 1970-01-01T00:00:00Z 开始的毫秒数的实例。

您的位置,Israel was at an offset of +02:00 hours in 1970,因此 DateTime 实例以 +02:00 小时的偏移量实例化。

演示:

import java.util.concurrent.TimeUnit;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;

public class Main {
    public static void main(String[] args) {
        DateTime defaultDate = new DateTime(TimeUnit.HOURS.toMillis(12), DateTimeZone.UTC);
        System.out.println(defaultDate);
    }
}

输出:

1970-01-01T12:00:00.000Z

您可能已经从代码中注意到的另一件事是,如果已经有标准 API(例如 TimeUnit#toMillis)可用,则不要自己执行计算。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

【讨论】:

    猜你喜欢
    • 2017-01-30
    • 2012-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-24
    相关资源
    最近更新 更多