0

I am dealing with MySQL and Java and have a timezone handling challenge.

The issue: Database server is in Central US. User 1 is in Mexico. User 2 is in Singapore.

User 1 enters date and time as per UK Time Zone to provide information about a Flight taking off from London.

User 2 should be able to see the filed in any of below 3 options

  1. Date and Time as entered by User 1 in UK time zone
  2. Date and Time as per User's timezone
  3. Date and Time as per UTC

How should the database be structured? Should we store both the user provided date and time in one column and timezone in another or can we store the date and time and timezone in one column?

  • See similar questions [here](http://stackoverflow.com/q/33343893/642706) and [here](http://stackoverflow.com/q/2532729/642706). – Basil Bourque Apr 18 '16 at 23:27

2 Answers2

1

Strive for storing time information always in UTC convention. It is the only one that corresponds 1:1 with "moments in time" as they "happened" in reality.

All the rest is an issue of presentation/rendering.

Do this even when you think you don't have a timezones issue. The issue can still raise its head later on in the lifecycle of the DB.

Erwin Smout
  • 17,245
  • 4
  • 28
  • 49
  • Would you suggest to use 2 fields for time and timezone or only one? – user3160980 May 24 '14 at 07:12
  • 1
    Eurhm, the answer to that is in the answer. Do you know what UTC really is ? – Erwin Smout May 26 '14 at 06:31
  • Hi Erwin, I understand what UTC is. My problem is to capture flight timings. If a person in UK has to enter Departure and Arrival time of a flight from US to Singapore, I cannot expect the user to convert to a local time zone and enter. Similarly if a person in Singapore has to see timings the departure time should be as in US time but not Singapore time. I will go ahead with time saved as UTC but also timezone if different from user profile. – user3160980 Jun 08 '14 at 18:03
0

The Answer by Erwin Smout is correct.

Here is example code for all three of your cases, and some discussion.

Database type TIMESTAMP WITH TIME ZONE

Your database table column should be defined as the SQL standard type TIMESTAMP WITH TIME ZONE (not WITHOUT). Or something analogous depending on your database. Support for date-time varies widely between some that are weak (SQLite) to the robust (Postgres).

Virtually all databases actually store the date-time values in UTC (if they respect time zones at all). Some retain the time zone information passed with input values while some such as Postgres discard that information after using it to adjust the value to UTC.

Think, work, and store in UTC

Your business logic and data storage should be in UTC. So there is only one actual flight time, in UTC. For the various Mexico, Singapore, and UK representations we apply various time zones for going to/from the UTC value.

Server Irrelevant

The location of the server in central US should be irrelevant. First, servers should almost always be set to UTC (or Iceland) for their time zone. Secondly, you should never depend on that setting, as it is an externality outside your control and is too terribly easy to be changed -- even during runtime! Instead, always specify your desired/expected time zone as arguments in your code.

java.time

Always use java.time classes, never the java.util.Date/.Calendar/java.text.SimpleDateFormat classes.

java.sql

Retrieve the flight time from the database as a java.sql.Timestamp which is in UTC by definition.

java.sql.Timestamp ts = myResultSet.getTimestamp( … );

As part of the old troublesome date-time classes, minimize your use of the java.sql types. Immediately convert to java.time classes. An Instant is a moment on the timeline in UTC with a resolution of nanoseconds.

Instant instant = ts.toInstant();

Notice that all the moving parts are in UTC: database storage, JDBC, java.sql.Timestamp, and Instant. No time zone complications at all.

Adjust for México

For the customer in Mexico, apply the time zone that they choose or that you assume is appropriate.

ZoneId zdt_America_MexicoCity = ZoneId.of( "America/Mexico_City" );
ZonedDateTime zdt_America_MexicoCity = ZonedDateTime.ofInstant( instant , zdt_America_MexicoCity );

Search Stack Overflow for info about generating strings that are automatically localized into human language and cultural norms by using DateTimeFormatter class and its ofLocalized… methods.

Adjust for Singapore

Ditto for the customer in Singapore.

ZoneId zdt_Asia_Singapore = ZoneId.of( "Asia/Singapore" );
ZonedDateTime zdt_Asia_Singapore = ZonedDateTime.ofInstant( instant , zdt_Asia_Singapore );

All three objects, our instant and pair of ZonedDateTime objects, represent the same simultaneous moment on the timeline.

Adjust for UTC

For the airline staff person working in UTC, use the Instant if all you need for a textual representation is ISO 8601 format with 0, 3, 6, or 9 decimal place digits for fraction of second.

String output = instant.toString();

If you need other formats as a textual representation, use the java.time.format package after converting the Instant to the more flexibly-formatted OffsetDateTime class. Note the use of the constant for UTC, stored in the subclass of ZoneId, ZoneOffset.

OffsetDateTime odt = OffsetDateTime.ofInstant( instant , ZoneOffset.UTC );

Adjust Data Input

If the user is inputting the flight time in UK time zone, adjust to UTC afterwards. By the way, do not confuse UK time with UTC. London time has varied over history, currently changing with Daylight Saving Time while UTC never varies (except leap seconds).

ZoneId zoneId_Europe_London = ZoneId.of( "Europe/London" );
ZonedDateTime zdt = ZonedDateTime( 2016 , 1 , 3 , 9 , 0 , 0 , 0 , zoneId_Europe_London );
Instant instant = zdt.toInstant();
java.sql.Timestamp ts = java.sql.Timestamp.from( instant );

Local

This Answer applies to specific moments, a specific date and time-of-day. If you meant flight times in the sense of "9 AM" by the clock on the wall which can move around because of anomalies including Daylight Saving Time (DST), then that would be another discussion. The Question said the user is entering a specific date and a specific time so the discussion above applies.

Community
  • 1
  • 1
Basil Bourque
  • 218,480
  • 72
  • 657
  • 915