Since your date-time string has timezone offset information. So, you can parse it to an OffsetDateTime
object and then get the year from it.
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
public class Main {
public static void main(String[] args) {
String strDateTime = "2015-10-10T14:34:22Z";
OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
System.out.println(odt);
System.out.println(odt.getYear());
// If you want to get LocalDateTime from OffsetDateTime
LocalDateTime ldt = odt.toLocalDateTime();
System.out.println(ldt);
}
}
Output:
2015-10-10T14:34:22Z
2015
2015-10-10T14:34:22
Note that Z
in the date-time string stands for Zulu
date-time and specifies a timezone offset of +00:00
hours or date-time at UTC
.
Taking the getYear() from Date has the 1900 issue.
The date-time API of java.util
and their formatting API, SimpleDateFormat
are outdated and error-prone. I suggest you should stop using them completely and switch to the modern date-time API. Learn more about the modern date-time API at Trail: Date Time.
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.
Converting from legacy API to the modern API:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Date;
public class Main {
public static void main(String[] args) throws ParseException {
String strDateTime = "2015-10-10T14:34:22Z";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
Date date = sdf.parse(strDateTime);
Instant instant = date.toInstant();
OffsetDateTime odt = instant.atOffset(ZoneOffset.UTC);
System.out.println(odt);
System.out.println(odt.getYear());
// If you want to get LocalDateTime from OffsetDateTime
LocalDateTime ldt = odt.toLocalDateTime();
System.out.println(ldt);
}
}
Output:
2015-10-10T14:34:22Z
2015
2015-10-10T14:34:22
Note: If you want to convert the Instant
into ZonedDateTime
at UTC
, you can do it as follows:
ZonedDateTime zdt = instant.atZone(ZoneOffset.UTC);
or the following:
ZonedDateTime zdt = instant.atZone(ZoneId.of("Etc/UTC"));
Note that the three-letter name for a ZoneId
is error-prone i.e. avoid using something like ZoneId.of("UTC")
.
What is wrong with your code:
You are using .atZone(ZoneId.systemDefault())
which is converting the object of Instant
to an object of ZonedDateTime
with your JVM's timezone. You have to use .atOffset(ZoneOffset.UTC)
as shown above to keep the date-time with the same timezone offset (i.e. +00:00
hours or date-time at UTC
) which is there in the date-time string.