Recently, while developing a Uniface application within a microservices architecture, I found myself tackling a common issue: how to manage users and systems across different time zones within a single application. If you’re working with dates and times on the web, you’ll inevitably encounter time zones—and Uniface developers are no exception. With the increasing integration of web interfaces and web services in Uniface applications, understanding time zones is essential.
Starting from version 9.4, Uniface offers time zone support, though it’s disabled by default. Activating it is simple, either in code or in the assignment file. The question isn’t whether Uniface can handle time zones, but rather how best to do it. Let’s dive into what time zones mean for Uniface, why the functionality is off by default, and how to use it effectively. And the best part? I’ve created a library with all the time zone functions discussed here—completely open source and ready for you to use.
Why Time Zone Support is Disabled by Default
Before explaining how to work with time zones in Uniface, it’s useful to understand why this feature is disabled by default. Most applications operate within a single time zone, where time zone management isn’t necessary. If your application is designed for local use or has no interfaces with systems in other time zones, time zones are likely irrelevant. Enabling time zone support in such cases could even disrupt existing functionality.
In cases where time zones matter, many developers have implemented their own solutions. Uniface’s time zone functionality remains off by default to preserve existing code, giving developers control over when and how to activate it.
Why Your Application Needs Time Zone Support
Understanding why time zones are important requires a look at what they are and why they exist. The Earth rotates around the sun and its axis, creating day and night and dividing a 24-hour day into time zones. Although each location on Earth experiences its own “high noon,” modern life requires a standardized time system. In 1884, we established 24 time zones and set the prime meridian at Greenwich, England, creating Greenwich Mean Time (GMT).
GMT was later replaced by Coordinated Universal Time (UTC), which isn’t an acronym but a compromise between the French “TUC” and English “CUT.” In IT, UTC time is also known as “Zulu time,” providing a universal time standard. To the right of Greenwich on the world map, the time is later than UTC, marked by a positive offset. To the left, it’s earlier, indicated by a negative offset.
In daily life, working with time zones is instinctive—we know that half-past four in our time zone might be quite different elsewhere. But applications don’t have this instinct; they need explicit instructions. If your application operates solely within a single time zone, time zones are irrelevant. However, if it must serve users across time zones, enabling Uniface’s time zone functionality is crucial. After all, 4:30 p.m. in the Netherlands differs significantly from 4:30 p.m. in New Zealand or New York.
How to Work with Time Zones in Uniface
The last example illustrates an important concept. While 4:30 p.m. in one time zone may not be the same in another, the time is technically the same when referenced in a single time zone. For example, if I schedule a meeting at 4:30 p.m., the exact time matters only when communicating it to someone in another time zone, at which point we use UTC.
Uniface follows a similar logic, distinguishing between internal and external times. With time zone functionality enabled, the internal time is always in UTC, with Uniface automatically converting local time to UTC. External time is what the application displays to the user in their local time zone.
Here’s an example: I live in the Netherlands, and my application runs on a server there. If my users are also nearby, time zones aren’t necessary. But with a user in Sydney, or if my server were in India and using a web service from Los Angeles, I’d be juggling four time zones, not to mention the added complexity of daylight saving time.
Let’s look at an example table for 3:30 p.m. on Wednesday, November 4, 2020:
| Location | Timezone | UTC Offset | Local Time |
| Amsterdam | Central European Time | +1:00 | 15:30 |
| Sydney | Australian Eastern Daylight | +11:00 | November 5, 01:30 |
| New Delhi | India Standard Time | +5:30 | 20:00 |
| Los Angeles | Pacific Standard Time | -8:00 | 6:30 |
In all cases, UTC time remains the same: 14:30. By working in UTC and specifying the offset, we maintain consistency across time zones.
$nlsinternaltime
The `$nlsinternaltime` function defines the internal time zone Uniface should use, with two possible values:
- Classic: Time zones are ignored (default setting).
- UTC: Uniface uses UTC as its internal time zone, enabling time zone functionality.
Note: When `$nlsinternaltime` is set to UTC, Uniface treats all times in the application and database as UTC. Use caution when applying this in existing applications with pre-existing time data.
To activate time zones via the assignment file, use `$NLS_INTERNAL_TIME`, which accepts the same values as `$nlsinternaltime`.
$nlstimezone
Once time zone support is enabled, Uniface distinguishes between internal UTC time and external user-local time. The `$nlstimezone` function specifies the external time zone:
- Classic: Uniface assumes all time-related data is local.
- System: Explicitly sets the external time to match the operating system’s time zone.
- Time zone: Allows you to specify an alternative time zone.
In the assignment file, `$NLS_TIME_ZONE` specifies the time zone.
$nlstimezonelist
Uniface recognizes all common time zones defined by the Unicode Common Locale Data Repository (CLDR). Use `$nlstimezonelist` to retrieve all supported time zones or to identify the current time zone with `$nlstimezonelist(“system”)`.
Practical Use in Uniface
With just three functions—`$nlsinternaltime`, `$nlstimezone`, and `$nlstimezonelist`—Uniface provides full time zone support. While tempting to enable by default, consider that all time-related data, whether stored in a database or retrieved with `$clock`, `$date`, or `$datim`, will be in UTC. This may require a shift in mindset.
For instance, in the Netherlands (wintertime), a local time of 16:58 is 15:58 UTC internally. Extracting the hour with `$clock[H]` returns 15. While this is expected, it requires awareness from the developer.
Experienced Uniface developers may prefer disabling time zone functionality by default, enabling it only when necessary. This approach allows the use of time zones in existing applications while maintaining control.
ISO8601
Time zones matter only when communicating times. To avoid confusion, time zones should be specified, and the ISO8601 standard is widely accepted for this purpose. For example, in Amsterdam:
- Local time: `2020-11-04T15:30:49+01:00`
- UTC time: `2020-11-04T14:30:49+00:00`
And in Sydney:
- Local time: `2020-11-05T01:30:49+11:00`
- UTC time: `2020-11-04T14:30:49+00:00`
Uniface’s time zone functions support ISO8601 easily. Here’s an example:
variables string vs_tz_datetime datetime vdt_tz, vdt_utc numeric vn_offset endvariables ; Switch on the Uniface time zone support $nlsinternaltime = "UTC" $nlstimezone = "UTC" ; Capture the current UTC time vdt_utc = $datim ; Set to required time zone and convert to string format $nlstimezone = "AEDT" vs_tz_datetime = "%%vdt_utc" ; Revert to classic mode to ignore time zones $nlsinternaltime = "classic" vdt_tz = vs_tz_datetime ; Calculate UTC offset vn_offset = vdt_tz - vdt_utc
With this routine, all date and time calculations can be managed accurately.
Open Source Time Zone Library
I created several functions to simplify working with time zones, which I’m sharing in an open-source library. The key functions include:
- `getISO8601Format`: Returns a date and time in ISO8601 format.
- Usage: `formatted_datetime = UEP_TIME::getISO8601Format(timezone, datetime, format)`
- `GetUTCOffset`: Provides the offset of a specified time zone relative to UTC, ideal for calculations.
- Usage: `offset_numeric = UEP_TIME::getUTCOffset(timezone, datetime)`
- `getUTCOffsetTxt`: Similar to `GetUTCOffset` but returns the offset as a displayable string.
Additional helper functions include `leftPad` and `rightPad` for string manipulation. These are available on GitLab, licensed under Apache 2.0, so you can use and contribute to this evolving project.
More about this opensource project can be found in the corresponding post about it: link to this project