让格式化程序解析字符串
问题是您的“dateToIso”方法。没必要。DateTimeFormatter对象的工作是在给定正确格式时解析字符串。你确实给了它正确的格式。然后你去把字符串变形为不同的格式!
解决方案:(a)杀死你的 dateToIso 方法。(b) 删除对该方法的调用。只需将原始字符串传递给parseDateTime
.
附带问题:您忽略了时区问题。因此,在解析该字符串时,Joda-Time 将假定该日期时间的事件发生在您的 JVM 的默认时区中。因此,使用相同的输入但在另一台具有不同时区设置的计算机/JVM 上运行相同的代码将导致不同的输出。可能不是你想要的。经验教训:始终指定时区而不是依赖默认值。
另一个问题:您引用的错误是另一个问题,从 Joda-Time 转换为 Google 时间。继续阅读。
阅读文档
如果您尝试将org.joda.time.DateTime
对象转换为com.google.api.client.util.DateTime
对象,只需查看JavaDoc。在那里,您将看到 Google DateTime 的构造函数采用 java.util.Date。Joda-Time 有一个内置toDate
方法可以转换为 java.util.Date 对象,以便与其他类进行互操作。
食物链
像这样创建一个对象的食物链:
org.joda.time.DateTime → java.util.Date → com.google.api.client.util.DateTime
一些未经测试的代码……</p>
org.joda.time.DateTimeZone = org.joda.time.DateTimeZone.forID( "Africa/Johannesburg" );
org.joda.time.DateTime jodaDateTime = new DateTime( timeZone );
// Convert from Joda-Time to old bundled j.u.Date
java.util.Date juDate = jodaDateTime.toDate();
// Convert from j.u.Date to Google Date.
com.google.api.client.util.DateTime googleDateTime = new com.google.api.client.util.DateTime( juDate );
毫秒
或者,您可以提取并传递毫秒。
一般来说,我建议尽可能避免直接处理毫秒。使用毫秒可能会令人困惑、草率且容易出错。毫秒计数很难调试,因为人类无法轻易破译long
. 而 Joda-Time 和 java.util.Date 使用毫秒-since-Unix-epoch 作为它们的内部时间跟踪机制......
走向另一个方向
[以下部分假设 Google 已用更新的 API 取代了问题引用的 API。不确定这个假设是否正确。]
当从com.google.gdata.data.DateTime对象转到 Joda-Time DateTime 时,我将使用该getValue
方法提供的毫秒数。请注意,它返回 64-bit long
,而不是 32-bit int
。
请务必将所需的时区分配给 Joda-Time DateTime
,而不是依赖于隐式分配 JVM 的当前默认时区。
long millisecondsFromUnixEpoch = myGoogleDateTime.getValue();
org.joda.time.DateTimeZone zone = DateTimeZone.forID( "Africa/Johannesburg" );
org.joda.time.DateTime jodaDateTime = new DateTime( millisecondsFromUnixEpoch, zone );
Google API 提供了一些其他选择。
toStringRfc822
您可以调用该toStringRfc822
方法来生成要由 Joda-Time 解析的字符串。不幸的是,RFC 822 解析起来很笨拙且模棱两可。在其他错误中,它使用了非标准的非唯一 3-4 字母时区代码,而不是正确的时区名称。Joda-Time 拒绝尝试解析这些代码,因为它们模棱两可。我假设 Google 仅在此处包含它是为了与旧 API/库向后兼容。现代互联网协议已转向 ISO 8601。
toUiString
也许您可以调用该toUiString
方法来创建要由 Joda-Time 解析的字符串。不幸的是,他们的文档未能解释该方法使用什么格式。
toString
您可以调用toString
记录为生成xs:dateTime
字符串的方法。该文档未能准确解释,但我猜他们的意思是XML Schema 规范包含 ISO 8601。你可以试试这个方法看看它会产生什么。如果您想保留嵌入在 Google 对象中的与 UTC 的偏移量,这可能会很有用。但请记住,时区不仅仅是与 UTC 的偏移量,因此您仍应将所需/预期的时区分配给您的 Joda-Time DateTime 对象。因此,我不确定这是否比仅将long
count-from-epoch 传递给 Joda-Time DateTime 的构造函数更好。
java.time
现在Java 8发布了,也许 Google 可能会对其 API 进行现代化改造以使用java.time 包。
请注意,java.time 扩展了 ISO 8601 格式以附加时区的正式名称,这是一个非常有用的想法。