Reputation: 845
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
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
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
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