Reputation: 719
I have a two part issue, or maybe its two different ways to solve this. I receive an ISO string like 2015-11-17T17:10:24-0800. The end goal is to display the string as 11/17/15 5:10 PM in some HTML generated by some Freemarker. The string I receive could be in any timezone, but I always need to display the string in its local timezone as shown above. Currently, our code was just taking the string and passing it into the template and coverting as such:
<#assign mydate = obj.mydate?datetime("yyyy-MM-dd'T'HH:mm:ssz")?string.short>
This is no longer good since I believe Freemarker is using the system's local timezone and now we are getting more than one timezone. I see there is an iso method in freemarker. So I try
<#assign order_date = order.order_date?iso("yyyy-MM-dd'T'HH:mm:ssz")>
but I keep getting error:
For "?iso" left-hand operand: Expected a date, but this evaluated to a string
Ok I need a date. Working with Joda, I try and create a datetime object by:
DateTime dateTime = ISODateTimeFormat.dateTimeNoMillis().parseDateTime("2015-11-17T17:10:24-0800");
But that appears to use my local timezone as well and shows 2015-11-17T20:10:24.000-05:00. I know I could do withZone(...) but I dont know the zone other than the -0800 or whatever zone is passed at the end of the string. So I'm at a loss of what to do now. Oh, and I cannot change the format of the string I receive.
Upvotes: 4
Views: 1202
Reputation: 79075
java.time
Shown below is a notice on the Joda-Time Home Page:
Note that from Java SE 8 onwards, users are asked to migrate to
java.time
(JSR-310) - a core part of the JDK which replaces this project.
In March 2014, Java 8 introduced the modern, java.time
date-time API which supplanted the error-prone legacy, java.util
date-time API. Any new code should use the java.time
API*.
The string, 2015-11-17T17:10:24-0800 contains a ZoneOffset
of -08:00, rather than a time zone. Therefore, it should be parsed into an OffsetDateTime
. Had it contained a ZoneId
e.g. ZoneId
of Pacific/Pitcairn, a ZonedDateTime
would have been the appropriate object to parse into.
Once you have parsed it into an OffsetDateTime
, you can format it as desired.
If you want to convert it into an OffsetDateTime
with another ZoneOffset
, you can do so using OffsetDateTime#withOffsetSameInstant
.
Demo:
public class Main {
public static void main(String[] args) {
DateTimeFormatter parser = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssZ");
OffsetDateTime odt = OffsetDateTime.parse("2015-11-17T17:10:24-0800", parser);
System.out.println(odt);
// Print it in a custom format
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/uu");
String odtFormatted = odt.format(formatter);
System.out.println(odtFormatted);
// Convert it into an OffsetDateTime with another ZoneOffset
// A sample ZoneOffset
ZoneOffset zoneOffset = ZoneOffset.of("-04:00");
OffsetDateTime odtWithAnotherOffset = odt.withOffsetSameInstant(zoneOffset);
System.out.println(odtWithAnotherOffset);
}
}
Output:
2015-11-17T17:10:24-08:00
11/17/15
2015-11-17T21:10:24-04:00
Learn more about the modern Date-Time API from Trail: Date Time.
* If you are receiving an instance of java.util.Date
, convert it tojava.time.Instant
, using Date#toInstant
and derive other date-time classes of java.time
from it as per your requirement.
Upvotes: 2
Reputation: 6656
DateTime dateTime = ISODateTimeFormat.dateTimeNoMillis().withOffsetParsed().parseDateTime("2015-11-17T17:10:24-0800");
This will create a DateTime
with a fixed timezone offset of -08:00
.
Upvotes: 5
Reputation: 138
May require a little more work, but you could always use the DateTimeFormatterBuilder to create your own custom display for the Date Time. This way you could drop the TimeZone if you care to and render it for within that TimeZone or render locally.
Upvotes: 0