4

我有一个需要发送到 Google Tasks API 的日期/时间字符串,但我不知道如何将Joda-TimeDateTime对象转换为 Java DateTime 对象。我使用 Android 作为平台。

该字符串以“2012/07/19 22:00:00”开头,并首先转换为 Iso 格式。

这是我的代码:

    Task task = new Task();
    task.setTitle(title);
    task.setNotes(note);        
    DateTimeFormatter formatter =  DateTimeFormat.forPattern("yyyy/MM/dd HH:mm:ss");
    DateTime dt = formatter.parseDateTime(dateToIso("2012/07/19 22:00:00"));
    task.setDue(dt);    

private String dateToIso(String date) {
    date = date.replace("/", "-");
    date = replaceCharAt(date, 10, 'T');
    date = date + ".000Z";
    return date;
}

我得到的错误是:

“类型不匹配:无法从 org.joda.time.DateTime 转换为 com.google.api.client.util.DateTime”

请协助。有关 ISO 转换的信息也很有用。

4

1 回答 1

3

让格式化程序解析字符串

问题是您的“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 对象。因此,我不确定这是否比仅将longcount-from-epoch 传递给 Joda-Time DateTime 的构造函数更好。

java.time

现在Java 8发布了,也许 Google 可能会对其 API 进行现代化改造以使用java.time 包

请注意,java.time 扩展了 ISO 8601 格式以附加时区的正式名称,这是一个非常有用的想法。

于 2014-02-12T09:54:13.910 回答