etherton
etherton

Reputation: 942

Joda Time: Parse string and override time zone, if time zone is omitted

This is my scenario: I want to parse time stamps that the user gives me. If the time stamp doesn't have time zone information, I want to assume the time stamp is in the user's timezone, if the timestamp does define it's timezone, use that.

Here are the parts that make it hard:

What I want is something like:

DateTimeFormatter parser = ISODateTimeFormat.dateTimeParser()
DateTimeZone userTimeZone = getUserTimeZone(); //assume -04:00

//returns 2014-05-17T15:36:14+02:00
parser.parseDateTime("2014-05-17T15:36:14+02:00", userTimeZone); 

//returns 2014-05-17T15:36:14-04:00
parser.hasTimeZone("2014-05-17T15:36:14", userTimeZone);

Is there any easy way to do this?

Upvotes: 2

Views: 657

Answers (2)

etherton
etherton

Reputation: 942

It turns out I was wrong about how withZone() works. If a time zone information is specified in the time stamp, it will only adjust the chronology, but the underlying milliseconds since the epoch will still be the same, but if a time zone is not set in the time stamp, it will offset the milliseconds since the epoch to make the time correct for the given time zone.

I thought since the Joda Time documentation said,

When parsing, this zone will be set on the parsed datetime.

That it would overwrite the time zone, but I was wrong. withZone() is exactly what I needed.

This is the code I ended up using:

DateTimeZone timeZone = user.getTimeZone();
DateTime dateTime = ColumnTypeUtil.DATE_FORMATTER.withZone(timeZone).parseDateTime(formattedValue);
String dbTimeStamp = ISODateTimeFormat.dateTime().withZone(DateTimeZone.UTC).print( dateTime );

Upvotes: 0

Warren Dew
Warren Dew

Reputation: 8928

I would divide this problem into two parts. The first part is to figure out whether the string has time zone information in it. The second is to parse the string the way you want.

I believe the following will work for the first part. First, create two DateTimeFormatter objects with different time zones. Now, parse the string with both objects. Now call getDate() on both results. If both dates are the same, the string had a time zone in it, and specified an instant in time, which was appropriately adjusted by both DateTimeFormatter objects. If the dates are different, the string had no time zone in it, and specified a local date and time, which was assumed by each DateTimeFormatter to be its own time zone.

Now you can do the second part, choosing whether to use a DateTimeFormatter withOffsetParsed() or one withZone() in the user's time zone, depending on whether the string has the time zone.

This requires four different DateTimeFormatter objects, but it's straightforward if not simple. It can be optimized to use only three different DateTimeFormatter objects, by using one with the user's time zone as one of the two that are used in the first part of the solution - in which case you have to reparse in the second part of the solution only if the string had a time zone in it.

Upvotes: 1

Related Questions