To convert a Calendar
object to an object of Java 8+ Time API, retaining the field values of the Calendar
object, use:
ZonedDateTime.ofInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId())
To show how this correctly keeps all the field values:
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Yekaterinburg"));
Calendar cal = Calendar.getInstance();
ZonedDateTime zdt = ZonedDateTime.ofInstant(cal.toInstant(), cal.getTimeZone().toZoneId());
System.out.println("java.util.Date: " + new SimpleDateFormat("MMM d, yyyy, h:mm:ss.SSS a XXX").format(cal.getTime()));
System.out.println("ZonedDateTime : " + DateTimeFormatter.ofPattern("MMM d, uuuu, h:mm:ss.SSS a XXX").format(zdt));
System.out.println();
System.out.printf("%-12s%-20s%s%n", "Field" , "Calendar" , "ZonedDateTime");
System.out.printf("%-12s%-20d%d%n", "Year" , cal.get(Calendar.YEAR) , zdt.getYear());
System.out.printf("%-12s%-20d%d%n", "Month" , cal.get(Calendar.MONTH) , zdt.getMonthValue());
System.out.printf("%-12s%-20d%d%n", "Day" , cal.get(Calendar.DAY_OF_MONTH), zdt.getDayOfMonth());
System.out.printf("%-12s%-20d%d%n", "Hour" , cal.get(Calendar.HOUR_OF_DAY) , zdt.getHour());
System.out.printf("%-12s%-20d%d%n", "Minute" , cal.get(Calendar.MINUTE) , zdt.getMinute());
System.out.printf("%-12s%-20d%d%n", "Second" , cal.get(Calendar.SECOND) , zdt.getSecond());
System.out.printf("%-12s%-20d%d%n", "Milli/Nano", cal.get(Calendar.MILLISECOND) , zdt.getNano());
System.out.printf("%-12s%-20s%s%n", "Time Zone" , cal.getTimeZone().getID() , zdt.getZone().getId());
System.out.printf("%-12s%-20s%d%n", " Offset" , cal.getTimeZone().getOffset(cal.getTimeInMillis()), zdt.getOffset().getTotalSeconds());
System.out.println();
System.out.println("Instant (same real time) : " + zdt.toInstant());
System.out.println("Instant (same local time): " + zdt.withZoneSameLocal(ZoneOffset.UTC).toInstant());
Output
java.util.Date: Sep 4, 2020, 4:20:32.475 PM +05:00
ZonedDateTime : Sep 4, 2020, 4:20:32.475 PM +05:00
Field Calendar ZonedDateTime
Year 2020 2020
Month 8 9
Day 4 4
Hour 16 16
Minute 20 20
Second 32 32
Milli/Nano 475 475000000
Time Zone Asia/Yekaterinburg Asia/Yekaterinburg
Offset 18000000 18000
Instant (same real time) : 2020-09-04T11:20:32.475Z
Instant (same local time): 2020-09-04T16:20:32.475Z
Note how the Calendar
month value is 0-based. It's one of the many reasons we don't use it any more.