Timezone logic in OE ABL

Posted by dbeavon on 24-Jan-2019 17:41

Has anyone worked with apps that need to interact with users from multiple timezones?

I find the existing ABL programming API to be very cumbersome in the area of datetime's and timezone conversion.  I hope that Progress will consider building some OO classes whose semantics are easier to work with.

One of the bigger problems is that certain data-types are named exactly the same as functions that operate on those types (eg. DATETIME and DATETIME-TZ).  Additionally, certain of those functions have a number of overloaded variations which work in substantially different ways, despite having the same name.  Additionally some of these functions interact auto-magically with a "session" variable, SESSION:TIMEZONE, which is an offset in minutes from UTC.  This "feature" has been a source of actual bugs in prior versions of OE ABL.  Apparently Progress has trouble with this API as well. 

 

Whenever I'm working with datetimes and converting them back and forth between UTC and the local timezone of the user, I have to refer to a bunch of my previously written (& trusted) code to avoid introducing bugs.  The same is true for other members of my team, who currently consider me the "timezone expert".  This stuff is not confusing except insofar as the ABL programming API makes it so.  There should be no need of a "timezone expert".

Perhaps it would be better if the questions were posted to this forum, so that one day these ABL-timezone-related questions will come up in google search results.

Posted by gus bjorklund on 25-Jan-2019 15:28

Values of variables and database fields of type datetime-tz are stored as GMT, with a timezone offset in minutes initially set to the "originating timezone". database indexing, arithmetic, and comparisons are all done in GMT independent of the timezone value.

you can determine the timezone setting of a datetime-tz value by using the timezone function, as follows:

tzoffset = timezone (dtx expression).

you can change the stored timezone of a datetime-tz variable or field by using the datetime-tz function, as follows:

dtzvariable = datetime (dtzvariable, newtzoffset).

the SESSION:DISPLAY-TIMEZONE attribute is used when converting a datetime-tz value to display format. if the SESSION:DISPLAY-TIMEZONE has not been set, then the SESSION:TIMEZONE is used instead. you can change the SESSION:DISPLAY-TIMEZONE to be whatever you want to be used when displaying datetime=tz values. The setting has no effect on the stored values, only on display formatting.

the SESSION:TIMEZONE attribute is used as the "originating timezone" when assigning values to datetime-tz variables.

When sessions in different timezones assign values to database fields, they can be compared directly and give the correct result as long as each session's SESSION:TIMEZONE is set correctly.

You can think of the timezone part of a datetime-tz value as being mostly for display purposes.

Posted by dbeavon on 24-Jan-2019 19:07


>> sharing details of the issues you ran into

The primary issue is that I and other ABL developers in my team (with 10 years or more of ABL experience) have a hard time interacting with the related API.  There are a lot of pitfalls and it is easy generate invalid data.  I'm wondering if others have the same difficulty.  Hopefully Progress will revisit this topic now that they have added OO features to the language.  I suppose I could write my own OO wrappers that would have better semantics than the existing API, but that seems like something which customers shouldn't be doing on their own.

Even Progress seems to have difficulty with their own datetime/timezone API.  Here is a bug that I had reported some time ago.

https://knowledgebase.progress.com/articles/Article/Inconsistency-assigning-datetime-tz-to-datetime

As a result of that support case,  a new client session parameter was created (-usesessionTZ).  And the default behavior prior to OE 11.7 was to preserve the bug mentioned in the KB.

Here is the documentation for "-usesessionTZ": https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/dpspr/use-session-3atimezone-(-usesessiontz).html

That is one of several pitfalls when interacting with time-related functionality in ABL.  Other pitfalls aren't necessarily because of Progress bugs, but we run into them because of the way the API was designed.  It is hard to use the API without scrutinizing the documentation to see how each function and variable-assignment is supposed to behave. 

Like I said earlier, things would be easier if data types had different names than functions, if functions didn't have so many overloads that worked so differently from one another, and if there wasn't so much auto-magical behavior that seems to depend on the value of SESSION:TIMEZONE.

All Replies

Posted by Mike Fechner on 24-Jan-2019 17:50

Mind sharing details of the issues you ran into?

Sent from Nine

Von: dbeavon <bounce-dbeavon@community.progress.com>
Gesendet: Donnerstag, 24. Januar 2019 18:42
An: TU.OE.Development@community.progress.com
Betreff: [Technical Users - OE Development] Timezone logic in OE ABL

Update from Progress Community
dbeavon

Has anyone worked with apps that need to interact with users from multiple timezones?

I find the existing ABL programming API to be very cumbersome in the area of datetime's and timezone conversion.  I hope that Progress will consider building some OO classes whose semantics are easier to work with.

One of the bigger problems is that certain data-types are named exactly the same as functions that operate on those types (eg. DATETIME and DATETIME-TZ).  Additionally, certain of those functions have a number of overloaded variations which work in substantially different ways, despite having the same name.  Additionally some of these functions interact auto-magically with a "session" variable, SESSION:TIMEZONE, which is an offset in minutes from UTC.  This "feature" has been a source of actual bugs in prior versions of OE ABL.  Apparently Progress has trouble with this API as well. 

 

Whenever I'm working with datetimes and converting them back and forth between UTC and the local timezone of the user, I have to refer to a bunch of my previously written (& trusted) code to avoid introducing bugs.  The same is true for other members of my team, who currently consider me the "timezone expert".  This stuff is not confusing except insofar as the ABL programming API makes it so.  There should be no need of a "timezone expert".

Perhaps it would be better if the questions were posted to this forum, so that one day these ABL-timezone-related questions will come up in google search results.

View online

 

You received this notification because you subscribed to the forum.  To stop receiving updates from only this thread, go here.

Flag this post as spam/abuse.

Posted by Brian K. Maher on 24-Jan-2019 18:06

Have you looked into session:time-source = “some_connected_db” ??
 
This would allow you to align all date/time logic to the date/time of the machine on which the specified database is running.
 
 
Brian Maher
Principal Engineer, Technical Support
Progress
Progress
14 Oak Park | Bedford, MA 01730 | USA
phone
+1 781 280 3075
 
 
Twitter
Facebook
LinkedIn
Google+
 
 

Posted by dbeavon on 24-Jan-2019 19:07


>> sharing details of the issues you ran into

The primary issue is that I and other ABL developers in my team (with 10 years or more of ABL experience) have a hard time interacting with the related API.  There are a lot of pitfalls and it is easy generate invalid data.  I'm wondering if others have the same difficulty.  Hopefully Progress will revisit this topic now that they have added OO features to the language.  I suppose I could write my own OO wrappers that would have better semantics than the existing API, but that seems like something which customers shouldn't be doing on their own.

Even Progress seems to have difficulty with their own datetime/timezone API.  Here is a bug that I had reported some time ago.

https://knowledgebase.progress.com/articles/Article/Inconsistency-assigning-datetime-tz-to-datetime

As a result of that support case,  a new client session parameter was created (-usesessionTZ).  And the default behavior prior to OE 11.7 was to preserve the bug mentioned in the KB.

Here is the documentation for "-usesessionTZ": https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/dpspr/use-session-3atimezone-(-usesessiontz).html

That is one of several pitfalls when interacting with time-related functionality in ABL.  Other pitfalls aren't necessarily because of Progress bugs, but we run into them because of the way the API was designed.  It is hard to use the API without scrutinizing the documentation to see how each function and variable-assignment is supposed to behave. 

Like I said earlier, things would be easier if data types had different names than functions, if functions didn't have so many overloads that worked so differently from one another, and if there wasn't so much auto-magical behavior that seems to depend on the value of SESSION:TIMEZONE.

Posted by dbeavon on 24-Jan-2019 19:22

>> session:time-source = “some_connected_db” ?

This was essentially how we used to design our ABL software.  Unfortunately if a given database is used across multiple timezones, it didn't end up being a good solution.  The timezone of the database is not necessarily a great reference point (especially when the server of the database observes daylight savings).   We ended up settling on using UTC for storing absolute chronological date/time to the database.

Every user has their own timezone.  It is a not much more than preference.  Showing a given date/time in a some (preferred) timezone is analogous to displaying a length that is formatted as feet or meters.

By storing chonological datetime values as UTC (which doesn't respect daylight savings), it is more intuitive to convert back and forth to the user's preference of timezone.  Even then, the API is not totally straightforward, and the semantics are a bit clunky.  It would be nice to see some improvement.  Perhaps I'll add an enhancement idea to create an OO wrapper...

Posted by gus bjorklund on 25-Jan-2019 15:28

Values of variables and database fields of type datetime-tz are stored as GMT, with a timezone offset in minutes initially set to the "originating timezone". database indexing, arithmetic, and comparisons are all done in GMT independent of the timezone value.

you can determine the timezone setting of a datetime-tz value by using the timezone function, as follows:

tzoffset = timezone (dtx expression).

you can change the stored timezone of a datetime-tz variable or field by using the datetime-tz function, as follows:

dtzvariable = datetime (dtzvariable, newtzoffset).

the SESSION:DISPLAY-TIMEZONE attribute is used when converting a datetime-tz value to display format. if the SESSION:DISPLAY-TIMEZONE has not been set, then the SESSION:TIMEZONE is used instead. you can change the SESSION:DISPLAY-TIMEZONE to be whatever you want to be used when displaying datetime=tz values. The setting has no effect on the stored values, only on display formatting.

the SESSION:TIMEZONE attribute is used as the "originating timezone" when assigning values to datetime-tz variables.

When sessions in different timezones assign values to database fields, they can be compared directly and give the correct result as long as each session's SESSION:TIMEZONE is set correctly.

You can think of the timezone part of a datetime-tz value as being mostly for display purposes.

Posted by dbeavon on 30-Jan-2019 14:53

Thanks for the tips Gus.   I suppose it is possible that I have exaggerated the complaints about how confusing this API is.  It doesn't sound like anyone else has the same trouble that we have.  

But I still think it would be nice to have some OO wrappers with semantics that are a bit more explicit and intuitive.

The fact that some of the API will implicitly take into account your session (SESSION:TIMEZONE and SESSION:DISPLAY-TIMEZONE) can be both a good thing *and* a bad thing.  The use of the session will introduce a bit of uncertainty into the API, since those are used "under the hood".  I suspect that they are necessary for some complex reason, like preserving compatibility between the code that *is* and the code that is *not* aware of the existence of timezones....  But I must say that I really don't like them; these TIMEZONE-related session members act in a way that brings to mind "shared variables" (shudder).

Some of our code is written in a way that is *not* bound to one individual timezone (eg. batch processes, services and such).  This type of code may deal with transaction data from many timezones.  The fact that this ABL batch-process-code is implicitly making use of it's *own* SESSION:TIMEZONE is problematic, especially if SESSION:TIMEZONE is not set to UTC.

Thanks for the feedback.

Posted by gus bjorklund on 03-Feb-2019 20:02

dont forget that you can change the SESSION:TIMEZONE and SESSION:DISPLAY-TIMEZONE settings as needed and as often as you wish.

Posted by Jurjen Dijkstra on 05-Feb-2019 10:47

Hope you don't mind that I chime in... but I was wondering, if you want some OO wrappers with semantics that are a bit more explicit and intuitive, then what stops you from designing and writing them? I would not wait for PSC.

It would be great if one could find such OO classes on Github (or somewhere else), but somebody has to be the first to write and publish them.

Probably it is not very easy to do it right. I have once seen an interview with a member of the team who are maintaining the excellent moment.js  package (https://momentjs.com), they experienced all kinds of quirks in how people subjectively perceive what the right time is.

Anyway, if one would design an OO wrapper, then moment.js would be a very good example.

This thread is closed