1
votes

We have a resource based service which takes a date and a time as parameters to fetch the data from the backend.

The data is stored in the database in UTC format and the server is also configured withe UTC timezone.

When the request is received from the client I want to convert the date and time to UTC format date and time and then query the database accordingly.

In order to do the conversion, I have the below code which converts from a given zoneId to the UTC format.

public ZonedDateTime convertDateBetweenTimeZones(LocalDateTime sourceDateTime,String sourceZone,String targetZone){
     return sourceDateTime.atZone( ZoneId.of(sourceZone)).withZoneSameInstant( ZoneId.of(targetZone));
    }

I invoke the above method as below,

 ZonedDateTime zonedDateTime=convertDateBetweenTimeZones(LocalDateTime.now(),"Asia/Calcutta","UTC");

Once I can get a zonedDateTime object I think I can pass it the database and query it accordingly.

My question is, in my case, I have passed "Asia/Calcutta" as the zoneID of the source timezone. But, the source timezone can be anything, "America/New_York" or even "Asia/Singapore".

So, in that case, I am not sure how I can dynamically get the zoneId from the request received from the client so that I can convert it accordingly.

Can anyone help me on how can I get the zoneId or alternate way to handle my scenario.

Thanks,

JavaUser

2

2 Answers

1
votes

You are doing everything well, but for three things.

Ignore server time zone settings

The server’s time zone setting should be irrelevant to your coding. The server setting can change at any time, so you cannot rely on that.

Always pass the optional time zone object to all the relevant java.time methods, to specify whatever time zone you expect/desire.

You are wisely using the proper IANA 'tz' time zone names in continent/region format such as America/Montreal. Never use the 3-4 letter abbreviations such as EST or IST as they are not true time zones, not standardized, and are not even unique(!).

Database

For database exchange, you will likely need to extract an Instant from the ZonedDateTime via toInstant method. Most any serious database stores the date-time in UTC. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.

A JDBC driver complying with JDBC 4.2 or later can likely use Instant directly via ResultSet::getObject and PrepatedStatement::setObject. If not, fall back to converting briefly to the java.sql types such as java.sql.Timestamp.

Study carefully your database’s behavior with date-time handling; various databases vary widely on this(!). The SQL spec says little on the topic of date-time handling past vaguely defying a few days types. Some like Postgres have excellent date-time support while others have poor support, and all vary in behavior.

Browser time zone

As for determining the time zone from a web browser, that is not simple. Search Stack Overflow for more info with many Questions and Answers already posted.

Ultimately, the only sure way is to ask the user. Include a time zone field when you collect data from the user.

0
votes

One solution is you can use an alias map to keep non standard time zone ids and pass into ZoneId.of(id, alias) method. Example:

HashMap<String, String> aliasMap = new HashMap<>();
aliasMap.put("FOO", "America/New_York");
ZoneId zoneId = ZoneId.of("FOO", aliasMap);