Setting the TZ Environment Variable on Linux
The Update Checklist for v2015.1 recommends setting the TZ environment variable on Linux platforms and points to the manpage for tzset. This is recommended to improve the performance of Cache’s time-related functions. You can find out more about this here:
https://community.intersystems.com/post/linux-tz-environment-variable-not-being-set-and-impact-caché
The manpage on my CentOS 7 test system (RHEL 6 says the same) has this to say:
“The tzset() function initializes the tzname variable from the TZ environment variable. This function is automatically called by the other time conversion functions that depend on the timezone.”
So how do you set TZ? How does it affect the time on a Linux server? Let’s see what we can learn:
The System Timezone --
For my test, I’m using Ensemble 2016.1 on a virtual CentOS system. First let’s check the system timezone. The system-config-date utility can show you.
What about “System clock uses UTC”? This refers to the server’s hardware clock. On a dedicated server, UTC is very common. When Linux is used in a dual-boot configuration with Windows, this is not the case (Windows uses local time for its system clock).
Since dual-boot configurations aren’t common for Cache’ and Ensemble installations, I won’t say more about this. The key ideas here are that the system timezone is set for the server’s timezone and that the hardware clock time is set correctly.
Time and Date Seen by Users –
Let’s take a look. Here’s a snippet from my Terminal session:
Looks OK. My shell process (running the date command) and my Cache’ process show the same time, except for a few seconds that I needed to type the WRITE command.
Setting the TZ variable --
Now let’s set TZ in the environment. The command to do this is tzselect. Here’s a typescript of the command output to set TZ
[ehemdal@localhost ~]$ tzselect Please identify a location so that time zone rules can be set correctly. Please select a continent or ocean. 1) Africa 2) Americas 3) Antarctica 4) Arctic Ocean 5) Asia 6) Atlantic Ocean 7) Australia 8) Europe 9) Indian Ocean 10) Pacific Ocean 11) none - I want to specify the time zone using the Posix TZ format. #? 2 Please select a country. 1) Anguilla 19) Dominican Republic 37) Peru 2) Antigua & Barbuda 20) Ecuador 38) Puerto Rico 3) Argentina 21) El Salvador 39) St Barthelemy 4) Aruba 22) French Guiana 40) St Kitts & Nevis 5) Bahamas 23) Greenland 41) St Lucia 6) Barbados 24) Grenada 42) St Maarten (Dutch) 7) Belize 25) Guadeloupe 43) St Martin (French) 8) Bolivia 26) Guatemala 44) St Pierre & Miquelon 9) Brazil 27) Guyana 45) St Vincent 10) Canada 28) Haiti 46) Suriname 11) Caribbean NL 29) Honduras 47) Trinidad & Tobago 12) Cayman Islands 30) Jamaica 48) Turks & Caicos Is 13) Chile 31) Martinique 49) United States 14) Colombia 32) Mexico 50) Uruguay 15) Costa Rica 33) Montserrat 51) Venezuela 16) Cuba 34) Nicaragua 52) Virgin Islands (UK) 17) Curacao 35) Panama 53) Virgin Islands (US) 18) Dominica 36) Paraguay #? 49 Please select one of the following time zone regions. 1) Eastern (most areas) 16) Central - ND (Morton rural) 2) Eastern - MI (most areas) 17) Central - ND (Mercer) 3) Eastern - KY (Louisville area) 18) Mountain (most areas) 4) Eastern - KY (Wayne) 19) Mountain - ID (south); OR (east) 5) Eastern - IN (most areas) 20) MST - Arizona (except Navajo) 6) Eastern - IN (Da, Du, K, Mn) 21) Pacific 7) Eastern - IN (Pulaski) 22) Alaska (most areas) 8) Eastern - IN (Crawford) 23) Alaska - Juneau area 9) Eastern - IN (Pike) 24) Alaska - Sitka area 10) Eastern - IN (Switzerland) 25) Alaska - Annette Island 11) Central (most areas) 26) Alaska - Yakutat 12) Central - IN (Perry) 27) Alaska (west) 13) Central - IN (Starke) 28) Aleutian Islands 14) Central - MI (Wisconsin border) 29) Hawaii 15) Central - ND (Oliver) #? 1 The following information has been given: United States Eastern (most areas) Therefore TZ='America/New_York' will be used. Local time is now: Tue May 31 11:21:04 EDT 2016. Universal Time is now: Tue May 31 15:21:04 UTC 2016. Is the above information OK? 1) Yes 2) No #? 1 You can make this change permanent for yourself by appending the line TZ='America/New_York'; export TZ to the file '.profile' in your home directory; then log out and log in again. Here is that TZ value again, this time on standard output so that you can use the /usr/bin/tzselect command in shell scripts: America/New_York [ehemdal@localhost ~]$
The file ~/.profile (if it exists) gets run when you log in and will set the TZ variable for you. You might use a different initialization file if you use a shell other than /bin/sh or /bin/bash. I set this and logged back in. If you update a file like /etc/profile, you can apply this for all users.
Here you can see that TZ is set for my user (ehemdal), but NOT for the root user.
TZ and the Time and Date Seen by Users –
What happens if a user is connected to your server from a different timezone? The TZ variable helps keep the user’s local time correct while keeping management of timezones and Daylight Saving Time in the hands of the operating system. This affects the time that Cache’ uses as well. For an example, I decided to change my timezone to that for Honolulu.
Here are two screenshots that show the result.
My user’s process has set TZ to Pacific/Honolulu. Root’s process does not have TZ set (so is using the system timezone America/New_York). At operating system level (with the date command), the display reflects local time for both users. The date command reflects the user’s local time (HST for user ehemdal and EDT for root). Since $HOROLOG obtains its value from the OS time available to the user process, the $H values are DIFFERENT for the two users.
I chose Honolulu time as an interesting example because Hawaii does not observe Daylight Saving Time. By setting TZ properly for all users, the local time can “spring ahead and fall back” for users who observe DST, and remain stable for users who don’t.