2

I'm about to deal with time zones in Grails (Java). Here Java 7 is used and Grails 2.3.7.

I have a WebApp where each user is assigned a timeZoneID. If a user enters a date, it only consists of day, month and year. I want to set the time automatically.

The date entered by the user (e.g. 01.10.2018, german format) should be saved in the DB (MySQL) in UTC format. When the date is displayed to the user, it is formatted according to the user's time zone.

Many timeZoneIDs work fine with my code (Europe/Berlin, Hont_Kong, ....), but America/New_York for example doesn't and I don't understand why.

The code to parse and save a date is as follows:

//endDate is 31.10.2018
def format = messageService.getMessage(code: 'default.date.short.format')

//--> dd.MM.yyyy for DE and MM/dd/yy for EN
println("Use format: " + format)

SimpleDateFormat sdf = new SimpleDateFormat(format);

//set timezone (America/New_York)
sdf.setTimeZone(TimeZone.getTimeZone(user.timeZoneID))

//parse endDate
Date parsedEndDate = sdf.parse(endDate)

//create a calendar instance (e.g. America/New_York)
Calendar calendarEnd = Calendar.getInstance(TimeZone.getTimeZone(user.timeZoneID));

//set time
calendarEnd.setTime(parsedEndDate);

//set hour/minute automatically
calendarEnd.set(Calendar.HOUR_OF_DAY, 23)
calendarEnd.set(Calendar.MINUTE, 59)

//at this point it should be 31.10.2018, 23:59 (german format, timezone America/New_York)

//Convert to UTC before saving date in DB (MySQL)
calendarEnd.setTimeZone(TimeZone.getTimeZone('UTC'))

//save the date
def obj = new Foo(date:calendarEnd).save(flush:true)

The code inside my view (gsp) to display a date is as follows:

<g:formatDate
        timeZone="${user.timeZoneID}"
        date="${fooInstance?.calendarEnd}"
        format="${message(code: 'default.date.format', default: 'MM/dd/yyyy, hh:mm a')}"/>

Inside the DB I get 2018-11-01 00:59:00 Inside my view (GSP) it results in 31.10.2018, 19:59, instead of 31.10.2018, 23:59

Thank you very much for your help.

Sweeny
  • 21
  • 2
  • FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Oct 16 '18 at 21:50
  • Thank you. I switched to joda time. Unfortunately java 8 is no option – Sweeny Oct 18 '18 at 10:26
  • The Joda-Time project is now in maintenance mode, receiving updates and bug fixes but no new feature work. The man heading that project, Stephen Colebourne, also leads the *ThreeTen-Backport* project that brings most of the *java.time* functionality to Java 6 & 7 with virtually the same API. – Basil Bourque Oct 18 '18 at 18:37

1 Answers1

1

The problem is in convert step:

//Convert to UTC before saving date in DB (MySQL)
calendarEnd.setTimeZone(TimeZone.getTimeZone('UTC'))

Because you are just changing the time zone so it is using the given time and date as if it is the UTC time zone.

Java 1.7 and before are somewhat unwieldy in regards to the Time API so a lot of people use Joda Time.

Otherwise you can use the advice from this question resulting in something like:

calendarEnd.add(Calendar.MILLISECOND, TimeZone.getTimeZone('UTC').getOffset(parsedEndDate.getTime())

This is not tested and could be wrong as the offset calculation might be diffrent

Dinomaster
  • 256
  • 1
  • 6
  • Thank you very much for your Answer. And I thought the time zone would not only be set but also converted. So how do I than convert to UTC If this sets only the timezone? – Sweeny Oct 16 '18 at 13:16
  • Ok, the above code works in certain situations, but it doesn't solve the problem completely. I have integrated the joda time plugin into my Grails app. Since the attributes in the domain classes are of type Calendar, I would implement a service that calculates the time zones over the Joda time. I.e. in the domain class I still have calendars. Within the logic however exclusively DateTime. The calendar objects are stored in the database in UTC. The question is (in terms of application design and further implementations) whether this is a good idea? Or is it necessary to rework my application? – Sweeny Oct 18 '18 at 09:50
  • I have dealt with this issue as well and I just wrote an Calendar to/from DateTime converter that was applied where needed – Dinomaster Oct 18 '18 at 10:50