TZ, localtime and strftime problem on AIX and Solaris


 
Thread Tools Search this Thread
Top Forums Programming TZ, localtime and strftime problem on AIX and Solaris
# 1  
Old 04-26-2013
TZ, localtime and strftime problem on AIX and Solaris

Hello all,
I have the following code that seems to be misbehaving depending on the timezone setting (TZ Environment variable). It gives the correct value when TZ is in POSIX format and the wrong value when in OLSON format.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <memory.h>
int main()
{
    long secs;
    char timeString[20];
    struct tm timeHolder;
    for(secs=0; secs < 3610; secs++)
    {
        localtime_r((const time_t *) &secs, (struct tm *) &timeHolder);
        memset( timeString, 0, sizeof( timeString));
        strftime( timeString, sizeof( timeString), "%H:%M:%S\0", &timeHolder);
        printf("Secs: %d\t\t\tTime: %s\n", secs, timeString);
    }
}

I compile and link this as follows:

gcc -o timeprob.exe timeprob.c

The run below is on AIX 6.1 (oslevel -r gives 6100-05). Same happens on Solaris 10.

date
Fri Apr 26 16:44:25 BST 2013

date -u
Fri Apr 26 15:44:38 GMT 2013

So currently we are 1 hour ahead of GMT with Daylight Savings in operation.

1] First with POSIX format TZ:

echo $TZ
GMT0BST,M3.5.0,M10.5.0

./timeprob.exe
<snip>
Secs: 3599 Time: 00:59:59
Secs: 3600 Time: 01:00:00
Secs: 3601 Time: 01:00:01
<snip>

ie. at 3600 secs from epoch the time shows correctly as 1 hour from epoch.

2] Next with OLSON format TZ:

echo $TZ
Europe/London

./timeprob.exe
<snip>
Secs: 3599 Time: 01:59:59
Secs: 3600 Time: 02:00:00
Secs: 3601 Time: 02:00:01
<snip>



ie. at 3600 secs from epoch the time shows wrongly as 2 hours from epoch.
  • 'date' from Unix prompt shows the date correctly with/without DST.
  • When there is no DST both format work correctly.
Any idea what the problem could be? I would expect both POSIX and OLSON formats should give the same output ie. either both should say 1 hour from epoch or both should say 2 hours from epoch.
The libc.a function used is that which comes with AIX 6.1.

Any help appreciated.

Regards

Last edited by biju64; 04-26-2013 at 02:05 PM..
# 2  
Old 04-29-2013
Can you post the output of the following command...
Code:
ls -la /usr/share/lib/zoneinfo/Europe

# 3  
Old 04-29-2013
I ran your code. The reason is because in 1970 daylight savings did not work the way it does now. I edited you code and added a %c to the format string + more space in the output string:
This is what I get with Mountain/Denver TZ on Solaris:

Secs: 3599 Time: Wed Dec 31 17:59:59 1969 17:59:59
Secs: 3600 Time: Wed Dec 31 18:00:00 1969 18:00:00
Secs: 3601 Time: Wed Dec 31 18:00:01 1969 18:00:01

FYI: DST does not work in winter in London, and most countries including North America had odd ball timezone settings way back then, if they even had it. I could go on. Your long variables "secs" should also be a time_t. Try starting with:

Code:
secs=1367265312

and count forward from there.
# 4  
Old 04-30-2013
Quote:
Originally Posted by shamrock
Can you post the output of the following command...
Code:
ls -la /usr/share/lib/zoneinfo/Europe

Thanks for replying.
You may have found the problem (partially)...

On our AIX machine, the 'Europe' folder does not exist.
However we have a file called GB-Eire under the /usr/share/lib/zoneinfo directory.

When I set TZ to GB-Eire, I get the correct output (ie. same output as when I set TZ to Posix format GMT0BST,M3.5.0,M10.5.0)

I changed the strftime and the timeString variables as follows:
Code:
 char timeString[30];
strftime( timeString, sizeof( timeString), "%d-%b-%Y %H:%M:%S", &timeHolder);

<snip>
Secs: 3599 Time: 01-Jan-1970 00:59:59
Secs: 3600 Time: 01-Jan-1970 01:00:00
Secs: 3601 Time: 01-Jan-1970 01:00:01
<snip>

But on our Solaris machine, we have the 'Europe/London' folder and file, a GB file and a GB-Eire file. Setting TZ to any of these does not work. All give:

<snip>
Secs: 3599 Time: 01-Jan-1970 01:59:59
Secs: 3600 Time: 01-Jan-1970 02:00:00
Secs: 3601 Time: 01-Jan-1970 02:00:01
<snip>

Which is different from what I get when I set TZ to Posix format : GMT0BST,M3.5.0,M10.5.0

<snip>
Secs: 3599 Time: 01-Jan-1970 00:59:59
Secs: 3600 Time: 01-Jan-1970 01:00:00
Secs: 3601 Time: 01-Jan-1970 01:00:01
<snip>

Strange...so it looks like it might work correctly when I get the 'Europe/London' file under zoneinfo folder on AIX (will need to test this)...but not sure why it does not work on Solaris.

---------- Post updated at 01:45 PM ---------- Previous update was at 01:09 PM ----------

Quote:
Originally Posted by jim mcnamara
I ran your code. The reason is because in 1970 daylight savings did not work the way it does now. I edited you code and added a %c to the format string + more space in the output string:
This is what I get with Mountain/Denver TZ on Solaris:

Secs: 3599 Time: Wed Dec 31 17:59:59 1969 17:59:59
Secs: 3600 Time: Wed Dec 31 18:00:00 1969 18:00:00
Secs: 3601 Time: Wed Dec 31 18:00:01 1969 18:00:01

FYI: DST does not work in winter in London, and most countries including North America had odd ball timezone settings way back then, if they even had it. I could go on. Your long variables "secs" should also be a time_t. Try starting with:

Code:
secs=1367265312

and count forward from there.
Thanks for replying.
I agree that the DST does not apply in winter in London. But I would expect that if I set TZ in Posix (GMT0BST,M3.5.0,M10.5.0) or Olson (Europe/London) formats, I should get the same output (this is on Solaris where I have the '/usr/share/lib/zoneinfo/Europe/London' file).

When I try starting at 1367275312 onwards it does match. But then these are when DST is ON and it always works correctly (as in both posix/olson outputs match) when DST is ON. Same when I set to 8598706 (when DST is ON and in the 1970s):

Secs: 8598706 Time: 10-Apr-1970 13:31:46

On both formats, I get the same answer.

So the problem exists only when DST is off and looking at my reply to 'Shamrock' above, maybe only on Solaris (as AIX seems to work for GB, EB-Eire and if I have 'Europe/London' may work too).
# 5  
Old 04-30-2013
Summer Time Act 1972

IANA ? Time Zone Database

Have a look. DST onset changes over time. If you want to test timezones, use now, not way back when. Or look at the source for those timezone files you are using. The IANA link. It is in human readable text.
This User Gave Thanks to jim mcnamara For This Post:
# 6  
Old 04-30-2013
Quote:
Originally Posted by biju64
But on our Solaris machine, we have the 'Europe/London' folder and file, a GB file and a GB-Eire file. Setting TZ to any of these does not work. All give:

<snip>
Secs: 3599 Time: 01-Jan-1970 01:59:59
Secs: 3600 Time: 01-Jan-1970 02:00:00
Secs: 3601 Time: 01-Jan-1970 02:00:01
<snip>

Which is different from what I get when I set TZ to Posix format : GMT0BST,M3.5.0,M10.5.0

<snip>
Secs: 3599 Time: 01-Jan-1970 00:59:59
Secs: 3600 Time: 01-Jan-1970 01:00:00
Secs: 3601 Time: 01-Jan-1970 01:00:01
<snip>

Strange...so it looks like it might work correctly when I get the 'Europe/London' file under zoneinfo folder on AIX (will need to test this)...but not sure why it does not work on Solaris.
Not sure why it doesnt work on Solaris...I can only talk about AIX as that is the machine I use. However you can try to get the latest timezone patch for your Solaris machine. Btw what is the os version for your Solaris box and compare the outputs of the following commands on AIX and Solaris and see if there is any difference which might hint at a timezone patch...
Code:
zdump -vc 1970 GB
zdump -vc 1970 GB-Eire
zdump -vc 1970 Europe/London

Obviously you cant run the last command on AIX as it doesnt have the Europe/London timezone info file but post the outputs of those commands here so all can look and suggest a solution...
This User Gave Thanks to shamrock For This Post:
# 7  
Old 05-10-2013
Thank you both.
That seems to be the problem - mystery solved - and both were correct !

Under OLSON format the TZ depends on the data in /usr/share/lib/zoneinfo and under POSIX format we specify the DST details directly and so it does not depend on anything else.

Using zdump -vc to dump the zoneinfo database shows that there are gaps in the data stored w.r.t. DST for different years.
Specifically in the cases where the above code does not work the data for 1970 is missing.

We have another AIX machine where Europe/London was available but details for 1970 is missing and so the code gives the wrong output:

zdump -vc 1970 Europe/London
<snip>
Europe/London Sun Oct 29 02:00:00 1967 UTC = Sun Oct 29 02:00:00 1967 GMT isdst=0
Europe/London Sun Feb 18 01:59:59 1968 UTC = Sun Feb 18 01:59:59 1968 GMT isdst=0
Europe/London Sun Feb 18 02:00:00 1968 UTC = Sun Feb 18 03:00:00 1968 BST isdst=1
Europe/London Sat Oct 26 22:59:59 1968 UTC = Sat Oct 26 23:59:59 1968 BST isdst=1
Europe/London Sat Oct 26 23:00:00 1968 UTC = Sun Oct 27 00:00:00 1968 BST isdst=0
Europe/London Mon Jan 18 03:14:07 2038 UTC = Mon Jan 18 03:14:07 2038 GMT isdst=0
Europe/London Tue Jan 19 03:14:07 2038 UTC = Tue Jan 19 03:14:07 2038 GMT isdst=0
<snip>

And where the data is available (and correct), the code gives the right output.

So the moral of the story is :
1) Using Posix format is reliable and to be preferred
2) If using Olson format check the zoneinfo database using zdump and if the data for the year is there and correct all is well. Otherwise first ensure that the zoneinfo database is corrected.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Help on awk strftime

cat file 41285.000034722223 41285.000567129631 41285.000069444446 41285.001122685186 41285.000092592592 41285.001620370371 41285.000138888892 41285.00340277778 41285.000185185185 41285.000405092593 41285.000196759262 41285.000856481478 41285.000208333331 41285.000717592593... (5 Replies)
Discussion started by: phpshell
5 Replies

2. Shell Programming and Scripting

How to use a variable in perl localtime()?

Hi all, a=$1 ## b=`echo "86400 * $a"|bc` `perl -e 'use POSIX qw(strftime);$now_string = strftime "%d/%m/%Y", localtime(time-$b); print $now_string,"\n";' > date_file` but im always getting current date; can any one suggest me any the improvement the above works fine if i use some thing... (2 Replies)
Discussion started by: zozoo
2 Replies

3. Shell Programming and Scripting

Perl help LocalTime in New Format

Hi, I'm new to perl scripting and am trying it out. I have a file written in the following format: myfile-MMDDYY where MM is the number of the Month; DD the Day and YY the last two of the year... (Apologies for dumbing this down; I'm trying to be clear). There is a new file put onto my... (2 Replies)
Discussion started by: Astrocloud
2 Replies

4. Programming

strftime equivalent in c++

HI, i wish to convert a millsec value to a readable string format. the one option is to use strftime. However this is a bit costly (1-5 micros). is there a a faster way to do so with just string manipulation (Note i have the date object which has the time details but wish o avoid strftime) (2 Replies)
Discussion started by: wojtyla
2 Replies

5. Shell Programming and Scripting

date with perl localtime

Hi Experts, I know how to handle normal date changes in perl. Most of my requirement are full filled with following: $date1 = strftime "%Y%m%d",localtime; $date2 = strftime "%Y%m%d",localtime(time -24 * 60 * 60); $date3 = strftime "%Y%m%d",localtime(time +24 * 60 * 60); $date4 = strftime... (4 Replies)
Discussion started by: mtomar
4 Replies

6. Shell Programming and Scripting

PERL localtime Warning

Hello All, I am facing a warning "Argument "" isn't numeric in localtime at" what i m using is below my $timestamp = Timestamp(time); go_log("###############$timestamp###############"); can some one please suggest the way to avoid this message :confused: (6 Replies)
Discussion started by: NIMISH AGARWAL
6 Replies

7. Shell Programming and Scripting

gawk and strftime()

Strange behaviour of the strftime() function from gawk (3.1.5): $ awk 'BEGIN{print strftime("%T", 3600)}' > 02:00:00 $ awk 'BEGIN{print strftime("%T", 0)}' > 01:00:00 Obviously something with DST but I can not figure out why? To me 3600 epoch seconds remains 01:00, DST or not. From... (2 Replies)
Discussion started by: ripat
2 Replies

8. Solaris

AIX & Solaris 10 problem

I have this command in my script and it's working fine with AIX: ls init?*.ora 2>/dev/null | egrep -i -e "" the same command is failing in Solaris 10. does anyone have better idea how to make it work for both ? Thanks (1 Reply)
Discussion started by: talashil
1 Replies

9. UNIX for Advanced & Expert Users

converting localtime to unixtime

hi, how to convert the localtime to unixtime? i have date from the date command in unix i want to convert it into unixtime thnx (2 Replies)
Discussion started by: AshishK
2 Replies

10. Shell Programming and Scripting

Perl + localtime()

ok here is a perl date question not asked befor. i know i am feeling small for not knowing. BUT!!!! $ENV{TZ}="US/Central"; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(); how can i do the addition to year so i can get the current year w/o going $ntime=$year+1900;... (3 Replies)
Discussion started by: Optimus_P
3 Replies
Login or Register to Ask a Question