Calculating the UTC offset in your SAS session


Update 25Nov2010: I've updated this example to correct the code so that it works correctly for positive UTC offsets. Thanks to Bruno Müller, my colleague at SAS, for finding my mistakes.

One of my SAS colleagues was recently working on a project where she had to create reports that include the UTC offset encoded into the report. The UTC offset is that part of your computer time zone notation that indicates how far off the local time is from "Coordinated Universal Time" (which, in practice, is the same as Greenwich Mean Time). For example, I live on the east coast of USA, which puts me in UTC -05:00. My colleagues in Sydney, Australia are in UTC +11:00 at the moment (since they are enjoying their daylight savings time).

Prior to SAS 9.2, gathering this information required that you use some type of shell command to get the UTC offset value from your host machine (using systeminfo on Windows or date -u on Unix). But with SAS 9.2, you can use the new E8601LZ format to help calculate the correct value in a platform-independent way. (This SAS format is part of a group of formats and informats that support ISO 8601 date and time notations.)

There is also an undocumented function, gmtoff(), which returns the raw number for the offset in seconds. Even though the function is not documented, it does appear in some examples on I don't feel that I'm revealing too many secrets by sharing it with you.

Update: SAS 9.4 now has an official version of this function, named TZONEOFF(). GMTOFF() still works for now as well, still undocumented. Adjust your future SAS programs accordingly.

Here is a SAS program example that calculates the UTC offset for the machine that hosts your SAS session:

data _null_;
     utc_offset_display $ 7
     utc_offset 8;
  /* E8601LZ formats as a UTC value and converts to a local time */
  utc_offset_display=substr( put('00:00:00't,E8601LZ.), 9);
  utc_offset=gmtoff()/3600; /* undocumented */
  call symput('utc_offset',utc_offset);
  call symput('utc_offset_display',utc_offset_display);
%put &utc_offset_display;
%put &utc_offset;

When I run this on my machines in Cary, NC, the output log looks like this:

27         %put &utc_offset_display;
28         %put &utc_offset;

Special thanks to one of my colleagues in SAS Japan, Shin Kayano, who is one of our software globalization experts. He's the one who pointed me to this method of using the E8601LZ format.

Update: you can achieve the same result in SAS 9.1.3, but the format name was IS8601LZ instead of E8601LZ. In SAS 9.1.3, these formats were added mainly in support of the XML LIBNAME engine.


About Author

Chris Hemedinger

Director, SAS User Engagement

+Chris Hemedinger is the Director of SAS User Engagement, which includes our SAS Communities and SAS User Groups. Since 1993, Chris has worked for SAS as an author, a software developer, an R&D manager and a consultant. Inexplicably, Chris is still coasting on the limited fame he earned as an author of SAS For Dummies


  1. Yes, it should work, but I guess it depends on what you want. Do you want to know the official offset for your timezone, or do you want the value difference as adjusted for daylight savings?

    Here is another program that Bruno provided to me, and it does the math using the ISO 8601 formats.

    data work.utc_orig;
      /** E8601LZ reads a UTC value and converts to a local time **/
      currentTime = time();
      timeTC = put( currentTime, e8601LZ.);
      timeLocal = put( currentTime, e8601TZ.);
      timeTC_SAS = input( timeTC, e8601LZ.);
      timeLocal_SAS = input( timeLocal, e8601TZ.);
      utcOffsetCalc = timeLocal_SAS - timeTC_SAS;
      utcOffsetFunc = gmtoff();
      putlog (_all_) (=/);
        timeTC_SAS timeLocal_SAS time12.3
  2. Pingback: Making up for lost time (UTC vs. DST) - The SAS Dummy

  3. newport light on

    Yesterday, while I was at work, my cousin stole my iPad and tested to see if it can survive a forty foot drop, just so she can be a youtube sensation. My iPad is now broken and she has 83 views. I know this is entirely off topic but I had to share it with someone!

    • Chris Hemedinger
      Chris Hemedinger on

      Ms. Light, I'm so glad that I could be your sounding board. Anytime that you need somebody to talk to about your crazy consumer electronics shenanigans, I'm right here.

      P.S. Smoke'm if you got'em.

  4. Pingback: Converting from Unix epoch to SAS datetime

  5. Pingback: Read a Microsoft datetime value into a SAS datetime value - The SAS Dummy

  6. Pingback: How to convert a Unix datetime to a SAS datetime - The SAS Dummy

Back to Top