【问题标题】:Java time in GMT格林威治标准时间的 Java 时间
【发布时间】:2011-10-30 00:33:22
【问题描述】:

我有一个带有以下代码的 Grails 应用程序:

Date now = Calendar.getInstance().getTime() //Also tried new Date()
println "now: " + now

当我这样做时,我得到now: Thu Aug 18 12:47:09 CDT 2011。我需要日期为 GMT,而不是本地时间,因为我需要将 GMT 时间存储在数据库中。我可以使用 simpleDateFormat 对象打印出 GMT 时间,但我需要将其实际存储为 GMT。

问题:如何使用 GMT 将 Date 对象转换为 Date 对象?

【问题讨论】:

  • @jpredham 可能应该得到这个问题的“答案”,因为他在将日期/时间检索为 GMT 时是正确的。 (我自己测试过,发现它是真的。)另外,他比较新,我们其他人已经有了相当多的声誉。
  • 仅供参考,麻烦的旧日期时间类,如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 和 Java 中内置的 java.time 类所取代9. 见Tutorial by Oracle

标签: java grails date gmt


【解决方案1】:

这突出了为什么 Java 在时间上很糟糕。之前的帖子都已经接近了,但是我们需要非常小心地获取 GMT 中的当前时间,以及获取 CDT 中的当前时间并将其调用 GMT。

TimeZone reference = TimeZone.getTimeZone("GMT");
Calendar myCal = Calendar.getInstance(reference);

这是 GMT 的当前时间,时区为 GMT。

要转换为保持区域完整的 Date 对象,您需要调用:

TimeZone.setDefault(reference);

此设置将与您当前的 JVM 一样长。现在调用 get Time 应该会产生预期的结果。

myCal.getTime();

【讨论】:

  • 向你致敬!我更改了我的帖子以更好地反映您所说的内容。甚至 ZONE_OFFSET 也没有用。好收获!
【解决方案2】:

好吧,如果你真的想要 GMT 时间,你需要得到它作为 GMT(@jpredham 是对的。向你致敬!编辑我的帖子以反映这一点)

所以请执行以下操作

//this option uses TimeZone
TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT");
TimeZone.setDefault(gmtTimeZone);
Calendar calendar = Calender.getInstance(gmtTimeZone);

Date myDate = calendar.getTime();

【讨论】:

    【解决方案3】:

    试试这个:

    println Calendar.getInstance(TimeZone.getTimeZone('GMT')).format('HH:mm:ss')
    

    请注意,当您转换为日期时,您会丢失时区信息。当 Java/Groovy 格式化您的日期以进行打印时,它会自动将其格式化为您的本地时区。不用担心,您的日期没有与之关联的时区。您可以在显示时重新添加正确的时区:

    Date now = Calendar.getInstance(TimeZone.getTimeZone('GMT')).time
    def formatter = new java.text.SimpleDateFormat('HH:mm:ss')
    formatter.timeZone = TimeZone.getTimeZone('GMT')
    println formatter.format(now)
    

    【讨论】:

      【解决方案4】:

      Calendar 对象在内部以 UTC(GMT 的现代名称)存储时间。 getTimeInMillis() 返回一个 UTC 值,并且可能是您想要存储的值。

      【讨论】:

        【解决方案5】:

        你应该试试 GregorianCalendar#setTimeZone(TimeZone timeZone)。

        【讨论】:

          【解决方案6】:

          使用 System.currentTimeMillis() 不仅比使用 Calendar 或 Date 快得多,而且它始终为您提供 GMT 时间。如果您想显示这个时间,您可以使用 SimpleDateFormat,将时区设置为您想要的任何时间。

          【讨论】:

            【解决方案7】:

            您将日期时间对象与其字符串表示混淆了。 Java 中的所有常见日期时间库(Java 8 中的 java.util.Date、Joda-Time、java.time)在内部跟踪自 1970 年第一刻(UTC)以来的小数秒数,同时忽略闰秒。因此,在所有三个库中,日期时间始终为 internally UTC/GMT。

            因此,您关于如何在 GMT (UTC) 中将 Date 对象转换为 Date 对象的问题毫无意义。

            两个更好的库(Joda-Time 和 java.time)也在日期时间对象内跟踪时区。出了名的麻烦 java.util.Date 没有分配时区,但在调用 toString 方法时会混淆地应用 JVM 的当前默认时区。

            为了记录,Joda-Time 对此做了简短的处理。

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

            调用该对象的 toString 方法会在祖鲁 (UTC) 时间生成 ISO 8601 格式的字符串。

            在 StackOverflow 中搜索“Joda”和“formatter”,找到许多适应其他时区的示例。

            【讨论】:

              【解决方案8】:

              tl;博士

              Instant.now()    // Capture current moment in UTC.
                  .toString()  // Generate a String object in standard ISO 8601 format, YYYY-MM-DDTHH:MM:SS.SSSSSSSSSZ.
              

              2018-02-16T23:28:01.101324Z

              java.time

              现代方法使用 java.time 类。完全避免麻烦的遗留日期时间类。

              Instant 类表示UTC 中时间轴上的时刻,分辨率为nanoseconds(最多九 (9) 位小数)。

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

              通过调用toString 生成标准 ISO 8601 格式的字符串。

              String output = instant.toString() ;
              

              如果您需要比Instant 提供的更多灵活性,例如在生成字符串时进行格式化,请使用OffsetDateTime 和常量ZoneOffset.UTC

              OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;  // Capture the current moment in UTC.
              

              要生成非标准格式的字符串,请使用DateTimeFormatter


              关于java.time

              java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

              Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

              要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

              使用符合JDBC 4.2 或更高版本的JDBC driver,您可以直接与您的数据库交换java.time 对象。不需要字符串也不需要 java.sql.* 类。

              从哪里获得 java.time 类?

              ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

              【讨论】:

                猜你喜欢
                • 2011-05-13
                • 2013-03-10
                • 1970-01-01
                • 2010-12-02
                • 2013-06-01
                • 2011-02-04
                • 2019-11-25
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多