Search code examples
c++c++-chrono

chrono usage wirh timezone


I have a duration as string e.g. "13:00:00" and a time_point parsed to a utc_time from an UTC time string using std::chrono::parse function.

Now given this duration and a timezone e.g. "America/New_York". How to compare my time_point to today duration as time point using UTC as common timezone. The documentation tz of cppreference chrono is not yet completed.


Solution

  • I've attempted to add extra verbose comments so that no further explanation is needed:

    #include <chrono>
    #include <iostream>
    #include <sstream>
    
    int
    main()
    {
        using namespace std;
        using namespace chrono;
    
        // Inputs
        
        // duration as string
        string tod_s = "13:00:00";
        // Some utc_time from UTC string
        utc_seconds tp_utc = floor<seconds>(clock_cast<utc_clock>(system_clock::now()) + 6h);
        // Some time zone
        string tz_s = "America/New_York";
    
        // Compare today's midnight in time zone + duration against utc_time
    
        // Convert tod_s to duration
        istringstream in{tod_s};
        in.exceptions(ios::failbit);
        seconds tod;
        in >> parse("%T", tod);
    
        // Get pointer to time_zone
        auto tz = locate_zone(tz_s);
    
        // Get local midnight of today
        auto local_mid = floor<days>(tz->to_local(system_clock::now()));
        // Add duration to get local time point
        auto tp_local = local_mid + tod;
    
        // Convert local time to sys_time, and then to utc_time
        auto tp = clock_cast<utc_clock>(tz->to_sys(tp_local));
    
        // Compare tp and tp_utc
        bool b = tp > tp_utc;
    }
    

    A comment though: You might want to use sys_time in place of utc_time. sys_time is what computers normally traffic in. utc_time adds leap seconds to it. You really only want to do this when you know that you need the leap seconds in. This is typically for spacecraft or astronomical applications.

    To change to using sys_time, simply remove the clock_cast to utc_time at the last step.