我需要将Joda-Time日期/时间转换为java.util.Date
。我正在做如下。
DateTimeFormatter dateTimeFormatter=DateTimeFormat.forPattern("dd-MMM-yyyy hh:mm:ss aa");
DateTime dateTime = dateTimeFormatter.parseDateTime("2-Oct-2013 11:34:26 AM").withZone(DateTimeZone.UTC);
System.out.println(dateTime);
按预期显示由UTC区域表示的日期/时间。在这种情况下,它是2013-10-02T06:04:26.000Z
将此dateTime
转换为java.util.Date
时,如下所示
System.out.println(dateTime.toDate());
显示,Wed Oct 02 11:34:26 IST 2013
。它应该是UTC
格式。
从Joda-Time转换后,有没有办法在Date
中代表UTC
?
我希望将日期存储到UTC
区域所代表的数据库中。在将org.joda.time.DateTime
插入数据库之前,需要将java.util.Date
转换为java.sql.Timestamp
(或{{1}})。如何克服这种情况?
答案 0 :(得分:5)
每个定义的java.util.Date
对象始终为UTC!
(时间戳是自1.1.1970 UTC以来的毫秒数)
但是你必须在时间格式化之前将timeZone设置为utc:
TimeZone utc = TimeZone.getTimeZone("UTC")
SimpleDateFormatter df = new SimpleDateFormatter (PATTERN);
df.setTimeZone(utc);
System.out.println(df.format(date));
在您的代码中,您使用了使用系统默认TimeZone的java.util.Date.toString()
方法。
答案 1 :(得分:2)
java.util.Date
字符串输出不是UTC 来自你的问题:
它显示,10月02日星期三11:34:26 IST 2013.它应该是UTC格式。
不应该不采用UTC格式。这可能是你想要的,但这并不是课堂行为的记录方式。
您的代码:
System.out.println(dateTime.toDate());
...首先将Joda-Time DateTime
转换为java.util.Date
对象,然后在该j.u.Date对象上隐式调用toString
方法。 j.u.Date对其toString
方法的记录行为是将JVM当前的默认时区应用于生成的字符串。在内部,j.u.Date确实是UTC,但它生成的字符串不是。它的toString
的这种行为是一个善意但最终非常糟糕的Java团队设计决策,它给无数程序员带来了混乱。但它记录了行为。您应该始终仔细阅读库的文档,而不是假设库的行为与您想象的一样。
DateTime
来自你的问题:
从Joda-Time转换后,有没有办法用UTC表示日期?
是的,在Joda-Time中生成DateTime
UTC的字符串表示非常简单明了,与java.util.Date/.Calendar/SimpleDateFormat不同。只需调用withZone
即可根据原始实例显示新的DateTime,但调整为另一个时区。
Joda-Time 2.5中的一个小例子源代码应该很明显。还可以使用Joda-Time搜索StackOverflow以获取数百个示例。
DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" );
DateTime nowInMontréal = DateTime.now( zoneMontréal );
DateTimeZone zoneKolkata = DateTimeZone.forID( "Asia/Kolkata" );
DateTime nowInKolkata = nowInMontréal.withZone( zoneKolkata ); // Instantiating a new date-time object based on the original but adjusted for another time zone.
DateTime nowInUtc = nowInMontréal.withZone( DateTimeZone.UTC ); // Ditto, new object, adjusted time zone.
通过在每个DateTime上调用toString
转储到控制台:
nowInMontréal: 2014-11-14T02:03:19.932-05:00
nowInKolkata: 2014-11-14T12:33:19.932+05:30
nowInUtc: 2014-11-14T07:03:19.932Z
所有这三个代表宇宙时间轴中的同时时刻。蒙特利尔时间比UTC晚5个小时,印度时间比UTC早5个半小时。同一时刻,但不同的挂钟时间。
DateTime
放入数据库来自你的问题:
我希望将日期存储到UTC区域所代表的数据库中。在将org.joda.time.DateTime插入数据库之前,需要将其转换为java.util.Date(或java.sql.Timestamp)。如何克服这种情况?
易。通过传递自Unix纪元以来的毫秒数来构造java.sql.Timestamp对象。请注意,计数必须是long
,而不是int
。
java.sql.Timestamp ts = new java.sql.Timestamp( dateTime.getMillis() );
提示:请注意数据库的日期时间数据类型的性质。例如,Postgres对此类类型提供了出色的支持,包括SQL规范定义的类型。许多数据库都没有,使用旧的遗留类型或只有少数弱类型。阅读文档和实验,以确保您了解行为。
答案 2 :(得分:0)
public Date toDate(TimeZone timeZone)
使用指定的时区将日期时间作为java.util.Date获取。
创建的Date对象与此日期时间具有完全相同的字段,除非由于夏令时间隙而导致时间无效。在这种情况下,时间将设置为差距之后的最早有效时间。
在夏令时重叠的情况下,选择较早的时刻。
转换为JDK日期充满了复杂性,因为JDK Date构造函数的行为与您在DST转换时的预期不同。该方法通过先猜测然后调整来工作。这也处理JDK时区数据与Joda-Time时区数据不同的情况。
与toDate()不同,此实现不依赖于Java的同步时区初始化逻辑,并且应该展示更好的并发性能特征。
所以这看起来像:
Timezone utc = Timezone.getTimezone("UTC")
System.out.println(dateTime.toDate(utc));
让我知道它是否有效。