简体   繁体   中英

Different time conversion by using java.util.Date in Java

I am using the below code for epoch to time conversion by using java.util.Date class in Java.

Long scheduledTime = 1602258300000L;
Date date = new Date(scheduledTime);
System.out.println("Date obj :" + date);

Below are the outputs while running the same code on two different timezone server:

On EDT server-

Date obj :Fri Oct 09 11:45:00 EDT 2020

On IST server -

Date obj :Fri Oct 09 21:15:00 IST 2020

Why does this happen? I am only passing milliseconds. This data is supposed to be treated as 21:15 on all servers. Why does Date class change the data?

Please share a sample piece of code for getting the same time data regardless of the timezone of the server.

A Date object represents a specific instant in time, represented by a given number of milliseconds since the Unix epoch.

The toString() method converts that instant in time into a local time based on the default time zone. It's not that the Date value itself "has" a time zone - it's just toString() that uses the default one.

This data is supposed to be treated as 21:15 on all servers.

That suggests you want to use the Indian time zone in all servers, at least when converting the instant in time for display. Without knowing anything more about your application, that's all we can say... other than "don't use java.util.Date or java.util.Calendar ; use the java.time classes instead". They're much better designed, and you're less likely to run into problems like this.

java.time

I recommend you use java.time, the modern Java date and time API, for your date and time work.

    long scheduledTime = 1_602_258_300_000L;
    Instant pointInTime = Instant.ofEpochMilli(scheduledTime);
    System.out.println(pointInTime);

Output from this snippet will be the same on all servers in all time zones:

2020-10-09T15:45:00Z

Since you want 21:15, specify the time zone for India:

    ZoneId serverTimeZone = ZoneId.of("Asia/Kolkata");
    ZonedDateTime dateTime = pointInTime.atZone(serverTimeZone);
    System.out.println(dateTime);

2020-10-09T21:15+05:30[Asia/Kolkata]

What went wrong?

The epoch is one point in time independent of time zone. so a count of milliseconds also denotes one point in time. In your case that point in time is Friday 9. October 2020 15:45:00 UTC. And at that point in time it was 21:15 in India and 11:45 on the East coast of North America. It's a confusing trait of the outdated Date class that on one hand it represents just a point in time, on the other hand its toString method grabs the time zone setting of the JVM and uses it for rendering the string to be returned, thus giving you the false impression that you get different Date objects in different time zones when in fact they are equal.

Links

As pointed by others you should now use the java.time package for working with time. If you look at the documentation of the toString() method of java.util.Date , it says that it coverts the Date object to a String of form:

EEE MMM dm dd hh:mm:ss zzz yyyy

It is like the following code is running in the background:

public String toString(){
    Date date=this;
    SimpleDateFormat simpleDateFormat=new SimpleDateFormat(
             "EEE MMM d m dd hh:mm:ss zzz yyyy");
    simpleDateFormat.setTimeZone(TimeZone.getDefault());  //This line is important.
    return simpleDateFormat.format(date);
}

Now, if you wanna format your Date object for a certain timezone you can do the same including setting the timezone:

Long scheduledTime = 1602258300000L;
Date date = new Date(scheduledTime);
SimpleDateFormat simpleDateFormat=new SimpleDateFormat(
             "EEE MMM d m dd hh:mm:ss zzz yyyy");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("IST")); 
String dateStr = simpleDateFormat.format(date);
System.out.println("Date obj :" + dateStr);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM