Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #74192 > unrolled thread
| Started by | Francis Moreau <francis.moro@gmail.com> |
|---|---|
| First post | 2015-10-29 12:10 -0700 |
| Last post | 2015-10-30 09:06 -0700 |
| Articles | 5 — 2 participants |
Back to article view | Back to comp.lang.c
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
| From | Francis Moreau <francis.moro@gmail.com> |
|---|---|
| Date | 2015-10-29 12:10 -0700 |
| Subject | strftime(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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-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]
| From | Francis Moreau <francis.moro@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-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]
| From | Francis Moreau <francis.moro@gmail.com> |
|---|---|
| Date | 2015-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