public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* Re: Time zone bug
       [not found] ` <590670ec.5b119d0a.2fbc1.6460@mx.google.com>
@ 2017-05-01 15:25   ` cyg Simple
  2017-05-01 17:25     ` Brian Inglis
  0 siblings, 1 reply; 2+ messages in thread
From: cyg Simple @ 2017-05-01 15:25 UTC (permalink / raw)
  To: cygwin

On 4/30/2017 7:19 PM, Steven Penny wrote:
> On Sun, 30 Apr 2017 17:37:00, Ken Brown wrote:
>> As a result of a failing emacs test, I came across the following:
>>
>> $ TZ='NZST-12NZDT,M9.5.0,M4.1.0/3' date -d@0 +'%Y-%m-%d %H:%M:%S %z (%Z)'
>> 1970-01-01 12:00:00 +1200 (NZST)
>>
>> The same command on Linux yields "1970-01-01 13:00:00 +1300 (NZDT)",
>> which is
>> correct according to Paul Eggert
>> (https://lists.gnu.org/archive/html/emacs-devel/2017-04/msg00881.html).
> 
> I concur, here is non-esoteric example Linux:
> 
>    $ TZ=Pacific/Auckland date +%Z
>    NZST
> 
>    $ TZ=NZST date +%Z
>    NZST
> 
>    $ TZ=NZDT date +%Z
>    NZDT
> 
> Cygwin:
> 
>    $ TZ=Pacific/Auckland date +%Z
>    NZST
> 
>    $ TZ=NZST date +%Z
>    GMT
> 
>    $ TZ=NZDT date +%Z
>    GMT

The TZ value doesn't matter.

$ TZ=America/New_York date +%Z
EDT

$ TZ=EDT date +%Z
GMT

-- 
cyg Simple

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Time zone bug
  2017-05-01 15:25   ` Time zone bug cyg Simple
@ 2017-05-01 17:25     ` Brian Inglis
  0 siblings, 0 replies; 2+ messages in thread
From: Brian Inglis @ 2017-05-01 17:25 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 2219 bytes --]

On 2017-05-01 09:25, cyg Simple wrote:
> On 4/30/2017 7:19 PM, Steven Penny wrote:
>> On Sun, 30 Apr 2017 17:37:00, Ken Brown wrote:
>>> As a result of a failing emacs test, I came across the following:
>>>
>>> $ TZ='NZST-12NZDT,M9.5.0,M4.1.0/3' date -d@0 +'%Y-%m-%d %H:%M:%S %z (%Z)'
>>> 1970-01-01 12:00:00 +1200 (NZST)
>>>
>>> The same command on Linux yields "1970-01-01 13:00:00 +1300 (NZDT)",
>>> which is
>>> correct according to Paul Eggert
>>> (https://lists.gnu.org/archive/html/emacs-devel/2017-04/msg00881.html).

This may be a problem in: 

	winsup/cygwin/localtime.cc

not properly handling POSIX time zone specs in the S hemisphere, with DST 
which starts in autumn/fall and ends in spring, at the start of the time_t 
epoch, where the first DST transition happens with negative time_t. 

Neither localtime nor mktime on Cygwin properly handle these rules where 
both localtime and mktime on Linux do - STC and sdiff attached. 

On Linux, even if you comment out the localtime call, mktime sets the 
offset correctly; on Cygwin even using localtime and mktime fails to set 
the offset at 1970-01-01 correctly. 

Cygwin awk strftime also shows the same issue where Linux is also correct.

>> I concur, here is non-esoteric example Linux:
>>    $ TZ=Pacific/Auckland date +%Z
>>    NZST
>>    $ TZ=NZST date +%Z
>>    NZST
>>    $ TZ=NZDT date +%Z
>>    NZDT
>> Cygwin:
>>    $ TZ=Pacific/Auckland date +%Z
>>    NZST
>>    $ TZ=NZST date +%Z
>>    GMT
>>    $ TZ=NZDT date +%Z
>>    GMT

This is just a slight difference in handling POSIX time zone specs 
with no explicit offset specified - the basic format is std offset. 
If you provide only a std abbr with no offset, Cygwin defaults to 
GMT, where Linux uses the abbr and sets the offset to zero. Both 
behave identically if you specify a +-offset:

$ TZ=XXX date +"%F %a %R%z(%Z)"; TZ=XXX0 date +"%F %a %R%z(%Z)"
2017-05-01 Mon 17:13+0000(GMT)
2017-05-01 Mon 17:13+0000(XXX)
$ ssh ... 'TZ=XXX date +"%F %a %R%z(%Z)"; TZ=XXX0 date +"%F %a %R%z(%Z)"'
2017-05-01 Mon 17:13+0000(XXX)
2017-05-01 Mon 17:13+0000(XXX)

depends whether you prefer to see the same answer or the smart answer ;^>

-- 
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada

[-- Attachment #2: local-mktime-z-stc-diff.txt --]
[-- Type: text/plain, Size: 2656 bytes --]

NZST-12NZDT,M9.5.0,M4.1.0/3			NZST-12NZDT,M9.5.0,M4.1.0/3

1970-01-01 001 4   00:00+0000s(GMT)	gm	1970-01-01 001 4   00:00+0000s(GMT)	gm
1970-01-01 001 4   13:00+1300d(NZDT)	local |	1970-01-01 001 4   12:00+1200s(NZST)	local
1970-01-01 001 4   13:00+1300d(NZDT)	mk    |	1970-01-01 001 4   12:00+1200s(NZST)	mk
1970-01-01 001 Thu 13:00+1300 (NZDT)	      |	1970-01-01 001 Thu 12:00+1200 (NZST)

1970-04-04 094 6   13:00+0000s(GMT)	gm	1970-04-04 094 6   13:00+0000s(GMT)	gm
1970-04-05 095 0   02:00+1300d(NZDT)	local |	1970-04-05 095 0   01:00+1200s(NZST)	local
1970-04-05 095 0   02:00+1300d(NZDT)	mk    |	1970-04-05 095 0   01:00+1200s(NZST)	mk
1970-04-05 095 Sun 02:00+1300 (NZDT)	      |	1970-04-05 095 Sun 01:00+1200 (NZST)

1970-04-04 094 6   14:00+0000s(GMT)	gm	1970-04-04 094 6   14:00+0000s(GMT)	gm
1970-04-05 095 0   02:00+1200s(NZST)	local	1970-04-05 095 0   02:00+1200s(NZST)	local
1970-04-05 095 0   02:00+1200s(NZST)	mk	1970-04-05 095 0   02:00+1200s(NZST)	mk
1970-04-05 095 Sun 02:00+1200 (NZST)		1970-04-05 095 Sun 02:00+1200 (NZST)

1970-09-26 269 6   13:00+0000s(GMT)	gm	1970-09-26 269 6   13:00+0000s(GMT)	gm
1970-09-27 270 0   01:00+1200s(NZST)	local	1970-09-27 270 0   01:00+1200s(NZST)	local
1970-09-27 270 0   01:00+1200s(NZST)	mk	1970-09-27 270 0   01:00+1200s(NZST)	mk
1970-09-27 270 Sun 01:00+1200 (NZST)		1970-09-27 270 Sun 01:00+1200 (NZST)

1970-09-26 269 6   14:00+0000s(GMT)	gm	1970-09-26 269 6   14:00+0000s(GMT)	gm
1970-09-27 270 0   03:00+1300d(NZDT)	local	1970-09-27 270 0   03:00+1300d(NZDT)	local
1970-09-27 270 0   03:00+1300d(NZDT)	mk	1970-09-27 270 0   03:00+1300d(NZDT)	mk
1970-09-27 270 Sun 03:00+1300 (NZDT)		1970-09-27 270 Sun 03:00+1300 (NZDT)

1971-01-01 001 5   00:00+0000s(GMT)	gm	1971-01-01 001 5   00:00+0000s(GMT)	gm
1971-01-01 001 5   13:00+1300d(NZDT)	local	1971-01-01 001 5   13:00+1300d(NZDT)	local
1971-01-01 001 5   13:00+1300d(NZDT)	mk	1971-01-01 001 5   13:00+1300d(NZDT)	mk
1971-01-01 001 Fri 13:00+1300 (NZDT)		1971-01-01 001 Fri 13:00+1300 (NZDT)

1971-04-03 093 6   13:00+0000s(GMT)	gm	1971-04-03 093 6   13:00+0000s(GMT)	gm
1971-04-04 094 0   02:00+1300d(NZDT)	local	1971-04-04 094 0   02:00+1300d(NZDT)	local
1971-04-04 094 0   02:00+1300d(NZDT)	mk	1971-04-04 094 0   02:00+1300d(NZDT)	mk
1971-04-04 094 Sun 02:00+1300 (NZDT)		1971-04-04 094 Sun 02:00+1300 (NZDT)

1971-04-03 093 6   14:00+0000s(GMT)	gm	1971-04-03 093 6   14:00+0000s(GMT)	gm
1971-04-04 094 0   02:00+1200s(NZST)	local	1971-04-04 094 0   02:00+1200s(NZST)	local
1971-04-04 094 0   02:00+1200s(NZST)	mk	1971-04-04 094 0   02:00+1200s(NZST)	mk
1971-04-04 094 Sun 02:00+1200 (NZST)		1971-04-04 094 Sun 02:00+1200 (NZST)

0						0

[-- Attachment #3: local-mktime-z-stc.c --]
[-- Type: text/plain, Size: 2361 bytes --]

/* newlib/libc/time/strftime.c %z format STC */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define TZ	"TZ=NZST-12NZDT,M9.5.0,M4.1.0/3"
#define DFMT	"%04d-%02d-%02d %03d %-3d %02d:%02d%+03ld00%s(%s)\t%s\n" //:%02d
#define TFMT	"%F %j %a %R%z (%Z)"

#define EPOCH	1970
#define YADD	1900
#define MADD	 1
#define DADD	 1
#define YR_MTH	12
#define MTH_DAY	30
#define DAY_HR	24
#define HR_MIN	60
#define MIN_S	60
#define HR_S	(HR_MIN*MIN_S)

/* extra is total days over 30 in preceding months - net total 5/year */
#define S(extra,yr,mth,day,hr)	\
	((((((yr) - EPOCH)*YR_MTH + ((mth) - 1))*MTH_DAY + (extra) + (day) - 1)\
		*DAY_HR + (hr))*HR_S)


int
dump( struct tm* tp, char *label) {
    return printf( DFMT, tp->tm_year + YADD, tp->tm_mon + MADD, tp->tm_mday,
		tp->tm_yday + DADD, tp->tm_wday,
		tp->tm_hour, tp->tm_min,			// tp->tm_sec,
# ifdef __TM_GMTOFF
		tp->__TM_GMTOFF/HR_S,
# elif  __USE_BSD
		tp->tm_gmtoff/HR_S,
# else
		tp->__tm_gmtoff/HR_S,
# endif
		tp->tm_isdst < 0 ? "?" : tp->tm_isdst ? "d" : "s",
# ifdef __TM_ZONE
		tp->__TM_ZONE,
# elif  __USE_BSD
		tp->tm_zone,
# else
		tp->__tm_zone,
# endif
		label
	  	);
}


int
test( time_t tt ) {
    char	ss[BUFSIZ]	= "";
    struct tm *	tp;
    size_t	st;
    int		rc;

    if (EOF == (rc = puts( "" )))			return 5;
    if (!(tp = gmtime( &tt )))				return 1;
    if ((rc = dump( tp, "gm" )) <= 0)			return -rc;
    if (!(tp = localtime( &tt )))			return 2;
    if ((rc = dump( tp, "local" )) <= 0)		return -rc;
    if (-1 == (tt = mktime( tp )))			return 3;
    if ((rc = dump( tp, "mk" )) <= 0)			return -rc;
    if ((st = strftime( ss, sizeof ss, TFMT, tp)) <= 0)	return 4;
    if (EOF == (rc = puts( ss )))			return 5;

    return 0;
}


int
main( void ) {
    int	rc;

    if ((rc = putenv( TZ )))			return rc;
    if (EOF == (rc = puts( getenv( "TZ" ))))	return 6;
    /*		   extra  year  m day hour	*/
    if ((rc = test( S( 0, 1970, 1,  1,  0))))	return rc;
    if ((rc = test( S( 0, 1970, 4,  4, 13))))	return rc;
    if ((rc = test( S( 0, 1970, 4,  4, 14))))	return rc;
    if ((rc = test( S( 3, 1970, 9, 26, 13))))	return rc;
    if ((rc = test( S( 3, 1970, 9, 26, 14))))	return rc;
    if ((rc = test( S( 5, 1971, 1,  1,  0))))	return rc;
    if ((rc = test( S( 5, 1971, 4,  3, 13))))	return rc;
    if ((rc = test( S( 5, 1971, 4,  3, 14))))	return rc;

    return rc;
}


[-- Attachment #4: Type: text/plain, Size: 219 bytes --]


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2017-05-01 17:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <31d25ae6-b4f1-54cf-5582-810eeedcd8d3@cornell.edu>
     [not found] ` <590670ec.5b119d0a.2fbc1.6460@mx.google.com>
2017-05-01 15:25   ` Time zone bug cyg Simple
2017-05-01 17:25     ` Brian Inglis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).