Convert Localdatetime to Localdatetime in Utc

How to convert LocalDateTime to UTC and back, without loading zones?

This is probably happening because your JVM's default timezone is in Daylight Saving Time (DST).

To get the correct offset, you should check if the timezone is in DST and add this to the offset:

Calendar cal = Calendar.getInstance();

TimeZone zone = TimeZone.getDefault();
// if in DST, add the offset, otherwise add zero
int dst = zone.inDaylightTime(cal.getTime()) ? zone.getDSTSavings() : 0;
int offset = (zone.getRawOffset() + dst) / 1000;
LocalDateTime alternativeNowInUtc = now.atZone(ZoneOffset.ofTotalSeconds(offset))
.withZoneSameInstant(ZoneId.ofOffset("UTC", ZoneOffset.ofHours(0)))
.toLocalDateTime();

Another way to create the nowInUtc as a LocalDateTime is to create an Instant from the Calendar:

LocalDateTime nowInUtc = Instant.ofEpochMilli(cal.getTimeInMillis())
.atOffset(ZoneOffset.ofHours(0)).toLocalDateTime();

Actually, you don't need the Calendar at all, just use Instant.now() to get the current instant:

LocalDateTime nowInUtc = Instant.now().atOffset(ZoneOffset.ofHours(0)).toLocalDateTime();

Or, even shorter, use an OffsetDateTime directly:

LocalDateTime nowInUtc = OffsetDateTime.now(ZoneOffset.ofHours(0)).toLocalDateTime();

Not sure if any of those loads timezone data, it's up to you to test.

And I think that the constant ZoneOffset.UTC can be used instead of ZoneOffset.ofHours(0), because it won't load tz data as well (but I haven't tested it).

Final solution

Assuming the default timezone is in Israel (TimeZone.getDefault() is Asia/Jerusalem):

// April 11th 2018, 3 PM (current date/time in Israel)
LocalDateTime now = LocalDateTime.of(2018, 4, 11, 15, 0, 0);

TimeZone zone = TimeZone.getDefault();
// translate DayOfWeek values to Calendar's
int dayOfWeek;
switch (now.getDayOfWeek().getValue()) {
case 7:
dayOfWeek = 1;
break;
default:
dayOfWeek = now.getDayOfWeek().getValue() + 1;
}
// get the offset used in the timezone, at the specified date
int offset = zone.getOffset(1, now.getYear(), now.getMonthValue() - 1,
now.getDayOfMonth(), dayOfWeek, now.getNano() / 1000000);
ZoneOffset tzOffset = ZoneOffset.ofTotalSeconds(offset / 1000);

// convert to UTC
LocalDateTime nowInUtc = now
// conver to timezone's offset
.atOffset(tzOffset)
// convert to UTC
.withOffsetSameInstant(ZoneOffset.UTC)
// get LocalDateTime
.toLocalDateTime();

// convert back to timezone
LocalDateTime localTime = nowInUtc
// first convert to UTC
.atOffset(ZoneOffset.UTC)
// then convert to your timezone's offset
.withOffsetSameInstant(tzOffset)
// then convert to LocalDateTime
.toLocalDateTime();

How to convert UTC Time to LocalDateTime by using ZonedDateTime

Don’t use LocalDateTime for a date and time for which you know the UTC offset or time zone. For a date and time in your time zone or another known time zone, use ZonedDateTime. For a date and time for which you know an offset (and here UTC counts as an offset) use OFfsetDateTime.

Why? LocalDateTime (confusing class name) is a date and time without time zone or offset. Not storing the known offset or time zone is throwing away vital data and is an error waiting to happen.

One exception: For a date and time in a known time zone in a further future, do store a LocalDateTime and make sure to store the time zone as a separate ZoneId object. This will allow the offset and/or summer time rules (DST rules) for the time zone to be changed between now and that time (which happens more often than we like to think). Only when time draws near and our Java installation may have been updated with the latest zone rules, can we correctly combine the date-time and the zone and obtain the correct moment in time.

Convert UTC date and time to your time zone
    OffsetDateTime utcDateTime = OffsetDateTime.of(2019, 9, 10, 12, 0, 0, 0, ZoneOffset.UTC);
System.out.println("UTC date and time: " + utcDateTime);
ZonedDateTime myDateTime = utcDateTime.atZoneSameInstant(ZoneId.systemDefault());
System.out.println("Date and time in the default time zone: " + myDateTime);

After I set my time zone to Asia/Istanbul, this snippet output:

UTC date and time: 2019-09-10T12:00Z
Date and time in the default time zone: 2019-09-10T15:00+03:00[Asia/Istanbul]
Convert from your time zone to UTC

For the opposite conversion I prefer:

    OffsetDateTime convertedBackToUtc = myDateTime.toOffsetDateTime()
.withOffsetSameInstant(ZoneOffset.UTC);
System.out.println("UTC date and time again: " + convertedBackToUtc);
UTC date and time again: 2019-09-10T12:00Z

Still not using any LocalDateTime.

Convert LocalDateTime to LocalDateTime with specific Zone in Java

You need to convert it first to ZonedDateTime, change the timezone, and then extract LocalDateTime from that:

ZoneId from = ...;
ZoneId to = ...;
LocalDateTime input = ...;
LocalDateTime output = input.atZone(from).withZoneSameInstant(to).toLocalDateTime();

converting local date/time to UTC date/time java SE 8

Your approach works, but there is a cleaner method, see: https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html#withZoneSameInstant-java.time.ZoneId-

Something like this should work:

localDateTime.withZoneSameInstant(ZoneId.of("UTC"));

Convert LocalDateTime UTC to Europe/Rome gave me wrong result

I'm expecting the "converted time" to be 17:00 but I'm having this result.

I'm not sure why you're expecting that. 16:00 is the correct answer.

Perhaps you missed that this is in januari, when mainland europe is on winter time which is just 1 hour ahead of UTC.

15:00:00 UTC time on jan 1st means it's +1 hour in Rome. There's no way to get 17:00:00 here. Try this with a summer date, perhaps. That'll get you a 2 hour difference.

There's nothing wrong your code. That is exactly how to do it, which is why it gives you 16:00:00 (as that is the right answer).



Related Topics



Leave a reply



Submit