0

I have to use the date time which I receive by user, and convert that time to UTC from the given time. Right now, all the solutions are working, but not as I needed. First, it converts to the time zone, but I don't want to initially convert. I have to set that timezone on my date and then convert that time to UTC. Right now, each and every solution shows that I have to pass date and time, and then I am getting updated date and time with the time zone which I provide, and then converts to the UTC. This was not my question.

My user will send me date time of any timezone, and my server will be running on UTC time zone. I will get the zone id from the front end. I want to convert that date time to UTC and verify with my other conditions. It might be possible that I will get UTC-7 time in one request, and then after in next request I will get UTC+5:30. So, all the time should be converted to the UTC and I am not able to set timezone on date.

I wanted to set the specific timezone to date, and I am getting the date and time of that timezone, but I'm not able to set the exact timezone. Here, I am adding my code please tell me where I am wrong:

Calendar laCalendar = Calendar.getInstance();
laCalendar.set(2020, 8, 14, 00, 00);
Date losAngelesDate = laCalendar.getTime();
System.out.println("LA Date1===>" + losAngelesDate);

SimpleDateFormat simpleTimeFormatForUSA = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
simpleTimeFormatForUSA.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
String americaDateString = simpleTimeFormatForUSA.format(laCalendar.getTime());
SimpleDateFormat dateFormatUSA = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
losAngelesDate = dateFormatUSA.parse(americaDateString);

System.out.println("LA Date2===>" + losAngelesDate);
Date utcDate = losAngelesDate;
Calendar calendar = Calendar.getInstance();
calendar.setTime(utcDate);
TimeZone timeZone = TimeZone.getTimeZone("UTC");
SimpleDateFormat simpleTimeFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
simpleTimeFormat.setTimeZone(timeZone);
String utcTime = simpleTimeFormat.format(calendar.getTime());
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
utcDate = dateFormat.parse(utcTime);
System.out.println("UTC date====>" + utcDate);

And my output is

LA Date1===>Mon Sep 14 00:00:56 UTC 2020
LA Date2===>Sun Sep 13 17:00:00 UTC 2020
UTC date====>Sun Sep 13 17:00:00 UTC 2020

Here you can see that my DateTime is converted, but time zone is still UTC and I wanted to update that.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
T.Thakkar
  • 203
  • 2
  • 9
  • 1
    If you can, better use the classes from the java.time package. Date and Calendar are not straightforward to use, especially when dealing with time zones – Guillaume Sep 14 '20 at 16:47
  • @Guillaume will you please provide a code snippet? – T.Thakkar Sep 14 '20 at 16:49
  • 2
    Essentially java.util.Date does not have a time zone, it is a point in time since epoch. On the other hand the java.time has classes to represent time, with or without a time zone and methods to convert back and forth – Guillaume Sep 14 '20 at 16:52
  • I recommend you neither use `Calendar`, `Date`, `TimeZone` nor `SimpleDateFormat`. Those classes are poorly designed and long outdated, the last in particular notoriously troublesome. For date and time with a time zone you need `ZonedDateTime` from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Sep 14 '20 at 17:22
  • Under the linked original question I recommend [the answer by Basil Bourque](https://stackoverflow.com/a/60583558/5772882) using java.time. – Ole V.V. Sep 14 '20 at 17:24
  • Code snippet? Any time. `ZonedDateTime.of(2020, 9, 14, 0, 0, 0, 0, ZoneId.of("America/Los_Angeles"))` yields `2020-09-14T00:00-07:00[America/Los_Angeles]`. – Ole V.V. Sep 14 '20 at 17:32
  • How is the client sending the date-time? As numbers (like 2020, 8, 14, 0, 0)? As a string, and if so, in what format? Conversion to UTC is easy using java.time, and there are many questions and answers dealing with it already. Use your search engine. You may want to include `java-8` in your search since java.time was introduced in Java 8 and many questions refer to it as a Java 8 thing (it’s been backported to Java 6 and 7 as well). – Ole V.V. Sep 14 '20 at 17:49
  • I have set this 0,0 as an example I will get time in this format 2020-09-14T19:45:00.000+05:30 – T.Thakkar Sep 14 '20 at 17:57
  • Problem is with this sentence of your question: `My user will send me date time of any timezone..`. You can convert a date time of a zone to another zone but not **any** zone to other. In other words, if you know the time zone in which user would send then the API can help convert it to UTC. – Ritesh Sep 14 '20 at 19:18
  • 1
    That’s easy. `OffsetDateTime.parse("2020-09-14T19:45:00.000+05:30").withOffsetSameInstant(ZoneOffset.UTC)` yields `2020-09-14T14:15Z`. The trailing `Z` denotes UTC. – Ole V.V. Sep 14 '20 at 19:33

2 Answers2

2

Here, is how I would write it using Java 8 Date/Time APIs.

    public static void main(String[] args)
    {
        System.out.println("UTC");
        toTimeZone(new Date(), TimeZone.getTimeZone(ZoneId.of("UTC")));
        
        System.out.println("America/Los_Angeles");
        toTimeZone(new Date(), TimeZone.getTimeZone(ZoneId.of("America/Los_Angeles")));
    }

    public static void toTimeZone(Date date, TimeZone timeZone)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        Instant epochMillisInstant = Instant.ofEpochMilli(calendar.getTimeInMillis());
        LocalDateTime localDateTime = LocalDateTime.ofInstant(epochMillisInstant, ZoneId.systemDefault());
        ZonedDateTime dateTimeToConvert = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
        ZonedDateTime dateTimeWithTimeZone = dateTimeToConvert.withZoneSameInstant(timeZone.toZoneId());
        String formattedDateForNewTimeZone = dateTimeWithTimeZone.format(DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a"));
        System.out.println(formattedDateForNewTimeZone);
    }

Using Just Java 8 Date/Time APIs - Shorter Version

public static void main(String[] args) {
        System.out.println("UTC");
        toTimeZone(LocalDateTime.now(),"UTC");
        System.out.println("America/Los_Angeles");
        toTimeZone(LocalDateTime.now(),"America/Los_Angeles");
    }

    private static void toTimeZone(LocalDateTime localDateTime, String timeZone) {
        ZonedDateTime localDateTimeToConvert = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
        ZonedDateTime zonedDateTime = localDateTimeToConvert.withZoneSameInstant(ZoneId.of(timeZone));
        String formattedDateForNewTimeZone = zonedDateTime.format(DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a"));
        System.out.println(formattedDateForNewTimeZone);
    }
Sanket Parikh
  • 469
  • 3
  • 5
  • Thanks for demonstrating the use of java.time. the modern Java date and time API. Why not go all in and skip all of `Date`, `TimeZone` and `Calendar` completely? – Ole V.V. Sep 14 '20 at 17:26
  • Right, that is a good point! I just updated the shorter version removing Date, TimeZone and Calendar completely. – Sanket Parikh Sep 14 '20 at 17:43
0

Before you convert the Calendar to a Date, set the Timezone to your preference.

For example:

import java.util.Calendar;
import java.util.TimeZone;

public class Timezone{

    public static void main(String []args){
       Calendar laCalendar = Calendar.getInstance();
       TimeZone timezone = TimeZone.getTimeZone("UTC");
       laCalendar.set(2020, 8, 14, 00, 00);
       laCalendar.setTimeZone(timezone);
       java.util.Date losAngelesDate = laCalendar.getTime();
       System.out.println(losAngelesDate.toString());
    }
}
Spectric
  • 30,714
  • 6
  • 20
  • 43