Amit Garg
Amit Garg

Reputation: 59

How to get diffreence between GMT time and any time zone in C++

I want a soultion in C++ to get hours diffreence between GMT time and any time zone. e.g. This is in Java I want to make in C++

// New York
Calendar c = new GregorianCalendar(TimeZone.getTimeZone("America/New_York"));  

// Alaska  
c = new GregorianCalendar(TimeZone.getTimeZone("America/Anchorage"));
// Difference between New York and Alaska  

Please tell me how I can get this time zone in C++

Upvotes: 0

Views: 612

Answers (2)

Howard Hinnant
Howard Hinnant

Reputation: 218750

I've been staring at Greg's good answer for a few days now, and am contemplating adding some syntax sugar to my timezone library:

namespace date
{

class zoneverter
{
    const Zone* zp1_;
    const Zone* zp2_;

public:
    zoneverter(const Zone* z1, const Zone* z2)
        : zp1_(z1)
        , zp2_(z2)
        {}

    zoneverter(const Zone* z1, const std::string& z2)
        : zoneverter(z1, locate_zone(z2))
        {}

    zoneverter(const std::string& z1, const Zone* z2)
        : zoneverter(locate_zone(z1), z2)
        {}

    zoneverter(const std::string& z1, const std::string& z2)
        : zoneverter(locate_zone(z1), locate_zone(z2))
        {}

    template <class Rep, class Period>
    auto
    operator<<(std::chrono::time_point<std::chrono::system_clock,
                                       std::chrono::duration<Rep, Period>> tp) const
    {
        return zp1_->to_local(zp2_->to_sys(tp)).first;
    }
};

}  // namespace date

This adds a "streaming-like-object" which allows one to stream a std::chrono::time_point through it to convert it from one timezone to another. It is a very simple device, which does nothing but add some syntax sugar, at the expense of dropping some information, from my timezone library.

It would be used like this:

int
main()
{
    // So things don't get overly verbose
    using namespace date;
    using namespace std::chrono;

    // Set up the zone converters:
    zoneverter nyc_from_utc{"America/New_York",  "UTC"};
    zoneverter anc_from_nyc{"America/Anchorage", "America/New_York"};

    // Get the current time in New York and convert that to the current time in Anchorage
    auto now_nyc = nyc_from_utc << system_clock::now();
    auto now_anc = anc_from_nyc << now_nyc;

    // Output the difference
    std::cout << make_time(now_nyc - now_anc) << '\n';
}

This currently outputs for me:

04:00:00.000000

I'm also unsure if this syntax sugar is sufficiently better than the current syntax to warrant its existence:

int
main()
{
    // So things don't get overly verbose
    using namespace date;
    using namespace std::chrono;

    // Set up the zones:
    auto nyc_zone = locate_zone("America/New_York");
    auto anc_zone = locate_zone("America/Anchorage");

    // Get the current time in New York and the current time in Anchorage
    auto now_utc = system_clock::now();
    auto now_nyc = nyc_zone->to_local(now_utc).first;
    auto now_anc = anc_zone->to_local(now_utc).first;

    // Output the difference
    std::cout << make_time(now_nyc - now_anc) << '\n';
}

Upvotes: 1

Greg Miller
Greg Miller

Reputation: 96

You can use the cctz library to calculate the difference in UTC offset between two different time zones at some specific time.

#include <chrono>
#include "cctz.h"
using namespace std::chrono;

cctz::TimeZone nyc;
cctz::LoadTimeZone("America/New_York", &nyc);

cctz::TimeZone anc;
cctz::LoadTimeZone("America/Anchorage", &anc);

const auto now = system_clock::now();
const auto nyc_off = cctz::BreakTime(now, nyc).offset;
const auto anc_off = cctz::BreakTime(now, anc).offset;

const auto off_diff = nyc_off - anc_off;

Now, the truth is that you really don't want to do that. Really. Healthy, modern code should never (did I say never, because I meant never) care about UTC offsets. Computing with UTC offsets is the job of your time zone library, and if your time zone library doesn't handle that for you, then you're using the wrong time zone library. If you think you care about UTC offsets, then I encourage you to look into the following:

  • Read CCTZ's Fundamental Concepts section on its github page
  • Watch Time Programming Fundamentals from CppCon 2015
  • Read the cctz.h header file (it's short and simple)

[Disclaimer: I'm an author of cctz.]

Upvotes: 2

Related Questions