1

I am looking for solution, how to deal with the data which has specific time related data.

Project Architecture : Backend is RESTful services build in Java.

Frontend is: 1. Angular JS (for web only) 2. Native Mobile App (Android, iPhone).

For eg. one device is in UK (i.e. UTC+1:00) time zone another device is in HKT (Hong Kong i.e. UTC+8:00) timezone.

My server is in Germany (i.e. UTC +2:30) timezone.

What I should keep at server?

How to show current time at each device (web browser as well as mobile devices), and if I am serving web pages, which can be accessible from anywhere, which timezone value I should keep?

Current solution: Currently I am keeping whenever data is arrived at server calculate the UTC epoch time and store it, send the time as it is via REST and then at client side (web browser or Android device ) I am converting it to local Timezone.

Is this approach correct?

virsha
  • 1,140
  • 4
  • 19
  • 40
  • 2
    This may be of some help: http://yellerapp.com/posts/2015-01-12-the-worst-server-setup-you-can-make.html. tl;dr: use UTC for both your application and DB servers. – Naufal Jun 06 '17 at 01:42
  • 1
    Your approach sounds correct and fine to me. You may want to use `java.time.Instant` for storing, it is equivalent to epoch time (with nanosecond precision), but its `toString()` prints the UTC date and time, might be convenient in log statements and for debugging. – Ole V.V. Jun 06 '17 at 10:33

1 Answers1

2

Yes, your approach seems fine and correct.

For your implementation: if you're using Java 8, consider using the new java.time API. It's easier, less bugged and less error-prone than the old APIs.

If you're using Java <= 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, there's the ThreeTenABP (more on how to use it here).

The code below works for both. The only difference is the package names (in Java 8 is java.time and in ThreeTen Backport is org.threeten.bp), but the classes and methods names are the same.

To get the UTC time, you can use the Instant class. It's the best choice because it's always in UTC, and can be easily converted to and from another timezones:

// get current UTC time - Instant is always in UTC
Instant instant = Instant.now();

// you can use the string representation
System.out.println(instant.toString());// 2017-06-06T11:57:21.665Z
// or the timestamp (epoch millis - milliseconds from 1970-01-01T00:00:00Z)
System.out.println(instant.toEpochMilli());// 1496750241665

// convert to another timezone (always use valid IDs)
ZonedDateTime z = instant.atZone(ZoneId.of("America/Sao_Paulo"));
System.out.println(z);// 2017-06-06T08:57:21.665-03:00[America/Sao_Paulo]

// in another timezone
z = instant.atZone(ZoneId.of("Europe/Berlin"));
System.out.println(z);// 2017-06-06T13:57:21.665+02:00[Europe/Berlin]

// convert back to UTC Instant
System.out.println(z.toInstant()); // 2017-06-06T11:57:21.665Z

The API uses IANA timezones names (always in the format Continent/City, like America/Sao_Paulo or Europe/Berlin). Avoid using the 3-letter abbreviations (like CST or PST) because they are ambiguous and not standard. You can use ZoneId.getAvailableZoneIds() to get a full list of all timezones names.

You can also use ZoneId.systemDefault() to get the system's default timezone. In this case, if the code runs on a server, it'll use the server's machine timezone. And if it runs in a device, it'll use whatever is configured in the device.