xpages and time zone - timezone

I am building apps that support users spread across multiple countries / time zones. I had two questions with timezone manipulations in xpages. Please share any tips you have to make this easier to code and maintain.
Time zone list
In notes client and traditional domino web design we have a standard timezone control that lists exhaustive timezone options. With xpages, we do not have any such control and have to resort to maintaining some config based static list on our own. This is not very desirable as it does not update when DST rules change for countries or new time zones are introduced. These apps may also be accessed via notes client so we cannot really use java tz format, it should be the notes TZ constant (Z=6$DO..).
Is there a way to show a dynamic list of notes timezone options?
Time zone conversion (notes/java)
How do you convert a notes timezone constant into its java equivalent and vice-versa?
Scenario:
If a user in North America wants to know the current time in a different timezone, say X. Where X is stored in the current notes document. Can you do this conversion using SSJS code?
Currently, we are using #Texttotimeinzone and evaluating it (#Texttotimeinzone is not a SSJS function). Is there a simpler way to convert a notes tz constant to java so we can perform all date conversions using java classes?

The teamroom template that ships with the ExtLib has a calendar that has the option to create a meeting and specify the time zone.
check out the custom control "controlSectionTimezonePicker". It might not be exactly what your looking for but should be a good start as a working example.

You can include the time zone information along with the date.
Initialise the date variable and use .toString() (link to documentation)
Or you can compute it in a field with JS like
var d=new Date();
d.toString()
Instead of .toString(), you can use .toUTCString().

Related

Is there any global time/date format parsable by Google Sheets etc?

Is there any global timestamp format which can be automatically parsed and understood by most major spreadsheet software? (But especially Google Sheets.)
For example, consider the timestamp "2020-05-08T02:53:03+00:00". If I try to paste this into the spreadsheet as:
1) "2020-05-08T02:53:03+00:00" : not parsed by any major spreadsheet software
2) "2020-05-08T02:53:03Z" : not parsed by any major spreadsheet software
3) "20200508T025303Z" : not parsed by any major spreadsheet software
4) "2020-05-08 02:53:03 GMT" : not parsed by any major spreadsheet software
5) "2020-05-08 02:53:03" : parses; but only correct if user is in GMT/UTC
Please note that I am not the user, I cannot autodetect the user's timezone, and I cannot demand that they reconfigure their spreadsheet software to a particular timezone. All I can do is give them a string similar to the above -- which they expect to paste into their spreadsheet and it "just works". Anywhere in the world.
Format must be human-readable (no epoch times or Excel serials). User-side scripting is only acceptable if Grandpa can handle it. Grandpa just learned last week how to copy/paste (and still hasn't forgiven you for it). He uses Excel and will hurl a shoe at you if you say "Google Sheets". Or "script". Or "menu".
Or "Obama".
Details: I'm writing a script which presents a table full of timestamps to the user (by web, email, etc). Some users will then copy/paste the table into their spreadsheet software, and they will expect this software to automatically and correctly parse the timestamps so that they can be converted to the user's local timezone, can be used in spreadsheet math, etc. This of course requires that I give them a format where the timezone is either unnecessary or clearly specified. Like most coders, I can easily convert timestamps to any string format.
Rant: The standard ISO 8601 formats (examples 1-3 above) were created specifically for this purpose. So I was rather shocked to find that not even the datevalue() function in Google Sheets can parse them. I mean, Google can't parse ISO 8601? Google?? This is so unbelievable that I require independent confirmation. Because I must be missing something. There must be some global timestamp format that Google can parse.
I mean, come on. This is 2020. And it's Google.
With Google Apps Script you can parse dates with formatDate(date, timeZone, format) like the following:
function myFunction() {
var date = new Date('2020-05-08T02:53:03+00:00');
var formattedDate = Utilities.formatDate(date, "GMT", "yyyy-MM-dd HH:mm:ss");
Logger.log(formattedDate);
}
And you can also get the user's time zone with getScriptTimeZone().
With this you can make the user use this script on Sheets and with a trigger onOpen() or onEdit() reformat all the dates to their zone

Time zones `Etc/GMT`, why it is other way round?

Time zones in php work like this https://www.gsp.com/support/virtual/admin/unix/tz/gmt/
and when it named Etc/GMT+11 it actually GMT-11
and when it named Etc/GMT-11 it actually GMT+11
Why? And what does it mean Etc/GMT?
I find it in PHP, is it a bug in PHP or is it everywhere?
This is not a bug. The tz database identifiers of the form Etc/GMT±* deliberately have an inverted sign than the usual forms we expect under ISO 8601. That is, they are in terms of positive values being West of GMT, rather than positive values being East of GMT.
The reason is for backwards compatibility with POSIX style time zone identifiers, such as are used with the first format of the TZ environment variable. When POSIX compliant systems interpret this variable, values like America/Los_Angeles would clearly fall through to the third format (described in the same document), but values like Etc/GMT+11 are ambiguous as to which format rules should apply. Thus the zone identifiers must have their signs inverted to be compliant.
From the tz database where these zones are defined:
# Be consistent with POSIX TZ settings in the Zone names,
# even though this is the opposite of what many people expect.
# POSIX has positive signs west of Greenwich, but many people expect
# positive signs east of Greenwich. For example, TZ='Etc/GMT+4' uses
# the abbreviation "-04" and corresponds to 4 hours behind UT
# (i.e. west of Greenwich) even though many people would expect it to
# mean 4 hours ahead of UT (i.e. east of Greenwich).
This is also discussed in the Wikipedia article on the tz database.
As far as practical matters, the tz database commentary also says:
# These entries are mostly present for historical reasons, so that
# people in areas not otherwise covered by the tz files could "zic -l"
# to a time zone that was right for their area. These days, the
# tz files cover almost all the inhabited world, and the only practical
# need now for the entries that are not on UTC are for ships at sea
# that cannot use POSIX TZ settings.
So, if you're not keeping time for ships at sea, I highly suggest you use a locality based identifier instead. (perhaps Australia/Melbourne ?)
Also, A better source of time zone identifiers would be the one on Wikipedia.
Since you said you were using PHP note that the PHP documentation has a list as well, and on the "Others" page, it actually explains this as well:
Warning
Please do not use any of the timezones listed here (besides UTC), they only exist for backward compatible reasons, and may expose erroneous behavior.
Warning
If you disregard the above warning, please also note that the IANA timezone database that provides PHP's timezone support uses POSIX style signs, which results in the Etc/GMT+n and Etc/GMT-n time zones being reversed from common usage.
For example, the time zone 8 hours ahead of GMT that is used in China and Western Australia (among other places) is actually Etc/GMT-8 in this database, not Etc/GMT+8 as you would normally expect.
Once again, it is strongly recommended that you use the correct time zone for your location, such as Asia/Shanghai or Australia/Perth for the above examples.

Time of Day in the JSON response model?

I am using ASP.NET Web Api 2 with Json.NET 6.0.1.
According to ISO 8601, dates should be interchanged in a certain way. I am using the IsoDateTimeConverter() in order to achieve this:
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new IsoDateTimeConverter());
But how should "time of day" be returned in a JSON response model?
I cannot find anything for this in the ISO specification.
Should time perhaps be returned as a:
TimeSpan? (with expectation of the user to not use this as a duration representation)
DateTime? (with expectation of the user to drop off the date part)
A custom Time class
There is no standard structure in JSON for containing dates or times (see JSON.org). The de-facto stardard for dates-time values is using a string in ISO 8601 format, as you mentioned. But since there is no official standard it really comes down to what works best for you and consumers of your API.
Using a DateTime object is a reasonable choice because the support already exists in Json.Net and other serializers for converting these to and from ISO 8601 strings. So this would be the easiest to implement. However, users of your API would have to know to disregard the date portion, as you said. You could set the date to 0001-01-01 to emphasize its irrelevance. This isn't so different from the more common situation where you need only a date in your API and the time doesn't matter. Most people just set the time to midnight in this case and let it go. But, I would agree that this approach does seem to have a little bit of a "code smell" to it, given that part of the value is just noise.
Perhaps a cleaner idea is to format your DateTime value as ISO 8601, but then chop off the date portion before returning it. So users of the API would get a string that looks like 14:35:28.906Z. You could write a simple JsonConverter to handle this for you during serialization. This would sort of give you the best of both worlds -- a cleaner API, but you still can work with the familiar DateTime struct internally.
A custom Time class could also work here, but might be overkill, depending. If you do need to go there, you might want to look into a third-party library such as Noda Time, which has classes already built for these kinds of things, and also has pre-built converters for Json.Net.
I would definitely not choose TimeSpan for this purpose. Wrong tool for the job.

Mapping IANA/Olson timezone database to abbreviations (like EST, PST, etc)

I need to map IANA/Olson timezone id to abbreviations, like EST, PST, etc.
I understand that this is not 1-to-1 mapping and that, for example, for EST there are quite a bunch of IANA timezones.
Is there some kind of database/mapping I can use for this?
PS: JavaScript solution is preferable, but any info that could help me to build this mapping (IANA timezone id -> abbreviation) is appreciated.
The IANA TZDB source data does have abbreviations already, but they have to be computed for the date in question. You can see it in the example data here, in the Zone.FORMAT and Rule.LETTER/S columns.
Since time zone abbreviations like CST can be ambiguous, it is only recommended you use them for display to a human. Never attempt to use them going the other direction, because only a few will be recognized by most implementations, and they tend to be valid only for the USA.
Since you asked for code that could do this for you, look at the bottom half of the code in my answer of how to do this using Noda Time in .Net. (The top half is about translating from a Windows zone to an IANA zone first, which you don't need.)
You could look at one of the several TZDB libraries for JavaScript, but I'm not sure if any directly expose the abbreviation data or not. Besides, that's a bit heavy for something so small.
In java with joda-time, we can get time-zone abbreviation from iana id as below
DateTimeZone dz = DateTimeZone.forID("America/New_York");
String tzid = dz.getShortName(DateTimeUtils.currentTimeMillis());
//tzid will be 'EST'
String longerTimeZoneName = dz.getName(DateTimeUtils.currentTimeMillis());
//longerTimeZoneName will be 'Eastern Standard Time'

Are 'US/Eastern' and 'US/Central' and 'US/Pacific' deprecated for strftime or just PHP?

I have a shell script (zsh, to be precise) which uses
strftime "%I:%M %p %Z (%a, %b %d)" "$EPOCHSECONDS"
to generate a "current time" such as
"02:45 PM CST (Thu, Mar 01)"
This needs to be able to display the time in several different USA timezones, and so I have been using 'US/Eastern', 'US/Central', and 'US/Pacific' like so:
export TZ='US/Eastern'
strftime "%I:%M %p %Z (%a, %b %d)" "$EPOCHSECONDS"
That seems to work just fine, and I prefer it to using TZ='America/CityName' because it doesn't require me to know which city is in which TZ, I just need to tell it which TZ I want.
However, I happened across http://www.php.net/manual/en/timezones.others.php and saw that it says
Please do not use any of the timezones listed here (besides UTC),
they only exist for backward compatible reasons.
I don't know what the issues are with the US/Region names, but I'm curious to know if using them is likely to cause a problem in the foreseeable future, or are they still safe to use? Is it just PHP which doesn't like them, or is everyone moving away from them?
The standard format for naming timezones in the Olson database is Continent/City. The "old" names you mention like US/Eastern, US/Central, and many more, are listed as backward compatibility links in the tzdata source distribution (in the file "backward"). According to the comment at the top of the file, these names may have become backward compatibility links in late 1993.
I think I remember reading that this standard was adopted because it was felt to be more stable: geopolitical (country) boundaries change, cities never move around. Maybe also because names like "Eastern" and "Central" are thought to be more confusing because they mean different timezones in different parts of the world. However, I cannot find any references to the naming rationale at the moment, so don't quote me on this.
The Continent/City-style names are preferred. Notice that operating systems like Debian and Ubuntu ask you to select the system timezone using these names (unless they autodetect it at installation time), Using these names you wouldn't really be required to, as you say, "know which city is in which TZ" because the city name is, well, part of the timezone name! So if you happen to have learned the Continent/City names instead of or in addition to the Country/Region names, you're already OK.
That being said, I do not think that these names will ever disappear. On the timezone mailing list, they are definitely always called "backward compatibility", not "deprecated", and are intended to stay, notwithstanding what PHP recommends.

Resources