I have below code.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
LocalDateTime myDate = LocalDateTime.parse("2020-11-16T02:27:39.345Z", formatter);
But it throws below error in the second line. Not sure why it's complaining Z
java.time.format.DateTimeParseException: Text '2020-11-16T02:27:39.345Z' could not be parsed at index 23
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:492)
LocalDateTime does not have timezone or zone-offset information whereas your date-time string has zone-offset. The letter, Z at the end of your date-time string stands for Zulu i.e. zone-offset of UTC. You can parse it into OffsetDateTime or ZonedDateTime or Instant directly (i.e. without using a custom DateTimeFormatter).
Demo:
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
String dateTimeString = "2020-11-16T02:27:39.345Z";
OffsetDateTime odt = OffsetDateTime.parse(dateTimeString);
System.out.println(odt);
ZonedDateTime zdt = ZonedDateTime.parse(dateTimeString);
System.out.println(zdt);
Instant instant = Instant.parse(dateTimeString);
System.out.println(instant);
}
}
Output:
2020-11-16T02:27:39.345Z
2020-11-16T02:27:39.345Z
2020-11-16T02:27:39.345Z
Related
i was trying to convet string time into ZonedDateTime but not comes up with solution . This is the string format of time "2022-12-23T07:20:00"
i have tried this approach
String stringDate = "2022-12-23T07:20:00";
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
ZonedDateTime ztdOfDateOfPurchase = ZonedDateTime.parse(stringDate , dateTimeFormatter);
this error is coming=> java.time.format.DateTimeParseException: Text '2022-12-23T07:20:00' could not be parsed at index 19
Simply parse your date-time string using LocalDateTime#parse and add the applicable ZoneId to get the ZonedDateTime.
Note that java.time API is based on ISO 8601 and therefore you do not need a DateTimeFormatter to parse a date-time string which is already in ISO 8601 format (e.g. your date-time string, 2022-12-23T07:20:00).
Demo:
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
class Main {
public static void main(String[] args) {
LocalDateTime ldt = LocalDateTime.parse("2022-12-23T07:20:00");
// Replace ZoneId.systemDefault() with the applicable zone ID e.g.
// ZoneId.of("America/New_York")
ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());
System.out.println(zdt);
// Alternatively,
zdt = ldt.atZone(ZoneId.systemDefault());
System.out.println(zdt);
}
}
Output in my timezone:
2022-12-23T07:20Z[Europe/London]
2022-12-23T07:20Z[Europe/London]
Learn more about the modern Date-Time API from Trail: Date Time.
I am reading data from upstream system and it returns the date in string format like this,
String dateFromUpstream = 11-14-2022 10:41:12 EDT
Now, I want to convert this string to a date format of UTC timezone and then store it into my entity.
I tried the following way,
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd-yyyy HH:mm:ss z");
LocalDateTime date = ZonedDateTime.parse(dateFromUpstream, formatter).toLocalDateTime().atZone(ZoneId.of("UTC"));
But this doesn't change the date to UTC timezone. It still gives me the same date with UTC instead of EDT at the end of the string.
Anyone know how I can do this and then store into an entity?
Parse the given date-time string into a ZonedDateTime with the corresponding DateTimeFormatter and then convert the resulting ZonedDateTime into an Instant or another ZonedDateTime corresponding to UTC, using ZonedDateTime#withZoneSameInstant.
Demo:
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String dateFromUpstream = "11-14-2022 10:41:12 EDT";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM-dd-uuuu HH:mm:ss z", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(dateFromUpstream, dtf);
Instant instant = zdt.toInstant();
System.out.println(instant);
// Or get a ZonedDateTime at UTC
ZonedDateTime zdtUTC = zdt.withZoneSameInstant(ZoneOffset.UTC);
System.out.println(zdtUTC);
// If you want LocalDateTime
LocalDateTime ldt = zdtUTC.toLocalDateTime();
System.out.println(ldt);
}
}
See this code run at Ideone.com.
Output:
2022-11-14T15:41:12Z
2022-11-14T15:41:12Z
2022-11-14T15:41:12
Learn more about the modern Date-Time API from Trail: Date Time.
Note: As suggested by Basil Bourque, you can convert the parsed date-time into an OffsetDateTime at UTC as shown below:
OffsetDateTime odtUTC = zdt.toOffsetDateTime()
.withOffsetSameInstant(ZoneOffset.UTC);
"2021-09-17 11:48:06 UTC"
I want to parse the following string and create a LocalDateTime object or an Instant
I know you can write something like this
String dateTime = "2021-09-17 11:48:06 UTC";
LocalDateTime dt = LocalDateTime.parse(dateTime,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
How do I deal with the UTC part in the string?
Never hardcode the standard timezone text like UTC, GMT etc.
Never hardcode the standard timezone text like UTC, GMT etc. which DateTimeFormatter is already capable of handling in the best way.
Parse the given Date-Time string using the pattern, uuuu-MM-dd HH:mm:ss VV into a TemporalAccessor from which you can get the Instant as well as the LocalDateTime.
Demo:
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "2021-09-17 11:48:06 UTC";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss VV", Locale.ENGLISH);
TemporalAccessor temporalAccessor = dtf.parse(strDateTime);
Instant instant = Instant.from(temporalAccessor);
LocalDateTime ldt = LocalDateTime.from(temporalAccessor);
System.out.println(instant);
System.out.println(ldt);
}
}
Output:
2021-09-17T11:48:06Z
2021-09-17T11:48:06
ONLINE DEMO
Alternatively:
Parse the given Date-Time string using the pattern, uuuu-MM-dd HH:mm:ss VV into a ZonedDateTime from which you can get the Instant as well as the LocalDateTime.
Demo:
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "2021-09-17 11:48:06 UTC";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss VV", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);
Instant instant = Instant.from(zdt);
LocalDateTime ldt = zdt.toLocalDateTime();
System.out.println(zdt);
System.out.println(instant);
System.out.println(ldt);
}
}
Output:
2021-09-17T11:48:06Z[UTC]
2021-09-17T11:48:06Z
2021-09-17T11:48:06
ONLINE DEMO
Learn more about 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.
"2021-09-17 11:48:06 UTC" isn't a local date time: it's a date time, because it has a time zone. And because your time has a time zone, it doesn't match your pattern, which doesn't.
If your time strings always end with exactly "UTC", you can make that a literal in the pattern:
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss 'UTC'");
If you need to handle other time zones than UTC, you can use z:
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
but note that this is for parsing a zoned date time; from that, you can extract the local date time:
ZonedDateTime zdt = ZonedDateTime.parse(dateTime,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
LocalDateTime ldt =z dt.toLocalDateTime();
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?
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:
https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
Parse the date-time string into 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);
Combine this with UTC offset to create an OffsetDateTime:
OffsetDateTime odtUtc = ldt.atOffset(ZoneOffset.UTC);
Create its copy with offset set as -09:00 while keeping the instant same:
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.
I am trying to convert date 06-12-2015 02:10:10 PM from default zone to UTC using ZonedDateTime.
LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
ZonedDateTime utc = ZonedDateTime.of(localDateTime, ZoneOffset.UTC);
but utc returns 2015-12-06T14:10:10Z instead of 06-12-2015 09:10:10 AM
How can I convert date from default zone to UTC? The answer given here convert current time to UTC.
You can use ZonedDateTime.ofInstant(Instant, ZoneId) where the second parameter is UTC (the instant knows the local offset). Something like,
String source = "06-12-2015 02:10:10 PM";
String pattern = "MM-dd-yyyy hh:mm:ss a";
DateFormat sdf = new SimpleDateFormat(pattern);
try {
Date date = sdf.parse(source);
ZonedDateTime zdt = ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of("UTC"));
System.out.println(zdt.format(DateTimeFormatter.ofPattern(pattern)));
} catch (ParseException e) {
e.printStackTrace();
}
And I get (corresponding to my local zone offset)
06-12-2015 06:10:10 PM
06-12-2015 02:10:10 PM in Pakistan = 06-12-2015 09:10:10 AM in UTC
There are many ways to do it.
Parse to LocalDateTime ➡️ Combine it with your timezone to get ZonedDateTime ➡️ Convert to Instant ➡️ Convert to ZonedDateTime using Instant#atZone and UTC timezone.
import java.time.Instant;
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) {
String strDateTime = "06-12-2015 02:10:10 PM";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM-dd-uuuu hh:mm:ss a", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
// Using ZoneId.of("Asia/Karachi") for the demo. Change it to
// ZoneId.systemDefault()
Instant instant = ldt.atZone(ZoneId.of("Asia/Karachi")).toInstant();
ZonedDateTime zdtUtc = instant.atZone(ZoneId.of("Etc/UTC"));
System.out.println(zdtUtc.format(dtf)); // 06-12-2015 09:10:10 AM
}
}
Parse to LocalDateTime ➡️ Combine it with your timezone to get ZonedDateTime ➡️ Convert to Instant ➡️ Convert to ZonedDateTime using ZonedDateTime#ofInstant and UTC timezone.
import java.time.Instant;
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) {
String strDateTime = "06-12-2015 02:10:10 PM";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM-dd-uuuu hh:mm:ss a", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
// Using ZoneId.of("Asia/Karachi") for the demo. Change it to
// ZoneId.systemDefault()
Instant instant = ldt.atZone(ZoneId.of("Asia/Karachi")).toInstant();
ZonedDateTime zdtUtc = ZonedDateTime.ofInstant(instant, ZoneId.of("Etc/UTC"));
System.out.println(zdtUtc.format(dtf)); // 06-12-2015 09:10:10 AM
}
}
Using ZonedDateTime#withZoneSameInstant:
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) {
String strDateTime = "06-12-2015 02:10:10 PM";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM-dd-uuuu hh:mm:ss a", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
// Using ZoneId.of("Asia/Karachi") for the demo. Change it to
// ZoneId.systemDefault()
ZonedDateTime zdtPak = ldt.atZone(ZoneId.of("Asia/Karachi"));
ZonedDateTime zdtUtc = zdtPak.withZoneSameInstant(ZoneId.of("Etc/UTC"));
System.out.println(zdtUtc.format(dtf)); // 06-12-2015 09:10:10 AM
}
}
Using DateTimeFormatter#withZone and ZonedDateTime#withZoneSameInstant:
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) {
String strDateTime = "06-12-2015 02:10:10 PM";
// Using ZoneId.of("Asia/Karachi") for the demo. Change it to
// ZoneId.systemDefault()
DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("M-d-u h:m:s a", Locale.ENGLISH)
.withZone(ZoneId.of("Asia/Karachi"));
ZonedDateTime zdtPak = ZonedDateTime.parse(strDateTime, dtfInput);
ZonedDateTime zdtUtc = zdtPak.withZoneSameInstant(ZoneId.of("Etc/UTC"));
DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("MM-dd-uuuu hh:mm:ss a", Locale.ENGLISH);
System.out.println(zdtUtc.format(dtfOutput)); // 06-12-2015 09:10:10 AM
}
}
Learn more about 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.