HowardHinnant / date

A date and time library based on the C++11/14/17 <chrono> header
Other
3.07k stars 669 forks source link

Given UTC datetime and IANA region, how do I get time zone offset? #789

Closed cjc93 closed 11 months ago

cjc93 commented 11 months ago

Given a string with UTC datetime format and a string with IANA region, how do I get time zone offset (taking daylight saving into consideration)?

Example 1: Input: UTC string: "2021-12-07 13:38:00.335000-5:00" IANA region string: "America/New_York"

Desired Output: -5

Example 2: Input: UTC string: "2021-12-07 13:38:00.335000-5:00" IANA region string: "Europe/London"

Desired Output: 0

Example 3: Input: UTC string: "2022-06-16 13:38:00.335000-04:00" IANA region string: "America/New_York"

Desired Output: -4

Example 4: Input: UTC string: "2022-06-16 13:38:00.335000-04:00" IANA region string: "Europe/London"

Desired Output: 1

HowardHinnant commented 11 months ago

Parse the UTC string into a system_clock::time_point:

    string utc_string =  "2021-12-07 13:38:00.335000-5:00";
    istringstream is{utc_string};
    system_clock::time_point tp;
    is >> parse("%F %T%Ez", tp);

This reads the local time, applies the -05:00 offset to it, and fills that in as a UTC time stamp in tp.

You can then locate the time zone and get all of the information about that time zone at that time_point:

    string iana_region = "America/New_York";
    auto tz = locate_zone(iana_region);

    auto info = tz->get_info(tp);
    auto offset = info.offset;
    cout << offset << '\n';
    cout << offset/1h << '\n';

One piece of the information is the UTC offset. There is also other information here: http://eel.is/c++draft/time.zone.info.sys

The offset is in terms of seconds, but if you want to extract the integral number of hours out of that (as a scalar) you can divide by 1 hour. This outputs:

-18000s
-5
cjc93 commented 11 months ago

Thanks!