Reputation: 4670
I have a date/time string which needs to be sent to the Google Tasks API but I can't figure out how to convert a Joda-Time library DateTime object to a Java DateTime object. I'm using Android as the platform.
The string starts off as "2012/07/19 22:00:00" and is first converted to Iso format.
Here is my code:
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;
}
The error I am getting is:
"Type mismatch: cannot convert from org.joda.time.DateTime to com.google.api.client.util.DateTime"
Please assist. Information with regards to ISO conversion would also be useful.
Upvotes: 4
Views: 4459
Reputation: 339043
The problem is your "dateToIso" method. No need for that. The DateTimeFormatter object's job is to parse the string when given the correct format. You did indeed give it the correct format. And then you went and morphed the string into a different format!
Solution: (a) Kill your dateToIso method. (b) Delete the call to that method. Just pass the original string to parseDateTime
.
Side-Problem: You ignored the issue of time zone. So when parsing that string, Joda-Time will assume the event of that date-time occurred in your JVM's default time zone. So running this same code with same inputs but on another computer/JVM with different time zone settings will result in different output. Probably not what you want. Lesson Learned: Always specify a time zone rather than rely on default.
Yet Another Problem: The error you quoted is a different problem, converting from Joda-Time to Google time. Read on.
If you are trying to convert your org.joda.time.DateTime
object to a com.google.api.client.util.DateTime
object, just look at the JavaDoc. There you will see that the constructor of the Google DateTime takes a java.util.Date. Joda-Time has a built-in toDate
method to convert to a java.util.Date object for interoperability with other classes.
Create a food chain of objects like this:
org.joda.time.DateTime → java.util.Date → com.google.api.client.util.DateTime
Some untested code…
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 );
Alternatively, you could extract and pass milliseconds.
Generally I recommend avoiding dealing directly with milliseconds where possible. Using milliseconds can be confusing, sloppy, and error-prone. A milliseconds count is difficult to debug as humans cannot readily decipher the date-time meaning of a long
. While Joda-Time and java.util.Date use milliseconds-since-Unix-epoch as their internal time-tracking mechanism…
[The following section assumes Google has supplanted the API referenced by the Question with a newer API. Not sure if this assumption is correct.]
When going from a com.google.gdata.data.DateTime object to a Joda-Time DateTime, I would use the milliseconds count-from-epoch provided by the getValue
method. Note that it returns a 64-bit long
, rather than a 32-bit int
.
Be sure to assign the desired time zone to the Joda-Time DateTime
rather than rely on implicitly assigning the JVM’s current default time zone.
long millisecondsFromUnixEpoch = myGoogleDateTime.getValue();
org.joda.time.DateTimeZone zone = DateTimeZone.forID( "Africa/Johannesburg" );
org.joda.time.DateTime jodaDateTime = new DateTime( millisecondsFromUnixEpoch, zone );
The Google API provides a few other choices.
toStringRfc822
You could call the toStringRfc822
method to generate a string to be parsed by Joda-Time. Unfortunately, RFC 822 is awkward and ambiguous to parse. Among other faults it uses the non-standard non-unique 3-4 letter time zone codes rather than proper time zone names. Joda-Time refuses to attempt parsing those codes because of their ambiguity. I assume Google only includes it here for backward-compatibility with old APIs/libraries. The modern Internet protocols have moved on to ISO 8601.
toUiString
Perhaps you could call the toUiString
method to create a string to be parsed by Joda-Time. Unfortunately, their documentation fails to explain what format is used by that method.
toString
You could call the toString
method that is documented as producing a xs:dateTime
string. The doc fails to explain precisely, but I'm guessing they mean the XML Schema spec’s inclusion of ISO 8601. You might try this method to see what it generates. It may be useful if you want to preserve the offset-from-UTC embedded in the Google object. But remember that a time zone is more than an offset-from-UTC, so you should still assign the desired/expected time zone to your Joda-Time DateTime object. Therefore, I'm not sure if this better than just passing the long
count-from-epoch to the constructor of Joda-Time DateTime.
Now that Java 8 is released, perhaps Google may modernize its APIs to use the java.time package.
Note that java.time extends the ISO 8601 format to append the formal name of the time zone, a very helpful idea.
Upvotes: 3