Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to convert timezone for format date string ? #764

Open
TomGarden opened this issue Dec 13, 2022 · 1 comment
Open

How to convert timezone for format date string ? #764

TomGarden opened this issue Dec 13, 2022 · 1 comment

Comments

@TomGarden
Copy link

TomGarden commented Dec 13, 2022

   I have one time string : `2022-12-13 10:32:06` . 
   I know  , the time string express the time of `Asia/Shanghai` timezone . 

   How to convert the time string to utc0 time date string : `2022-12-13 02:32:06` ?


   I know de-format date by `date::parse`
   I know format date by `date::format`

   how to convert timestamp(without timezone info) from one timezone to antoher timezone?
@HowardHinnant
Copy link
Owner

HowardHinnant commented Dec 13, 2022

#include "date/tz.h"
#include <chrono>
#include <iostream>
#include <sstream>

int
main()
{
    using namespace date;
    using namespace std;
    using namespace std::chrono;

    string input{"2022-12-13 10:32:06"};
    cout << input << '\n';
    istringstream in{std::move(input)};
    in.exceptions(ios::failbit);
    local_seconds ltp;
    in >> parse("%F %T", ltp);
    auto utp = locate_zone("Asia/Shanghai")->to_sys(ltp);
    string output = format("%F %T", utp);
    cout << output << '\n';
}

In a nutshell, the input is local_time. And one can use the time_zone "Asia/Shanghai" to transform it into sys_time (which is a close approximation to UTC). Then you can format the sys_time however you want.

This program outputs:

2022-12-13 10:32:06
2022-12-13 02:32:06

An alternative to:

    auto utp = locate_zone("Asia/Shanghai")->to_sys(ltp);

is:

    auto utp = zoned_time{"Asia/Shanghai", ltp}.get_sys_time();

They are both equivalent. zoned_time is just a pair of {time_zone*, time point}. The zoned_time constructor calls locate_zone and to_sys for you. In this example, one is about as good as the other. In other examples direct use of the time_zone is simpler, or the use of zoned_time is simpler. In the end, zoned_time is a simple wrapper around {time_zone*, time point} to enable some higher-level code to have simpler syntax.

A key point to observe in this example is that the input is parsed into a local_time type. This detail is what enables the type-safe transformation of the local time in "Asia/Shanghai" to sys_time.

In the event that the "other time zone" is not UTC, for example "America/New_York", then the use of zoned_time makes the syntax simpler:

    local_seconds ltp;
    in >> parse("%F %T", ltp);
    auto Stp = zoned_time{"Asia/Shanghai", ltp};
    auto Ntp = zoned_time{"America/New_York", Stp};
    string output = format("%F %T", Ntp);

Output:

2022-12-13 10:32:06
2022-12-12 21:32:06

One can construct one zoned_time from another and the invariant is that the two zoned_times will point to the same UTC time_point.

One could do this at the time_zone level, but the syntax would be slightly messier.

    local_seconds ltp;
    in >> parse("%F %T", ltp);
    auto utp = locate_zone("Asia/Shanghai")->to_sys(ltp);
    auto Ntp = locate_zone("America/New_York")->to_local(utp);
    string output = format("%F %T", Ntp);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants