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).
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.
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:
Convert from your time zone to UTCUTC date and time: 2019-09-10T12:00Z
Date and time in the default time zone: 2019-09-10T15:00+03:00[Asia/Istanbul]
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
How to Pass JavaScript Values to Scriptlet in Jsp
How to Make a Multipart/Form-Data Post Request Using Java
How to Check If a Json Key Exists
Replace Whitespace in Json Keys
Tomcat Server Error - Port 8080 Already in Use
Mapstruct: Map List of Objects, When Object Is Mapped from Two Objects
Lombok Is Not Generating Getter and Setter
How to Format a String Number to Have Commas and Round
Launch New Activity from Fragment in Android Studio
Chrome Browser Is Not Opening in Selenium Webdriver
How to Join Results of Multiple Tables in Spring JPA Repository
How to Close a Javafx Application on Window Close
Arraylist: How Does the Size Increase
Jackson Jsonmappingexception: Can Not Deserialize Instance
How to Skip @Postconstruct When Unit Testing
What Is the Most Elegant Way to Check If All Values in a Boolean Array Are True
Netbeans Tomcat Build Failed - the Module Has Not Been Deployed