如何使用Groovy的.format()方法显示本地时间?

时间:2017-04-16 00:02:13

标签: date groovy format

我有一组使用以下代码保存到数据库的日期(我无法更改):

Date date = new Date()
save(date)

在groovy中没有干净的方式重新格式化并在用户的本地时区显示日期吗?比如...

dateCreated.format('h:mm a MMMM dd, yyyy', Locale.US)

Groovy中没有内置的东西吗?是唯一的解决方案吗?

import java.text.SimpleDateFormat

String date = dateCreated.format('h:mm a MMMM dd, yyyy')
def fmt = new SimpleDateFormat('h:mm a MMMM dd, yyyy', Locale.US);
Date local_time = fmt.parse(date);
String formatted_local = local_time.format('h:mm a MMMM dd, yyyy')
formatted_local

Groovy日期文档:http://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Date.html#format(java.lang.String)

参考:How to parse month full form string using DateFormat in Java?

2 个答案:

答案 0 :(得分:2)

在Groovy中应该非常简单。

假设,使用以下声明保存日期

def date = new Date()
println date

输出

Sun Apr 16 11:10:14 UTC 2017

如果您需要将其转换为具有特定日期时间格式的特定时区,请使用以下语句

println date.format('yyyy/MM/dd HH:mm', TimeZone.getTimeZone('IST'))

会显示输出:

2017/04/16 16:40

注意:来源为UTC格式,并将现有日期转换为IST格式。

如果您需要日期对象(不是上面提到的字符串),请使用以下内容:

def date = new Date()
def dtFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
def dt = date.format(dtFormat, TimeZone.getTimeZone('IST'))
assert dt instanceof String

def newDate = Date.parse(dtFormat, dt)
assert newDate instanceof Date

您可以快速在线试用 Demo

答案 1 :(得分:1)

TL;博士

ZonedDateTime.parse ( 
    "Mon Apr 03 16:49:56 PDT 2017" , 
    DateTimeFormatter.ofPattern ( "EEE MMM dd HH:mm:ss z uuuu", Locale.US ) 
) 

语法

抱歉,我不知道Groovy语法,所以这是Java语法。

java.util.Date::toString

您是说通过调用java.util.Date::toString将值作为文本数据类型保存到数据库中?

所以现在你需要用java.util.Date::toString使用的默认格式解析字符串,例如Mon Apr 03 16:49:56 PDT 2017以回到日期时间对象。

首先,您必须已经知道这是存储日期时间值的可怕方式。这种格式假定为英语,并且会减少任何小数秒。这种格式很难被人类阅读,并且很难被机器解析。它使用伪时区的3-4个字母缩写,如PDTIST,这些缩写不是真正的时区,不是标准化的,甚至不是唯一的(!)。 Proper time zone name格式为continent/region,例如America/MontrealAfrica/CasablancaPacific/Auckland

ISO 8601

相反,在序列化日期时间值时,请使用标准ISO 8601格式。

在解析和生成字符串时,java.time类默认使用标准ISO 8601格式。

避免遗留日期时间类

知道java.util.Date是与最早版本的Java捆绑在一起的设计糟糕且设计混乱的旧日期时间类之一。这些类现在是遗留的,取而代之的是java.time类。避免遗留类,改为使用java.time。

使用java.time

DateTimeFormatter类解析字符串。我们必须定义格式模式以匹配Date::toString的输出。

String input = "Mon Apr 03 16:49:56 PDT 2017" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "EEE MMM dd HH:mm:ss z uuuu", Locale.US ) ;

现在我们可以将该字符串解析为ZonedDateTime

ZonedDateTime zdt = ZonedDateTime.parse ( input, f ) ;
  

zdt.toString():2017-04-03T16:49:56-07:00 [America / Los_Angeles]

通常,序列化数据存储和交换的日期时间值的最佳做法是将值保留为UTC,然后生成标准ISO 8601格式的字符串。 ISO 8601中的UTC约定是附加ZZulu的缩写,表示UTC。

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

Instant instant = zdt.toInstant() ;
String output = instant.toString() ;
  

instant.toString():2017-04-03T23:49:56Z

JDBC

您的问题和意见不明确。如果使用适当的日期时间类型将值存储在数据库中,则无需像上面讨论的那样搞乱字符串。如果存储得当,您应该让JDBC驱动程序在根据需要进行转换时执行将数据输入和输出数据库的工作。

符合JDBC 4.2及更高版本的驱动程序可以通过PreparedStatement::setObjectResultSet::getObject直接使用java.time类型。

关于java.time

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

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

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

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