简体   繁体   中英

Not able to convert UTC to local time

I am writing a Java Code.I am able to convert the local time to UTC.But I am facing the problem when I want to convert it back to local time.The steps I am doing-

  1. Getting milliseconds of the present.(DONE)
  2. Converting present milliseconds(millisSinceEpoch) to present local time.(DONE)
  3. Converting present milliseconds(millisSinceEpoch) to UTC time.(DONE)
  4. Converting UTC time to UTC milliseconds.(DONE)
  5. Convert UTC milliseconds to UTC Time.(DONE)
  6. Convert UTC milliseconds to local time(IST)(Facing the problem here.....Getting the same UTC time here.Why is it not converting to Local time?).There is an answer where multiple date objects are created,But here I am not creating multiple date Objects and working only on milliseconds.My Code-

     import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Instant; import java.time.ZonedDateTime; import java.util.Date; import java.util.TimeZone; public class TimeApiClass { public static void main(String args[]) throws ParseException { ZonedDateTime currentZone = ZonedDateTime.now(); //Getting milliseconds of the present Instant instant=currentZone.toInstant(); long millisSinceEpoch=instant.toEpochMilli(); System.out.println("Not Converted to UTC-(Milliseconds-in local)"); System.out.println(millisSinceEpoch); //Output1->1579788244731 //Converting present milliseconds(millisSinceEpoch) to present local time SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS "); String str3=sdf3.format(new Date(millisSinceEpoch)); System.out.println("Local Time-Not Converted to UTC-(Present local time)"); System.out.println(str3); //2020/01/23 19:34:04.731 //Converting present milliseconds(millisSinceEpoch) to UTC time SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS "); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); String str=sdf.format(new Date(millisSinceEpoch)); System.out.println("UTC time-Local time Converted to UTC(unrequired time format)-"); System.out.println(str);// str contains 2020/01/22 13:22:55 UTC //Output3 ->2020/01/23 14:04:04.731 System.out.println("-----------------------------------------------------------------------------------------"); //Converting UTC time to UTC milliseconds String myDate = str; // myDate and str contains 2020/01/22 10:08:42 SimpleDateFormat sdff = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS "); Date date = sdff.parse(myDate); long millis = date.getTime(); System.out.println("Converted to milliseconds(Now its in required format in UTC milliseconds)"); System.out.println(millis); //Output4 ->1579749867000 //Convert UTC milliseconds to UTC Time DateFormat simple = new SimpleDateFormat(" yyyy/MM/dd HH:mm:ss.SSS"); Date result=new Date(millis); System.out.println("Converting UTC milliseconds back to date/time format-"); System.out.println(simple.format(result)); //Convert UTC milliseconds to local time(IST) Date dateee=new Date(millis); //Facing the problem here.....Getting the same UTC time here.Why is it not converting to Local time? DateFormat format=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS"); format.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata")); System.out.println("lllllllllllllllllllllllll"); System.out.println(format.format(dateee)); //Converting UTC time to IST time SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS "); sdf2.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata")); String istTime=sdf2.format(new Date(millis)); System.out.println("Now converting UTC millis to IST format->"); System.out.println(istTime); //Output5 ->2020/01/23 08:54:27 IST //Converting IST time to milliseconds,here I am facing the problem.My output has to give the local milliseconds as I am passing ISTtime here,but its giving me UTC milliseconds,Which I dont want. Date date66=sdf2.parse(istTime); long finalMillis=date66.getTime(); System.out.println("Now converting IST to IST milliseconds:"); System.out.println(finalMillis); //Output6 ->1579749867000

    } } //1579613838087

tl;dr

Convert a ZonedDateTime into a different time zone by ZonedDateTime.withZoneSameInstant(ZoneId)


You are not well advised to use java.util.SimpleDateFormat for operations on dates and times and your code shows partial use of java.time , which means you can just switch to java.time entirely. For formatting, use a java.time.format.DateTimeFormatter .

See this example:

public static void main(String[] args) {
    // get the current instant
    Instant instant = Instant.now();
    // and convert it to a datetime object representing date and time in UTC
    ZonedDateTime ofInstant = ZonedDateTime.ofInstant(instant, ZoneId.of("UTC"));
    // print it
    System.out.println("Now from Instant in UTC:\t"
            + ofInstant.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));

    // you can have a shorter way: current moment in your system's time zone
    ZonedDateTime nowHere = ZonedDateTime.now();
    // or in UTC
    ZonedDateTime utcNow = ZonedDateTime.now(ZoneId.of("UTC"));

    // print them both
    System.out.println("Now in my (system's) time zone:\t"
            + nowHere.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
    System.out.println("Now in UTC:\t\t\t"
            + utcNow.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));

    // then format the UTC datetime back to the one your system has
    ZonedDateTime backFromUtc = utcNow.withZoneSameInstant(ZoneId.systemDefault());
    // and print that one, too
    System.out.println("Back from UTC:\t\t\t"
            + backFromUtc.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
}

The output something like:

Now from Instant in UTC:        2020-01-23T15:44:11.921Z[UTC]
Now in my (system's) time zone: 2020-01-23T16:44:12.091+01:00[Europe/Berlin]
Now in UTC:                     2020-01-23T15:44:12.091Z[UTC]
Back from UTC:                  2020-01-23T16:50:52.194+01:00[Europe/Berlin]

Why is it not converting to Local time?

Where it goes wrong for you: The string myDate is in UTC, but (1) there is no indication of UTC in the string, and (2) you are parsing it using the formatter sdff , but this formatter is not using UTC (it is using your default time zone, India Standard Time). Therefore you are getting a wrong result from parsing.

There may be another misunderstanding: The epoch is one specific point in time regardless of time zone. Therefore milliseconds since the epoch are the same in all time zones. So the first sign of a problem is probably when your program is printing two different millisecond values. If the millisecond values were supposed to denote the same point in time, you should see the same value both times.

All of this said, deHaar is correct in the other answer that you should stay away from all of DateFormat , SimpleDateFormat , Date and TimeZone . All of those classes are poorly designed and long outdated. I think that your use of the mentioned classes have contributed quite much to making your code more complicated than it had needed to be.

Edit:

So you are telling me to not use DateFormat,SimpleDateFormat and TimeZone.So can you please suggest as to which class I should be ideally using?

You are already on the good track when using Instant and ZonedDateTime from java.time, the modern Java date and time API. This API offers all the functionality you need and is so much nicer to work with, so I suggest that you stick to it. Other java.time classes that you will probably find useful include ZoneId (instead of TimeZone ) and DateTimeFormatter (instead of SimpleDateFormat and DateFormat ). For more see the tutorial and/or the documentation. I will add links at the bottom later.

To parse a UTC string into milliseconds since the epoch:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu/MM/dd HH:mm:ss.SSS");
    String utcString = "2020/01/22 13:22:55.731";
    long millisSinceEpoch = LocalDateTime.parse(utcString, formatter)
            .atOffset(ZoneOffset.UTC)
            .toInstant()
            .toEpochMilli();
    System.out.println(millisSinceEpoch);

1579699375731

Or if your real goal was to convert it to local time in India:

    ZoneId indiaStandardTime = ZoneId.of("Asia/Kolkata");
    ZonedDateTime timeInIndia = LocalDateTime.parse(utcString, formatter)
            .atOffset(ZoneOffset.UTC)
            .atZoneSameInstant(indiaStandardTime);
    System.out.println(timeInIndia);

2020-01-22T18:52:55.731+05:30[Asia/Kolkata]

I am first telling Java to interpret the string in UTC, next to convert it to IST.

Links

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