Local Timezones for z/OS Applications

tpf
tcpip
wireshark
Author

Ian Worthington

Published

November 14, 2022

Controlling z/OS timezones for Language Environment applications

Target Audience

Anyone running applications under z/OS that use IBM Language Environment services and who needs customised control of timezone decoding on a per-job basis.

Introduction

The timezone displayed by a z/OS system, and the date and time when it moves from winter time to summer time, and back again, is controlled by a number of different parameters in different parts of the parmlibs structure, depending on exactly which function is called, and these, of course, have global effect.

You may, however, have a need for more localised control. This might be:

  • For testing of new definitions

  • For processing data requiring different timezone settings than your system defaults

  • For processing historical data which used different settings to those currently in effect

  • Because your systems’ settings are not correct and can’t be changed.

If any of the various proposed laws in the USA1 and EU2 ever come to fruition, this may become of some importance.

Indeed, running the IBM z/TPF IPTPRP IP Trace utility recently, I found I needed a different timezone definition to the one which was in effect on my system.

So what do you do if you need run an application using a different timezone, or summer time definition, from those used system wide?

First of all you need to determine which system services the application is calling to perform the decoding, which may require checking the source code. In my case, it was an IBM Language Environment function.

The actual format of the POSIX TZ parameter is well known, and fully documented, for example here. What is less clear is how this can be changed for a single application. It turns out that it is truly well buried in the IBM documentation, even more so than usual, but it can be done. There’s even two ways, both of them pretty straightforward.

In the PARMs

This is the simplest way. Just wrap the definition in an ENVAR(), and put it at the start of the PARMs, then separate it from the normal parameters for your program using a slash. Everything after the slash will be passed on to the program as usual, for example:

//XXXX  EXEC PGM=XXXX,
// PARM=('ENVAR("_TZ=CET-1CEST,M3.5.0/2,M10.5.0/3")',            
//             '/... normal parameters ...')  
// ...

You may have to use the environment variable TZ rather than _TZ depending on if your system is configured with POSIX(ON) or POSIX(OFF). If you’re not sure, ask your z/OS systems programmer, or just try and see which one works.

The gotcha here, of course, is that the total PARM field cannot exceed 100 bytes so, unless your program’s needs are rather simple, you’re likely to run out of room.

In a DD

The alternative is to put the ENVAR() in a CEEOPTS DD, which works just as well, and allows the full use of the 100 bytes PARM field. Here it is, inline:

//XXXX  EXEC PGM=XXXX
//CEEOPTS DD *                                                    
ENVAR("_TZ=CET-1CEST,M3.5.0/2,M10.5.0/3")                        
/*                                                               
//*  
// ...

Thanks

This article is based on work performed for SNCF, and is published with their permission, for which many thanks.

Author

Ian S. Worthington has over 25 years’ experience delivering solutions with high-volume, high-performance transaction processing systems using z/OS, z/TPF, ALCS, z/VM, and Linux on (and off) IBM Z. His customers have included IBM (three of ’em: US, UK, and India), British Airways, American Express, Associates Bancorp, and SNCF. He holds a BSc in Applied Physics, and an MSc in Database and Information Science, both from the University of London.

© 2022 Ian S. Worthington

Footnotes

  1. https://en.wikipedia.org/wiki/Permanent_time_observation_in_the_United_States↩︎

  2. https://en.wikipedia.org/wiki/Summer_time_in_Europe#Future↩︎