Reputation: 133
I have a date, assumed to be in GMT, which I want to convert to local time zone using the ISO_OFFSET_DATE_TIME formatting.
Basically, I want to go from:
2018-03-13 03:00:00.0
to:
2018-03-13T00:00:00-09:00
Obviously this would change, depending on your local time zone.
Any ideas on how I could do this?
Upvotes: 0
Views: 1505
Reputation: 79395
LocalDateTime
:DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s.S", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse("2018-03-13 03:00:00.0", dtf);
OffsetDateTime
:OffsetDateTime odtUtc = ldt.atOffset(ZoneOffset.UTC);
OffsetDateTime odtUtcMinus9 = odtUtc.withOffsetSameInstant(ZoneOffset.of("+09:00"));
Demo:
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s.S", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse("2018-03-13 03:00:00.0", dtf);
System.out.println(ldt); // 2018-03-13T03:00
OffsetDateTime odtUtc = ldt.atOffset(ZoneOffset.UTC);
System.out.println(odtUtc); // 2018-03-13T03:00Z
OffsetDateTime odtUtcMinus9 = odtUtc.withOffsetSameInstant(ZoneOffset.of("+09:00"));
System.out.println(odtUtcMinus9); // 2018-03-13T12:00+09:00
}
}
Note that the timezone offset is a fixed thing i.e. it is independent of the DST. If you are looking for an automatic adjustment of timezone offset as per the DST, use ZonedDateTime
. The methods are very much similar to what we have used in the last demo.
Demo:
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s.S", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse("2018-03-13 03:00:00.0", dtf);
System.out.println(ldt); // 2018-03-13T03:00
ZonedDateTime zdtUtc = ldt.atZone(ZoneId.of("Etc/UTC"));
System.out.println(zdtUtc); // 2018-03-13T03:00Z[Etc/UTC]
ZonedDateTime zdtAmericaAdak = zdtUtc.withZoneSameInstant(ZoneId.of("America/Adak"));
System.out.println(zdtAmericaAdak); // 2018-03-12T18:00-09:00[America/Adak]
// A custom format
DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSXXX", Locale.ENGLISH);
String formatted = dtfOutput.format(zdtAmericaAdak);
System.out.println(formatted); // 2018-03-12 18:00:00.000-09:00
}
}
Learn more about java.time
, the modern date-time API* from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Upvotes: 1
Reputation: 143
You can leverage ZonedDateTime
for this. You just need to read in the date as UTC and convert it as needed. You might get something like this:
String readPattern = "yyyy-MM-dd HH:mm:ss.S";
DateTimeFormatter readDateTimeFormatter = DateTimeFormatter.ofPattern(readPattern).withZone(ZoneOffset.UTC);
LocalDateTime utcLocalDateTime = LocalDateTime.parse("2018-03-13 03:00:00.0", readDateTimeFormatter);
ZonedDateTime localZonedDateTime = utcLocalDateTime.atOffset(ZoneOffset.UTC).atZoneSameInstant(ZoneId.systemDefault());
String writePattern = "yyyy-MM-dd HH:mm:ssXXX";
DateTimeFormatter writeDateTimeFormatter = DateTimeFormatter.ofPattern(writePattern);
System.out.println(writeDateTimeFormatter.format(localZonedDateTime));
For more info, see:
Upvotes: 2