Java 在Google Tasks API中使用Joda时间库将字符串转换为日期时间格式

Java 在Google Tasks API中使用Joda时间库将字符串转换为日期时间格式,java,android,datetime,jodatime,google-tasks-api,Java,Android,Datetime,Jodatime,Google Tasks Api,我有一个日期/时间字符串,需要发送到GoogleTasksAPI,但我不知道如何将库对象转换为Java DateTime对象。我使用Android作为平台 字符串以“2012/07/19 22:00:00”开头,并首先转换为Iso格式 这是我的密码: Task task = new Task(); task.setTitle(title); task.setNotes(note); DateTimeFormatter formatter = Da

我有一个日期/时间字符串,需要发送到GoogleTasksAPI,但我不知道如何将库对象转换为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转换的信息也很有用。

让格式化程序解析字符串 问题在于你的“dateToIso”方法。没必要那样。对象的任务是在给定正确格式时解析字符串。你确实给了它正确的格式。然后你去把字符串变形成不同的格式

解决方案:(a)杀死你的dateToIso方法。(b) 删除对该方法的调用。只需将原始字符串传递到
parseDateTime

次要问题:你忽略了时区的问题。因此,在解析该字符串时,Joda Time将假定该日期时间的事件发生在JVM的默认时区中。因此,在另一台具有不同时区设置的计算机/JVM上使用相同的输入运行相同的代码将导致不同的输出。可能不是你想要的。经验教训:始终指定时区,而不是依赖默认时区

还有一个问题:您引用的错误是另一个问题,从Joda Time转换为Google Time。继续读下去

看医生 如果您试图将
org.joda.time.DateTime
对象转换为
com.google.api.client.util.DateTime
对象,只需查看。在这里,您将看到GoogleDateTime的构造函数采用java.util.Date。Joda Time有一个内置的
toDate
方法来转换为java.util.Date对象,以便与其他类进行互操作

食物链 创建如下对象的食物链:

org.joda.time.DateTime→ java.util.Date→ com.google.api.client.util.DateTime

一些未经测试的代码

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 );
毫秒 或者,您可以提取并传递毫秒

通常,我建议尽可能避免直接处理毫秒。使用毫秒可能会令人困惑、草率和容易出错。毫秒计数很难调试,因为人类无法轻易破译
的日期时间含义。虽然Joda Time和java.util.Date使用Unix历元之后的毫秒作为其内部时间跟踪机制

  • 有些软件使用或而不是毫秒
  • 有些软件使用的是其他软件,而不是
往另一个方向走 [下一节假设谷歌已经用更新的API取代了问题引用的API。不确定这一假设是否正确。]

当从一个对象转到一个Joda Time DateTime时,我将使用
getValue
方法提供的epoch的毫秒计数。请注意,它返回64位
,而不是32位
int

确保将所需的时区分配给Joda时间,而不是依赖于隐式地分配JVM的时间

GoogleAPI提供了一些其他选择

toStringRfc822
您可以调用该方法来生成要由Joda Time解析的字符串。不幸的是,RFC822解析起来既笨拙又含糊不清。除其他故障外,它使用非标准非唯一的3-4字母时区代码,而不是。Joda Time拒绝尝试解析这些代码,因为它们具有歧义性。我假设Google在这里包含它只是为了向后兼容旧的API/库。现代互联网协议已经转向ISO 8601

toUiString
也许您可以调用该方法来创建一个由Joda Time解析的字符串。不幸的是,他们的文档无法解释该方法使用的格式

toString
您可以调用
toString
方法,该方法被记录为生成
xs:dateTime
字符串。医生没能准确解释,但我猜他们指的是。您可以尝试此方法以查看它生成的内容。如果您希望保留嵌入在Google对象中的UTC偏移量,那么它可能很有用。但是请记住,时区不仅仅是UTC的偏移量,因此您仍然应该将所需/预期的时区指定给Joda time DateTime对象。因此,我不确定这是否比将
long
计数从epoch传递给Joda Time DateTime的构造函数更好

java.time 现在发布了,谷歌可能会对其API进行现代化,以使用新的API


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

恰巧是指“Joda time”,不是吗?您问题中的“java DateTime”是指java.util.Date(与java捆绑在一起)还是错误消息中显示的com.google.api.client.util.DateTime?鉴于我们有多个可能的日期-时间框架,您应该注意具体说明。@EugenevanderMerwe请确切说明您所询问的Google API中的类。链接到官方文件以消除任何歧义。亲爱的@BasilBourque,你的观点是正确的。不幸的是,这篇文章已经发表了几年,所以我无法澄清。我在使用Google Calendar API时遇到了类似的问题,特别是上的
getDateTime()
方法,它返回一个
com.Google.API.client.util.DateTime
对象
EventDateTime
对象由使用发出的HTTP请求返回。希望这能为某人澄清。谢谢你的回答。从Google Date到Joda Date,还有比毫秒更好的方法吗?@xdhmoore我在回答中添加了另一个部分,“走另一个方向”
long millisecondsFromUnixEpoch = myGoogleDateTime.getValue();
org.joda.time.DateTimeZone zone = DateTimeZone.forID( "Africa/Johannesburg" );
org.joda.time.DateTime jodaDateTime = new DateTime( millisecondsFromUnixEpoch, zone );