Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #74192 > unrolled thread

strftime(3) and TZ

Started byFrancis Moreau <francis.moro@gmail.com>
First post2015-10-29 12:10 -0700
Last post2015-10-30 09:06 -0700
Articles 5 — 2 participants

Back to article view | Back to comp.lang.c


Contents

  strftime(3) and TZ Francis Moreau <francis.moro@gmail.com> - 2015-10-29 12:10 -0700
    Re: strftime(3) and TZ Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-29 19:53 +0000
      Re: strftime(3) and TZ Francis Moreau <francis.moro@gmail.com> - 2015-10-30 00:26 -0700
        Re: strftime(3) and TZ Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-30 11:19 +0000
          Re: strftime(3) and TZ Francis Moreau <francis.moro@gmail.com> - 2015-10-30 09:06 -0700

#74192 — strftime(3) and TZ

FromFrancis Moreau <francis.moro@gmail.com>
Date2015-10-29 12:10 -0700
Subjectstrftime(3) and TZ
Message-ID<fac11cd6-ef06-4481-8e80-ab8a0a686628@googlegroups.com>
Hello,

I'm probably missing something but can'f find what.

So my question is: strftime(3) isnt supposed to read TZ and to display time according to its value ?

From the manpage:

   ENVIRONMENT
          The environment variables TZ and LC_TIME are used.

But I cant verify it with my dumb prog:

$ cat strftime.c
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
    char outstr[200];
    time_t t;
    struct tm tmp = {
	    .tm_sec = 2,
	    .tm_min = 54,
	    .tm_hour = 19,
	    .tm_mday = 29,
	    .tm_mon = 9,
	    .tm_year = 115,
	    .tm_wday = 4,
	    .tm_yday = 301,
	    .tm_isdst = 0,
	    .tm_gmtoff = 3600,
	    .tm_zone = "CET",
    };

    if (strftime(outstr, sizeof(outstr), argv[1], &tmp) == 0) {
        fprintf(stderr, "strftime returned 0");
        exit(EXIT_FAILURE);
    }

    printf("Result string is \"%s\"\n", outstr);
    exit(EXIT_SUCCESS);
}

$ TZ='Europe/Paris' /tmp/strftime "%T %Z"
Result string is "19:54:02 CET"
$ TZ='UTC' /tmp/strftime "%T %Z"
Result string is "19:54:02 CET"

Thanks

[toc] | [next] | [standalone]


#74199

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-10-29 19:53 +0000
Message-ID<87bnbhh2nv.fsf@bsb.me.uk>
In reply to#74192
Francis Moreau <francis.moro@gmail.com> writes:

> I'm probably missing something but can'f find what.
>
> So my question is: strftime(3) isnt supposed to read TZ and to display
> time according to its value ?
>
> From the manpage:
>
>    ENVIRONMENT
>           The environment variables TZ and LC_TIME are used.

But does it say that they will override an explicit setting?  I would
hope they would not (and they don't).

> But I cant verify it with my dumb prog:
>
> $ cat strftime.c
> #include <time.h>
> #include <stdio.h>
> #include <stdlib.h>
>
> int
> main(int argc, char *argv[])
> {
>     char outstr[200];
>     time_t t;
>     struct tm tmp = {
> 	    .tm_sec = 2,
> 	    .tm_min = 54,
> 	    .tm_hour = 19,
> 	    .tm_mday = 29,
> 	    .tm_mon = 9,
> 	    .tm_year = 115,
> 	    .tm_wday = 4,
> 	    .tm_yday = 301,
> 	    .tm_isdst = 0,
> 	    .tm_gmtoff = 3600,
> 	    .tm_zone = "CET",

These last two are not standard C, and they don't even seem to be
standard POSIX extensions (I've not checked all versions) but they are,
I think, the root of the problem.  If you don't set them, the code works
as you want.

>     };
>
>     if (strftime(outstr, sizeof(outstr), argv[1], &tmp) == 0) {
>         fprintf(stderr, "strftime returned 0");
>         exit(EXIT_FAILURE);
>     }
>
>     printf("Result string is \"%s\"\n", outstr);
>     exit(EXIT_SUCCESS);
> }

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#74232

FromFrancis Moreau <francis.moro@gmail.com>
Date2015-10-30 00:26 -0700
Message-ID<f64aa962-7623-4186-bdc3-e0130d11180c@googlegroups.com>
In reply to#74199
Le jeudi 29 octobre 2015 20:53:51 UTC+1, Ben Bacarisse a écrit :
> Francis Moreau <francis.moro@gmail.com> writes:
> 
> > I'm probably missing something but can'f find what.
> >
> > So my question is: strftime(3) isnt supposed to read TZ and to display
> > time according to its value ?
> >
> > From the manpage:
> >
> >    ENVIRONMENT
> >           The environment variables TZ and LC_TIME are used.
> 
> But does it say that they will override an explicit setting?  I would
> hope they would not (and they don't).
> 
> > But I cant verify it with my dumb prog:
> >
> > $ cat strftime.c
> > #include <time.h>
> > #include <stdio.h>
> > #include <stdlib.h>
> >
> > int
> > main(int argc, char *argv[])
> > {
> >     char outstr[200];
> >     time_t t;
> >     struct tm tmp = {
> > 	    .tm_sec = 2,
> > 	    .tm_min = 54,
> > 	    .tm_hour = 19,
> > 	    .tm_mday = 29,
> > 	    .tm_mon = 9,
> > 	    .tm_year = 115,
> > 	    .tm_wday = 4,
> > 	    .tm_yday = 301,
> > 	    .tm_isdst = 0,
> > 	    .tm_gmtoff = 3600,
> > 	    .tm_zone = "CET",
> 
> These last two are not standard C, and they don't even seem to be
> standard POSIX extensions (I've not checked all versions) but they are,
> I think, the root of the problem.  If you don't set them, the code works
> as you want.

From the manpage of mktime(3):

       The glibc version of struct tm has additional fields

              long tm_gmtoff;           /* Seconds east of UTC */
              const char *tm_zone;      /* Timezone abbreviation */

       defined when _BSD_SOURCE was set before including <time.h>.  This is a
       BSD extension, present in 4.3BSD-Reno.

So you're right those fields are not standard C nor POSIX.

I actually set them because I thought that strftime(3) could automatically modify the time given by tm struct if a different timezone was specified in TZ than the one given by the extra fields (tm_zone, ...).

Another strange point is that LC_TIME isn't took into account too:

$ LC_TIME=fr_FR /tmp/strftime "%a %T %Z"
Thu 19:54:02 CET

which is not correct: 'Thu' should be 'jeu.'

And yes the french locale is installed on my system.

Thanks.

[toc] | [prev] | [next] | [standalone]


#74270

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-10-30 11:19 +0000
Message-ID<877fm4fvt4.fsf@bsb.me.uk>
In reply to#74232
Francis Moreau <francis.moro@gmail.com> writes:

> Le jeudi 29 octobre 2015 20:53:51 UTC+1, Ben Bacarisse a écrit :
>> Francis Moreau <francis.moro@gmail.com> writes:
>> 
>> > I'm probably missing something but can'f find what.
>> >
>> > So my question is: strftime(3) isnt supposed to read TZ and to display
>> > time according to its value ?
>> >
>> > From the manpage:
>> >
>> >    ENVIRONMENT
>> >           The environment variables TZ and LC_TIME are used.
>> 
>> But does it say that they will override an explicit setting?  I would
>> hope they would not (and they don't).
>> 
>> > But I cant verify it with my dumb prog:
>> >
>> > $ cat strftime.c
>> > #include <time.h>
>> > #include <stdio.h>
>> > #include <stdlib.h>
>> >
>> > int
>> > main(int argc, char *argv[])
>> > {
>> >     char outstr[200];
>> >     time_t t;
>> >     struct tm tmp = {
>> > 	    .tm_sec = 2,
>> > 	    .tm_min = 54,
>> > 	    .tm_hour = 19,
>> > 	    .tm_mday = 29,
>> > 	    .tm_mon = 9,
>> > 	    .tm_year = 115,
>> > 	    .tm_wday = 4,
>> > 	    .tm_yday = 301,
>> > 	    .tm_isdst = 0,
>> > 	    .tm_gmtoff = 3600,
>> > 	    .tm_zone = "CET",
>> 
>> These last two are not standard C, and they don't even seem to be
>> standard POSIX extensions (I've not checked all versions) but they are,
>> I think, the root of the problem.  If you don't set them, the code works
>> as you want.
>
> From the manpage of mktime(3):
>
>        The glibc version of struct tm has additional fields
>
>               long tm_gmtoff;           /* Seconds east of UTC */
>               const char *tm_zone;      /* Timezone abbreviation */
>
>        defined when _BSD_SOURCE was set before including <time.h>.  This is a
>        BSD extension, present in 4.3BSD-Reno.
>
> So you're right those fields are not standard C nor POSIX.
>
> I actually set them because I thought that strftime(3) could
> automatically modify the time given by tm struct if a different
> timezone was specified in TZ than the one given by the extra fields
> (tm_zone, ...).

The documentation is not very clear but I would not expect an
environment variable to override an explicit setting.  you were
surprised because you though it would.

> Another strange point is that LC_TIME isn't took into account too:
>
> $ LC_TIME=fr_FR /tmp/strftime "%a %T %Z"
> Thu 19:54:02 CET
>
> which is not correct: 'Thu' should be 'jeu.'

The local documentation is not clear, I agree.  You need to set the
locale for the environment by calling:

  setlocale(LC_ALL, "");

first (include <locale.h> of course).

It's actually clearer in the C standard which explicitly states that
programs execute as if a call to

  setlocale(LC_ALL, "C");

had been made at startup.  The text "Thu" is required from %a in the "C"
locale.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#74331

FromFrancis Moreau <francis.moro@gmail.com>
Date2015-10-30 09:06 -0700
Message-ID<03858145-6837-4ce6-9c87-56782fa7622d@googlegroups.com>
In reply to#74270
Le vendredi 30 octobre 2015 12:19:28 UTC+1, Ben Bacarisse a écrit :
> Francis Moreau <francis.moro@gmail.com> writes:
> 
> > Le jeudi 29 octobre 2015 20:53:51 UTC+1, Ben Bacarisse a écrit :
> >> Francis Moreau <francis.moro@gmail.com> writes:
> >> 
> >> > I'm probably missing something but can'f find what.
> >> >
> >> > So my question is: strftime(3) isnt supposed to read TZ and to display
> >> > time according to its value ?
> >> >
> >> > From the manpage:
> >> >
> >> >    ENVIRONMENT
> >> >           The environment variables TZ and LC_TIME are used.
> >> 
> >> But does it say that they will override an explicit setting?  I would
> >> hope they would not (and they don't).
> >> 
> >> > But I cant verify it with my dumb prog:
> >> >
> >> > $ cat strftime.c
> >> > #include <time.h>
> >> > #include <stdio.h>
> >> > #include <stdlib.h>
> >> >
> >> > int
> >> > main(int argc, char *argv[])
> >> > {
> >> >     char outstr[200];
> >> >     time_t t;
> >> >     struct tm tmp = {
> >> > 	    .tm_sec = 2,
> >> > 	    .tm_min = 54,
> >> > 	    .tm_hour = 19,
> >> > 	    .tm_mday = 29,
> >> > 	    .tm_mon = 9,
> >> > 	    .tm_year = 115,
> >> > 	    .tm_wday = 4,
> >> > 	    .tm_yday = 301,
> >> > 	    .tm_isdst = 0,
> >> > 	    .tm_gmtoff = 3600,
> >> > 	    .tm_zone = "CET",
> >> 
> >> These last two are not standard C, and they don't even seem to be
> >> standard POSIX extensions (I've not checked all versions) but they are,
> >> I think, the root of the problem.  If you don't set them, the code works
> >> as you want.
> >
> > From the manpage of mktime(3):
> >
> >        The glibc version of struct tm has additional fields
> >
> >               long tm_gmtoff;           /* Seconds east of UTC */
> >               const char *tm_zone;      /* Timezone abbreviation */
> >
> >        defined when _BSD_SOURCE was set before including <time.h>.  This is a
> >        BSD extension, present in 4.3BSD-Reno.
> >
> > So you're right those fields are not standard C nor POSIX.
> >
> > I actually set them because I thought that strftime(3) could
> > automatically modify the time given by tm struct if a different
> > timezone was specified in TZ than the one given by the extra fields
> > (tm_zone, ...).
> 
> The documentation is not very clear but I would not expect an
> environment variable to override an explicit setting.  you were
> surprised because you though it would.
> 

Indeed. I was influenced by the behaviour of date(1) somehow.

> > Another strange point is that LC_TIME isn't took into account too:
> >
> > $ LC_TIME=fr_FR /tmp/strftime "%a %T %Z"
> > Thu 19:54:02 CET
> >
> > which is not correct: 'Thu' should be 'jeu.'
> 
> The local documentation is not clear, I agree.  You need to set the
> locale for the environment by calling:
> 
>   setlocale(LC_ALL, "");
> 
> first (include <locale.h> of course).
> 
> It's actually clearer in the C standard which explicitly states that
> programs execute as if a call to
> 
>   setlocale(LC_ALL, "C");
> 
> had been made at startup.  The text "Thu" is required from %a in the "C"
> locale.
> 

I see thanks.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web