kavita
kavita

Reputation: 845

Converting time to UTC using java 8

I have some APIs in Java which accept times as strings.

The UI sends plain string like "10:00:00". I am creating a LocalTime out of that and saving in the db (MySQL).

Later in another API I use a LocalDate object and the above time with Zone UTC to create a ZonedDateTime object that is saved to the db. My problem is that the time is not getting converted to UTC.

ZonedDateTime.of(LocalDate.now(ZoneId.of("UTC")),LocalTime.now(ZoneId.of("UTC")), ZoneId.of("UTC"));
ZonedDateTime.of(LocalDate.now(ZoneId.of("UTC")),dto.getStart(), ZoneId.of("UTC"));

Both of these are different though I am sending for eg 07:00:00 which is my time in India. Please guide me as to how I should convert the time alone to UTC.

EDIT:: I have set jvm Duser.Timezone to UTC.When I do this:

ZonedDateTime.of(LocalDate.now(ZoneId.of("UTC")),dto.getStart(), ZoneId.of("UTC")).getOffset().getTotalSeconds();

It gives 0 as seconds

EDIT::

ZoneId z = ZoneId.of("Asia/Calcutta");
ZoneId z1 = ZoneId.of("UTC");
TimeZone.getTimeZone(z).getRawOffset();

Tried this and it gives the diff in ms. I will try using this provided the UI sends the actual local zone. Will update..

Upvotes: 1

Views: 11063

Answers (3)

kavita
kavita

Reputation: 845

For now We have decided to allow the UI to change the time to whatever is its timezone. JVM timezone for the server is set to UTC...

Upvotes: 1

java-timer
java-timer

Reputation: 23

If the input corresponds to your local time, you can create a ZonedDateTime to get the current date in India timezone, set the time and then convert it to UTC:

LocalTime time = LocalTime.parse("10:00:00"); // 10 AM

ZonedDateTime utc = ZonedDateTime
    .now(ZoneId.of("Asia/Calcutta")) // current date/time in India
    .with(time) // set time to 10 AM
    .withZoneSameInstant(ZoneOffset.UTC); // convert to UTC

The value of variable utc will be 2018-01-29T04:30Z (running the code today, January 29th). The time in UTC is 4:30 AM, which is equivalent to 10 AM in India.

I believe that MySQL can't save a ZonedDateTime, so you can first convert it to an Instant by calling utc.toInstant(). Or if the driver you use is an older version and it works only with java.util.Date, you can convert it using Date.from(utc.toInstant()).

Also note that I used the constant ZoneOffset.UTC, which is equivalent to (but better than, IMO) calling ZoneId.of("UTC").

Upvotes: 2

Ben Thurley
Ben Thurley

Reputation: 7141

I would advise against storing a ZonedDateTime in a MySQL database. MySQL timestamps don't store the timezone information so you can't guarantee you'll get back the same time that you save.

Instead I would store a LocalDateTime and standardise on UTC for internal times and then format with a timezone when you need to display etc. To get the current time in UTC you can do something like this.

LocalDateTime now = LocalDateTime.now(Clock.systemUTC());

To build a UTC timestamp for today and a provided time you could do something like this.

LocalTime time = getTime();
LocalDateTime = LocalDateTime.of(LocalDate.now(Clock.systemUTC()), time);

To build a timestamp using the date for the current timezone, a provided time and then convert to UTC for saving to the database.

ZoneId timezone = ZoneId.of("Asia/Calcutta");
LocalTime time = getTime();
ZonedDateTime zdt = ZonedDateTime.of(LocalDate.now(timezone), time, timezone);
LocalDateTime utcDateTime = LocalDateTime.ofInstant(zdt.toInstant(), ZoneOffset.UTC);

Upvotes: 0

Related Questions