* Converting time from timezone string to another timezone time
@ 2021-01-29 8:11 Jeffrey Walton
2021-02-02 14:33 ` Jeffrey Walton
2021-02-02 18:23 ` Adhemerval Zanella
0 siblings, 2 replies; 3+ messages in thread
From: Jeffrey Walton @ 2021-01-29 8:11 UTC (permalink / raw)
To: libc-help
Hi Everyone,
I'm having a heck of a time converting a time from a timezone string
to another timezone time. The best I seem to be able to do is adjust
for DST using strptime, mktime and localtime. For example:
* given: '15 Jan 2021 01:24:55 -0800 (PST)'
* expected: '15 Jan 2021 04:24:55 -0500 (EST)' (or similar, as long
as it includes 04:24:55)
* my best result: '15 Jan 00:24:55 2021' (seems to be a DST adj of PST time)
I've been through the manual at
https://www.gnu.org/software/libc/manual/html_node/Calendar-Time.html
but I can't seem to find the sequence of calls to perform the actions.
I've also been through the libc FAQ at
https://sourceware.org/glibc/wiki/FAQ (there's one topic on
timezones).
So I have two questions, but I only need one answered (whichever is
easier to answer):
1. Where is the discussion/faq on how to convert from timezone string
to another timezone time?
2. What is wrong with this code (error checking omitted)?
const char pst_timestring[] = '15 Jan 2021 01:24:55 -0800 (PST)';
struct tm gmail_tm[1];
strptime(pst_timestring, "%d %b %Y %T %z", gmail_tm);
// Already set, but just in case. It is -0500 (EST)
char my_timezone[] = "TZ=America/New_York";
putenv(my_timezone);
time_t utc_time;
utc_time = mktime(gmail_tm);
struct tm local_tm[1];
local_tm = localtime(&utc_time);
// This prints a time that was adjusted by 1 hour, not 3 hours
(expected from -0800 to -0500)
printf(..., asctime(local_tm));
// Output is similar to '15 Jan 00:24:55 2021'
Somewhere there is a non-obvious problem with the code stitched
together from the man pages.
Thanks in advance.
Jeff
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Converting time from timezone string to another timezone time
2021-01-29 8:11 Converting time from timezone string to another timezone time Jeffrey Walton
@ 2021-02-02 14:33 ` Jeffrey Walton
2021-02-02 18:23 ` Adhemerval Zanella
1 sibling, 0 replies; 3+ messages in thread
From: Jeffrey Walton @ 2021-02-02 14:33 UTC (permalink / raw)
To: libc-help
On Fri, Jan 29, 2021 at 3:11 AM Jeffrey Walton <noloader@gmail.com> wrote:
>
> Hi Everyone,
>
> I'm having a heck of a time converting a time from a timezone string
> to another timezone time. The best I seem to be able to do is adjust
> for DST using strptime, mktime and localtime. For example:
>
> * given: '15 Jan 2021 01:24:55 -0800 (PST)'
> * expected: '15 Jan 2021 04:24:55 -0500 (EST)' (or similar, as long
> as it includes 04:24:55)
> * my best result: '15 Jan 00:24:55 2021' (seems to be a DST adj of PST time)
>
> I've been through the manual at
> https://www.gnu.org/software/libc/manual/html_node/Calendar-Time.html
> but I can't seem to find the sequence of calls to perform the actions.
> I've also been through the libc FAQ at
> https://sourceware.org/glibc/wiki/FAQ (there's one topic on
> timezones).
>
> So I have two questions, but I only need one answered (whichever is
> easier to answer):
>
> 1. Where is the discussion/faq on how to convert from timezone string
> to another timezone time?
>
> 2. What is wrong with this code (error checking omitted)?
>
> const char pst_timestring[] = '15 Jan 2021 01:24:55 -0800 (PST)';
> struct tm gmail_tm[1];
> strptime(pst_timestring, "%d %b %Y %T %z", gmail_tm);
>
> // Already set, but just in case. It is -0500 (EST)
> char my_timezone[] = "TZ=America/New_York";
> putenv(my_timezone);
>
> time_t utc_time;
> utc_time = mktime(gmail_tm);
>
> struct tm local_tm[1];
> local_tm = localtime(&utc_time);
>
> // This prints a time that was adjusted by 1 hour, not 3 hours
> (expected from -0800 to -0500)
> printf(..., asctime(local_tm));
> // Output is similar to '15 Jan 00:24:55 2021'
>
> Somewhere there is a non-obvious problem with the code stitched
> together from the man pages.
Ping...
Does anyone know why libc can't seem to do this simple task?
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Converting time from timezone string to another timezone time
2021-01-29 8:11 Converting time from timezone string to another timezone time Jeffrey Walton
2021-02-02 14:33 ` Jeffrey Walton
@ 2021-02-02 18:23 ` Adhemerval Zanella
1 sibling, 0 replies; 3+ messages in thread
From: Adhemerval Zanella @ 2021-02-02 18:23 UTC (permalink / raw)
To: noloader, libc-help
On 29/01/2021 05:11, Jeffrey Walton via Libc-help wrote:
> Hi Everyone,
>
> I'm having a heck of a time converting a time from a timezone string
> to another timezone time. The best I seem to be able to do is adjust
> for DST using strptime, mktime and localtime. For example:
>
> * given: '15 Jan 2021 01:24:55 -0800 (PST)'
> * expected: '15 Jan 2021 04:24:55 -0500 (EST)' (or similar, as long
> as it includes 04:24:55)
> * my best result: '15 Jan 00:24:55 2021' (seems to be a DST adj of PST time)
>
> I've been through the manual at
> https://www.gnu.org/software/libc/manual/html_node/Calendar-Time.html
> but I can't seem to find the sequence of calls to perform the actions.
> I've also been through the libc FAQ at
> https://sourceware.org/glibc/wiki/FAQ (there's one topic on
> timezones).
>
> So I have two questions, but I only need one answered (whichever is
> easier to answer):
>
> 1. Where is the discussion/faq on how to convert from timezone string
> to another timezone time?
>
> 2. What is wrong with this code (error checking omitted)?
>
> const char pst_timestring[] = '15 Jan 2021 01:24:55 -0800 (PST)';
> struct tm gmail_tm[1];
> strptime(pst_timestring, "%d %b %Y %T %z", gmail_tm);
>
> // Already set, but just in case. It is -0500 (EST)
> char my_timezone[] = "TZ=America/New_York";
> putenv(my_timezone);
>
> time_t utc_time;
> utc_time = mktime(gmail_tm);
>
> struct tm local_tm[1];
> local_tm = localtime(&utc_time);
>
> // This prints a time that was adjusted by 1 hour, not 3 hours
> (expected from -0800 to -0500)
> printf(..., asctime(local_tm));
> // Output is similar to '15 Jan 00:24:55 2021'
>
> Somewhere there is a non-obvious problem with the code stitched
> together from the man pages.
>
I think what you might like is something like:
---
$ cat test.c
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
static void
set_tz (const char *tz)
{
char buf[128];
snprintf (buf, sizeof (buf), "TZ=%s", tz);
putenv (buf);
tzset ();
}
static struct tm
convert_time (const char *origtm, const char *dsttm, const char *timestr)
{
struct tm tm, ttm;
set_tz (origtm);
strptime (timestr, "%d %b %Y %T", &tm);
time_t t = mktime (&tm);
set_tz (dsttm);
localtime_r (&t, &ttm);
return ttm;
}
int main (int argc, char *argv[])
{
const char timestr[] = "15 Jan 2021 01:24:55";
const char origtm[] = "Europe/Berlin";
const char dsttm[] = "America/New_York";
struct tm tm = convert_time (origtm, dsttm, timestr);
char buffer[256];
strftime (buffer, sizeof (buffer), "%d %b %Y %T", &tm);
printf ("%s: %s\n%s: %s\n",
origtm, timestr,
dsttm, buffer);
return 0;
}
$ gcc -D_GNU_SOURCE test.c && ./a.out
Europe/Berlin: 15 Jan 2021 01:24:55
America/New_York: 14 Jan 2021 23:24:55
---
AFAIK there is not easy way to accomplish it without setting the current TZ,
create a struct tm, getting a canonical UNIX time_t from it, reset TZ, and
convert. Also keep in mind this has some corner cases regarding thread safety,
and I am not sure if plays well on every input and timezones.
The coreutils date command uses a different strategy, where it uses the
gnulib parse-datetime module [1]. It does something as:
char const *tzstring = getenv ("TZ");
timezone_t tz = tzalloc (tzstring);
[...]
parse_datetime2 (&when, datestr, NULL, parse_datetime_flags, tz, tzstring);
show_date (format, when, tz);
And parse_datetime2 does all the magic internally. It also seems to be
thread-safe and do not require messing with TZ environment variable.
[1] https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/parse-datetime.y;h=b8a832fcd8f70a0df7b6104e1bacc4e0495bf01f;hb=HEAD
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-02-02 18:23 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-29 8:11 Converting time from timezone string to another timezone time Jeffrey Walton
2021-02-02 14:33 ` Jeffrey Walton
2021-02-02 18:23 ` Adhemerval Zanella
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).