Using Joda-Time Library to Convert String to DateTime Format in Google Tasks API

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.

Answers


Let Formatter Parse String

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.

Read The Doc

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.

Food-Chain

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 );

Milliseconds

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…

Going The Other Direction

[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.

java.time

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.


Need Your Help

iText - how to do search/replace on existing RTF document

c# itext mailmerge

Currently I'm working on a simple Mail-Merge module.

Something strange with my sqlite method

ios xcode sqlite

What I'm trying to do is the following: