GMT中的Java时间

我有一个Grails应用程序,代码如下:

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

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

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

这突出了Java为什么会吮吸的原因。 之前的post都很接近,但我们需要非常小心地获取当前GMT时间,并将当前时间记录在CDT并称之为 GMT。

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

这是格林尼治标准时间的当前时间,具有GMT的时区背景。

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

 TimeZone.setDefault(reference); 

此设置将持续与您当前的JVM一样长。 现在调用get Time应该产生所需的结果。

 myCal.getTime(); 

好吧,如果你真的想要GMT的时间,你需要把它作为GMT(@jpredham是对的。感谢你!编辑我的post以反映这一点)

所以做以下事情

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

尝试这个:

 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) 

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

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

使用System.currentTimeMillis()不仅比使用Calendar或Date快得多,它总是为您提供GMT时间。 如果要显示此时间,可以使用SimpleDateFormat,将时区设置为您想要的时间。

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

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

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

为了记录,Joda-Time做了这个简短的工作。

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

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

搜索“Joda”和“formatter”的StackOverflow,找到调整到其他时区的许多示例。

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时间轴上的一个时刻,分辨率为纳秒 (最多九(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及更高版本中。 这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

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

要了解更多信息,请参阅Oracle教程 。 并搜索Stack Overflow以获取许多示例和解释。 规范是JSR 310 。

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

从哪里获取java.time类?

  • Java SE 8Java SE 9及更高版本
    • 内置。
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9增加了一些小function和修复。
  • Java SE 6Java SE 7
    • 许多java.timefunction都被反向移植到ThreeTen-Backport中的 Java 6和7。
  • Android的
    • 更高版本的Android捆绑java.time类的实现。
    • 对于早期的Android, ThreeTenABP项目采用ThreeTen-Backport (如上所述)。 请参见如何使用ThreeTenABP ….

ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如IntervalYearWeekYearQuarter等。