2017-04-16 393 views
1

我有一组日期的已保存到数据库中使用下面的代码(我不能改变):如何使用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?

+0

我不明白你的问题,但如果你认为它可以用Java做了,那么它也可以在Groovy实现为Java代码是有效的Groovy。我会用'Date.parse('h:mm a MMMM dd,yyyy','6:31 PM June 27,2007')' – bdkosher

+0

有没有更通用的方法?即假设日期在数据库中以格式“MM-d-yyyy-h-mm-s”存储,我如何使用Date.parse以新格式打印日期? –

+0

您将日期保存为数据库中的字符串? –

回答

1

应在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

FYI,麻烦的老的日期 - 时间类,如['java.util.Date'](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html),[ 'java.util.Calendar'](https://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html)和'java.text。SimpleTextFormat'现在是[legacy](https://en.wikipedia.org/wiki/Legacy_system),由[java.time]代替(https://docs.oracle.com/javase/8/docs/api/ java/time/package-summary.html)类。 –

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/Montreal,Africa/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 [美国/洛杉矶]

一般对于用于序列化的日期 - 时间值的最佳实践数据存储和交换将保持UTC值,然后以标准ISO 8601格式生成一个字符串。 ISO 8601中UTC的约定是附加Z,简写为Zulu,意思是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。时间

java.time框架内置于Java 8及更高版本。这些类取代了日期时间类legacy,如java.util.Date,Calendar,& SimpleDateFormat

Joda-Time项目现在位于maintenance mode,建议迁移到java.time类。请参阅Oracle Tutorial。并搜索堆栈溢出了很多例子和解释。规格是JSR 310

从何处获取java.time类?

ThreeTen-Extra项目与其他类扩展java.time。这个项目是未来可能增加java.time的一个试验场。您可以在这里找到一些有用的类,如Interval,YearWeek,YearQuartermore

+0

我会在下次尝试。 Groovy/Grails似乎默认为Java.util.Date,所以我认为它是标准的。 Java.time看起来好多了。 –

+0

@DevonLuongo将java.time与传统类进行比较就像比较[Yugo cars](https://en.m.wikipedia.org/wiki/Yugo)与本田汽车 - 完全没有任何比较。 –

+0

更新:不幸的是,Grails与Java.time存在兼容性问题。临时解决方案已张贴在这里:http://stackoverflow.com/questions/32974704/grails-3-and-java-8-time-support –