如何以Java或GMT格式获取当前日期和时间?

当我创建一个新的Date对象时,它被初始化为当前时间,但在本地时区。 我如何在格林威治标准时间获得当前的日期和时间?


java.util.Date没有特定的时区,尽管它的值通常与UTC有关。 是什么让你认为这是当地时间?

准确地说: java.util.Date的值是自Unix时代开始的毫秒数,它发生在UTC时间1970年1月1日午夜。 同样的时代也可以在其他时区描述,但传统的描述是以UTC为单位的。 由于它是固定时期以来的毫秒数,因此无论本地时区如何,在任何特定时刻, java.util.Date的值都是相同的。

我怀疑问题在于,您是通过使用本地时区的日历实例来显示它,或者可能使用也使用本地时区的Date.toString()SimpleDateFormat实例,该实例默认情况下也使用本地时区时区。

如果这不是问题,请发布一些示例代码。

不过,我会建议你使用Joda-Time,它提供了一个更清晰的API。


SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));

//Local time zone   
SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");

//Time in GMT
return dateFormatLocal.parse( dateFormatGmt.format(new Date()) );

TL;博士

Instant.now()   // Capture the current moment in UTC. 

生成一个字符串来表示该值:

Instant.now().toString()  

2016-09-13T23:30:52.123Z

细节

正如Jon Skeet的正确答案所述,java.util.Date对象没有时区 †。 但是它的toString实现在生成该日期时间值的字符串表示时应用JVM的默认时区。 混淆天真的程序员,日期似乎有一个时区,但没有。

与Java捆绑在一起的java.util.DatejuCalendarjava.text.SimpleDateFormat类是非常麻烦的。 避免它们。 相反,使用这些有效的日期时间库中的任何一个:

  • Java 8中的java.time。*包
  • 乔达时间
  • java.time(Java 8)

    Java 8带来了一个优秀的新java.time。*包来取代旧的java.util.Date/Calendar类。

    获取UTC / GMT的当前时间是一个简单的单线...

    Instant instant = Instant.now();
    

    Instant类是java.time中的基本构建块,代表UTC时间轴上的时间片,分辨率为纳秒。

    在Java 8中,当前时刻仅以毫秒级分辨率捕获。 Java 9带来全新的Clock捕捉功能,捕捉当前时刻,达到此类的全纳秒能力,具体取决于主计算机时钟硬件的能力。

    它是toString方法使用一个特定的ISO 8601格式生成其值的字符串表示。 该格式根据需要输出零,三,六或九位数字(毫秒,微秒或纳秒)以表示秒的分数。

    如果您想要更灵活的格式,在各种时区或其他附加功能中进行调整,请应用时区( ZoneId对象)以获取ZonedDateTime 。 时区可以是UTC或任何其他时区。 的子类ZoneIdZoneOffset适用于UTC的常数。

    ZonedDateTime now = ZonedDateTime.now( ZoneOffset.UTC );
    

    转储到控制台...

    System.out.println( "now: " + now );
    

    当运行...

    now: 2014-01-21T23:42:03.522Z
    

    java.time类由JSR 310定义。它们受Joda-Time的启发,但完全重新架构。

    乔达时间

    更新:Joda-Time项目现在处于维护模式,建议迁移到java.time类。

    使用Joda-Time第三方开放源代码免费库,您可以在一行代码中获得当前的日期时间。

    Joda-Time启发了Java 8中新的java.time。*类,但具有不同的体系结构。 您可以在旧版本的Java中使用Joda-Time。 Joda-Time继续在Java 8中工作,并继续积极维护(截至2014年)。 但是,Joda-Time团队建议迁移到java.time。

    System.out.println( "UTC/GMT date-time in ISO 8601 format: " + new org.joda.time.DateTime( org.joda.time.DateTimeZone.UTC ) );
    

    更详细的示例代码(Joda-Time 2.3)...

    org.joda.time.DateTime now = new org.joda.time.DateTime(); // Default time zone.
    org.joda.time.DateTime zulu = now.toDateTime( org.joda.time.DateTimeZone.UTC );
    

    转储到控制台...

    System.out.println( "Local time in ISO 8601 format: " + now );
    System.out.println( "Same moment in UTC (Zulu): " + zulu );
    

    当运行...

    Local time in ISO 8601 format: 2014-01-21T15:34:29.933-08:00
    Same moment in UTC (Zulu): 2014-01-21T23:34:29.933Z
    

    有关进行时区工作的更多示例代码,请参阅我对类似问题的回答。

    时区

    我建议您始终指定一个时区,而不是隐式地依赖JVM的当前默认时区(可随时更改!)。 这种依赖似乎是日期时间工作中混淆和错误的常见原因。

    now()打电话时now()通过所需的/预期的时区进行分配。 使用DateTimeZone类。

    DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" );
    DateTime now = DateTime.now( zoneMontréal );
    

    该类对UTC时区保持不变。

    DateTime now = DateTime.now( DateTimeZone.UTC );
    

    如果您真的想要使用JVM的当前默认时区,请进行明确的调用,以便您的代码可以自行记录。

    DateTimeZone zoneDefault = DateTimeZone.getDefault();
    

    ISO 8601

    阅读ISO 8601格式。 java.time和Joda-Time都使用该标准的敏感格式作为解析和生成字符串的默认值。


    †事实上,java.util.Date确实有一个时区,深埋在源代码层下。 对于大多数实际用途,该时区将被忽略。 所以,作为简写,我们说java.util.Date没有时区。 此外,该埋藏时区不是Date toString方法使用的时区; 该方法使用JVM的当前默认时区。 所有更多的理由避免这个令人困惑的类,坚持Joda-Time和java.time。

    链接地址: http://www.djcxy.com/p/18749.html

    上一篇: How can I get the current date and time in UTC or GMT in Java?

    下一篇: How do I convert local time to UTC in Python?