Z
is not the same as z
.
DateTimeFormatter
evaluates the former as zone-offset while the later as time-zone name.
Another example can be M
which it uses for month-of-year, and m
which it uses for minute-of-hour.
The symbol for the components of date, time, timezone etc. are case-sensitive. Check DateTimeFormatter
to learn more about these symbols.
A quick demo:
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
ZonedDateTime odt = ZonedDateTime.now(ZoneId.of("Asia/Calcutta"));
System.out.println(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssZ").format(odt));
System.out.println(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssz").format(odt));
}
}
Output:
2020-12-22T00:14:44+0530
2020-12-22T00:14:44IST
A zone offset is not the same as timezone. A timezone has an ID in the form, Continent/City
e.g. Asia/Calcutta
whereas a zone offset is represented in hours and minutes which tells how many hours and minutes the date & time of a place is offset from UTC
date & time. Thus, many timezone IDs can have the same zone offset. In other words, a zone offset can be derived from the timezone ID but the converse is not possible e.g. in the following demo, OffsetDateTime
will be able to determine the zone offset from the timezone ID of Asia/Calcutta
but trying to get the timezone name (as in the above example) using z
will fail.
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
OffsetDateTime odt = OffsetDateTime.now(ZoneId.of("Asia/Calcutta"));
System.out.println(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssZ").format(odt));
System.out.println(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssz").format(odt));
}
}
Output:
2020-12-22T00:30:40+0530
Exception in thread "main" java.time.DateTimeException: Unable to extract ZoneId from temporal 2020-12-22T00:30:40.865087+05:30
at java.base/java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:289)
at java.base/java.time.format.DateTimeFormatterBuilder$ZoneTextPrinterParser.format(DateTimeFormatterBuilder.java:4072)
at java.base/java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2341)
at java.base/java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1843)
at java.base/java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1817)
at Main.main(Main.java:9)
And I used "OffsetDateTime.parse()" (in java) to parse this format. I
was able to parse date time by passing "t" (instead of "T") and "z"
(instead of "Z") here.
I have already explained about Z
and z
. Let's focus on T
and t
. If you observe carefully, you will find that I've used single quotes around T
i.e. 'T'
which makes it a string literal to be used inside the date-time string. It means that it can be anything e.g. 't'
or 'Foo'
or 'Bar'
. As long as the literals in the DateTimeFormatter
matches in the same case with that in the date-time string, it works without any problem. I've shown it in the following demo:
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String strDateTime = "2020-12-22T00:45:50+05:30";
// The given string is already in the format which is use by OffsetDateTime for
// parsing without a DateTimeFormatter
OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
// Let's try to parse it using different types of DateTimeFormatter instances
System.out.println(OffsetDateTime.parse(strDateTime, DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssXXX")));
//The following line will fail as the literal does not match case-wise
//System.out.println(OffsetDateTime.parse(strDateTime, DateTimeFormatter.ofPattern("uuuu-MM-dd't'HH:mm:ssXXX")));
strDateTime = "2020-12-22t00:45:50+05:30";// Now, DateTimeFormatter with 't' will work successfully
System.out.println(OffsetDateTime.parse(strDateTime, DateTimeFormatter.ofPattern("uuuu-MM-dd't'HH:mm:ssXXX")));
}
}
Output:
2020-12-22T00:45:50+05:30
2020-12-22T00:45:50+05:30
Learn more about the modern date-time API from Trail: Date Time.