IBM Think

Domino Timezones

02 Jan 2021

There are a number of challenges when it comes to two-way REST and Domino. But one of the biggest challenges for manipulation between NotesDateTime objects and JSON is timezone handling. There is an Product Ideas request to provide serialization / deserialization between Domino objects and JSON strings, which surprisingly only has 31 votes, but it’s not there yet. So for Volt MX LotusScript Toolkit, this needs handling within the toolkit itself.

The first aspect to bear in mind is that time only or date only do not have timezones. 1st January 2021 is 1st January in Australia, 1st January in UK and 1st January in east coast USA. Similarly, 12 noon is 12 noon in Australia, UK and USA - whether daylight savings is in operation or not. If you want to store a single value for 12 noon in the current timezone on any given day, a NotesDateTime is not (strictly speaking) the best storage format, unless the value is to be used only within a Notes or Domino context.

So I’m focusing here only on full date-times, which include a timezone. Interestingly, this isn’t the first time I’ve had to approach the problem. Project Keep uses Domino JNX - a redevelopment learning from Domino JNA and OpenNTF Domino API, going via C++ API. That’s actually very easy, because the DateTime objects are actually stored as UTC timestamps - and incidentally that avoids all the challenges of writing values. I also addressed conversion in Java in OpenNTF Domino API and blogged about. For ODA and Java 8, I was able to use a Temporal and a DateTimeFormatter, in combination with the internationalisation formats, although we had the same problems for writing that Volt MX LotusScript Toolkit will have.

With LotusScript and Volt MX LotusScript Toolkit, I drew upon my experience of ODA as well as some JavaScript code that Jason Roy Gary developed. For the timezone format to write to, there is a standard defined, RFC 3339, section 5.6. This uses UTC offsets, so the only challenge is working out the UTC offset for Domino timezones. Unfortunately, that’s not so straightforward.

The NotesDateTime object has a .timezone method which might seem to be the go-to method. But this only returns an integer, as the help text says:

“An integer representing the time zone of a date-time. In many cases, but not all, this integer indicates the number of hours which must be added to the time to get Greenwich Mean Time. May be positive or negative.”

An obvious example of where this is insufficient is for times in India, were the offset is three and a half hours. But with .localTime the timezone is appended, after a space. However, the Domino timezones don’t neatly correspond to timezones as defined beyond Domino. Jason’s code was a useful starting point, because it identified all the possible timezone strings that Domino could output. But it became apparent that it didn’t handle the crucial element of daylight savings time. With some further digging I realised that the list - and the offsets Jason had used - came from an LDD article, thankfully reproduced online here. For someone who lives in the UK, I can tell you categorically that GDT does not have a 0:00 offset from GMT. It is one hour ahead of GMT. Similarly, other daylight savings time abbreviations - for example EDT, CEDT - do not have the same offsets as the standard time label. “ZW” and “ZE” are just offsets, west and east of the Greenwich Meridien. “YW” is more of a challenge and I can only guess this is 1 hour in advance of the corresponding “ZW” timezone, otherwise there is no reason to have a different abbreviation. So the table in the LDD article is, unfortunately, not correct, and it doesn’t appear there is a correct published table. And it’s also worth bearing in mind the offset is what to add to UTC, not how to adjust the timezone to return UTC. So here’s the adjusted table I’ve used:

Domino Timezone Long Name Conversion to Return UTC RFC 3339 Timezone
GMT Greenwich Mean Time Same as UTC Z
YW1 Daylight savings for timezone one hour west of GMT Same as UTC Z
ZW1 Timezone one hour west of GMT Add 1 hour -0100
YW2 Daylight savings for timezones two hours west of GMT Add 1 hour -0100
ZW2 Timezone two hours west of GMT Add 2 hours -0200
YW3 Daylight savings for timezone three hours west of GMT Add 2 hours -0200
NDT Daylight savings, Newfoundland Add 2.5 hours -0230
ZW3 Timezone three hours west of GMT Add 3 hours -0300
ADT Atlantic Daylight Savings Add 3 hours -0300
NST Newfoundland Add 3.5 hours -0330
AST Atlantic Standard Time Add 4 hours -0400
EDT Eastern Daylight Savings Add 4 hours -0400
EST Eastern Standard Time Add 5 hours -0500
CDT Central Daylight Savings Add 5 hours -0500
CST Central Standard Time Add 6 hours -0600
MDT Mountain Daylight Savings Add 6 hours -0600
MST Mountain Standard Time Add 7 hours -0700
PDT Pacific Daylight Savings Add 7 hours -0700
PST Pacific Standard Time Add 8 hours -0800
YDT Alaska Daylight Savings Add 8 hours -0800
YST Alaska Standard Time Add 9 hours -0900
HDT Hawaii-Aleutian Daylight Savings Add 9 hours -0900
ZW9B Nine and a half hours west of GMT Add 9.5 hours -0930
HST Hawaii-Aleutian Standard Time Add 10 hours -1000
BDT Bering Daylight Savings Add 10 hours -1000
BST Bering Standard Time Add 11 hours -1100
ZW12 Twelve hours west of GMT Add 12 hours -1200
ZE12C Twelve and three quarters hours east of GMT Subtract 12.75 hours +1245
ZE12 Twelve hours east of GMT Subtract 12 hours +1200
ZE11B Eleven and a half hours east of GMT Subtract 11.5 hours +1130
ZE11 Eleven hours east of GMT Subtract 11 hours +1100
ZE10B Ten and a half hours east of GMT Subtract 10.5 hours +1030
ZE10 Ten hours east of GMT Subtract 10 hours +1000
ZE9B Nine and a half hours east of GMT Subtract 9.5 hours +0930
ZE9 Nine hours east of GMT Subtract 9 hours +0900
ZE8 Eight hours east of GMT Subtract 8 hours +0800
ZE7 Seven hours east of GMT Subtract 7 hours +0700
ZE6B Six and a half hours east of GMT Subtract 6.5 hours +0630
ZE6 Six hours east of GMT Subtract 6 hours +0600
ZE5C Five and three quarter hours east of GMT Subtract 5.75 hours +0545
ZE5B Five and a half hours east of GMT Subtract 5.5 hours +0530
ZE5 Five hours east of GMT Subtract 5 hours +0500
ZE4B Four and a half hours east of GMT Subtract 4.5 hours +0430
ZE4 Four hours east of GMT Subtract 4 hours +0400
ZE3 Three hours east of GMT Subtract 3 hours +0300
ZE2 Two hours east of GMT Subtract 2 hours +0200
CEDT Central European Daylight Savings Subtract 2 hours +0200
CET Central European Time Subtract 1 hour +0100
GDT British Summer Time Subtract one hour +0100

This is the basis of the code in Volt MX LotusScript Toolkit, so if you’re aware of any errors, please let me know so all can benefit.

Posted with : Domino, LotusScript, Volt MX