Today, 2012-03-25, uClibc did not switch to DST even though glibc-based systems using the same TZ string did. root@busybox:~# TZ='EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00' date Sun Mar 25 10:15:39 EET 2012 root@debian:~# TZ='EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00' date Sun Mar 25 11:20:01 EEST 2012 -- I think the problem is related to the parsing of the M3.5.0 specifier, which means "last Sunday of March". That meaning of '5' is documented atleast here: http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html and it is necessary to properly specify the DST observed in eastern Europe. The bug is probably somewhere around here. Lines 700-702 seem to implement the functionality, but for some reason it is not working. http://git.uclibc.org/uClibc/tree/libc/misc/time/time.c#n685 -- Because the commands given in the beginning will stop working when time proceeds, use this command for testing: TZ='EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00' date -d '2012-03-25 12:00' +%Z When working correctly, it should print 'EEST' (Eastern European Summer Time). Busybox currently prints EET.
I observe the same issue with uclibc 0.9.30.1. It seems that due to some bug it expects that in March 2012 there will be at least an extra sunday (32th?) # TZ=CET-1CEST-2,M3.5.0/2,M10.5.0/3 date -d '2012-03-30 12:00' Fri Mar 30 12:00:00 CET 2012 # TZ=CET-1CEST-2,M3.5.0/2,M10.5.0/3 date -d '2012-03-31 12:00' Sat Mar 31 12:00:00 CET 2012 # TZ=CET-1CEST-2,M3.5.0/2,M10.5.0/3 date -d '2012-03-32 12:00' Sun Apr 1 12:00:00 CEST 2012 # TZ=CET-1CEST-2,M3.5.0/2,M10.5.0/3 date -d '2012-04-01 12:00' Sun Apr 1 12:00:00 CEST 2012 CEST begins on last sunday of March. There were 4 sundays in March, the last was on the 25th. I didn't find any timezone-related fixes in the change logs since 0.9.30.1.
(In reply to comment #0) > Today, 2012-03-25, uClibc did not switch to DST even though glibc-based systems > using the same TZ string did. > > root@busybox:~# TZ='EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00' date > Sun Mar 25 10:15:39 EET 2012 > > root@debian:~# TZ='EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00' date > Sun Mar 25 11:20:01 EEST 2012 This was fixed in 0.9.33: $ TZ='EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00' ./busybox \ -d '2012-03-25 12:00' +%Z EEST
(In reply to comment #1) > I observe the same issue with uclibc 0.9.30.1. > It seems that due to some bug it expects that in March 2012 there will be at > least an extra sunday (32th?) > > # TZ=CET-1CEST-2,M3.5.0/2,M10.5.0/3 date -d '2012-03-30 12:00' > Fri Mar 30 12:00:00 CET 2012 > # TZ=CET-1CEST-2,M3.5.0/2,M10.5.0/3 date -d '2012-03-31 12:00' > Sat Mar 31 12:00:00 CET 2012 > # TZ=CET-1CEST-2,M3.5.0/2,M10.5.0/3 date -d '2012-03-32 12:00' > Sun Apr 1 12:00:00 CEST 2012 > # TZ=CET-1CEST-2,M3.5.0/2,M10.5.0/3 date -d '2012-04-01 12:00' > Sun Apr 1 12:00:00 CEST 2012 > > CEST begins on last sunday of March. There were 4 sundays in March, the last > was on the 25th. > > I didn't find any timezone-related fixes in the change logs since 0.9.30.1. This was fixed in 0.9.33: $ TZ=CET-1CEST-2,M3.5.0/2,M10.5.0/3 ./date_uClibc '2012-03-30 12:00' '2012-03-31 12:00' '2012-03-32 12:00' '2012-04-01 12:00' Using TZ=CET-1CEST-2,M3.5.0/2,M10.5.0/3 '2012-03-30 12:00' -> '2012-03-30 12:00' '2012-03-31 12:00' -> '2012-03-31 12:00' '2012-03-32 12:00' -> '1900-01-?? 00:00' got INVALID date '2012-04-01 12:00' -> '2012-04-01 12:00' $ TZ=CET-1CEST-2,M3.5.0/2,M10.5.0/3 ./date_glibc '2012-03-30 12:00' '2012-03-31 12:00' '2012-03-32 12:00' '2012-04-01 12:00' Using TZ=CET-1CEST-2,M3.5.0/2,M10.5.0/3 '2012-03-30 12:00' -> '2012-03-30 12:00' '2012-03-31 12:00' -> '2012-03-31 12:00' '2012-03-32 12:00' -> '2012-03-00 00:00' got INVALID date '2012-04-01 12:00' -> '2012-04-01 12:00' $ cat date.c /* TZ=CET-1CEST-2,M3.5.0/2,M10.5.0/3 ./date '2012-03-31 12:00' '2012-03-32 12:00' */ #define _XOPEN_SOURCE #include <time.h> #include <stdlib.h> #include <string.h> #include <stdio.h> int main(int argc, char **argv) { struct tm tm; char buf[128]; const char * date_fmt = "%Y-%m-%d %H:%M"; char *chp; int ret = 0; if ((chp = getenv("TZ")) == NULL) return 2; printf("Using TZ=%s\n", chp); while (++argv && *argv) { memset(&tm, 0, sizeof(struct tm)); memset(&buf, 0, sizeof buf); chp = strptime(*argv, date_fmt, &tm); ret |= chp == NULL; /* invalid date */ strftime(buf, sizeof buf, date_fmt, &tm); printf("'%s' -> '%s'%s\n", *argv, buf, chp == NULL ? " got INVALID date" : ""); } return ret; }