2

Getting current date/time in C++ is already known and answered.

Goal

Get date/time in specific time zone. Meaning, different users in different time zones, running my app at the same time, will get the same result.

Note

  1. For simplicity, assume the specific time zone is Eastern Time Zone.
  2. App will be running in windows environment ONLY.
  3. Native solutions are preferred (non boost etc.)

I've read Getting current time of a different timezone using C++. Non of the answers seems to solve my issue. perhaps I don't fully understand the use of SystemTimeToTzSpecificLocalTime. If I call GetTimeZoneInformation with some argument to specify the desired time zone, that will get me a bit further.

Community
  • 1
  • 1
idanshmu
  • 5,061
  • 6
  • 46
  • 92

3 Answers3

0

If you are using a windows environment, you can use SystemTimeToTzSpecificLocalTime function. It converts the time in UTC to the specified time zone's local time.

idanshmu
  • 5,061
  • 6
  • 46
  • 92
Pooja Nilangekar
  • 1,419
  • 13
  • 20
0

This was a fun exercise. The only part I can't figure out is how to set the Time Zone on std::tm*. Is it some kind of global variable?

#include <ctime>
#include <iomanip>
#include <iostream>

inline const int EST_diff(const bool is_DST)
{
    if (is_DST < 0)
        std::cout << "Erorr! No DST Information available!" << std::endl;    

    if (is_DST)
        return 4;
    else
        return 5;
}

inline const bool try_rollback(int& time)
{
    if (time > 1)
    {
        time -= 1;
        return true;
    }
    else
        return false;
}

inline int leapyear(const std::tm *const time)
{
    return time->tm_year % 4 == 0 ? 1 : 0;
}

inline int back_one(int& time, const int increment)
{
    return time = time > 1 ? time - 1 : time + increment - 1;
}

inline int advance_hours(int& time, const int difference)
{
    return time += 24 - difference;
}

inline int days_in_month(const int month, const bool leapyear)
{
    switch(month)
    {
    case 0: //january
        return 31;
    case 1: //february
        return leapyear ? 29 : 28;
    case 2: //march
        return 31;
    case 3: //april
        return 30;
    case 4: //may
        return 31;
    case 5: //june
        return 30;
    case 6: //july
        return 31;
    case 7: //august
        return 31;
    case 8: //september
        return 30;
    case 9: //october
        return 31;
    case 10:    //november
        return 30;
    case 11:    //december
        return 31;
    default:
        std::cout << "Input error in days_in_month!" << std::endl;
        break;
    }

    return -1;
}

inline std::tm* rollback_week(std::tm *const time)
{
    back_one(time->tm_wday, 7);
    advance_hours(time->tm_hour, EST_diff(time->tm_isdst));
    return time;
}

inline std::tm* rollback_month(std::tm *const time)
{
    back_one(time->tm_mon, 12);
    back_one(time->tm_mday, days_in_month(time->tm_mon, leapyear(time)));
    return rollback_week(time);
}

inline std::tm* rollback_year(std::tm *const time)
{
    time->tm_year -= 1;
    time->tm_yday += 364 + leapyear(time);
    return rollback_month(time);
}

inline std::tm* UTC_to_EST(std::tm *const time)
{
    if (time->tm_hour > EST_diff(time->tm_isdst))
        time->tm_hour -= EST_diff(time->tm_isdst);
    else
    {
        if (!try_rollback(time->tm_yday))
            rollback_year(time);
        else if(!try_rollback(time->tm_mday))
            rollback_month(time);
        else if(!try_rollback(time->tm_wday))
            rollback_week(time);
    }
    return time;
}

int main()
{
    std::time_t t = std::time(NULL);
    std::tm* time(std::gmtime(&t));
    std::cout << "UTC: " << std::put_time(time, "%c %Z") << '\n';
    std::cout << "EST: " << std::put_time(UTC_to_EST(time), "%c %Z") << '\n';
    std::cout << "Daylight Savings Time is " << (std::gmtime(&t)->tm_isdst < 0 ? "invalid" : (std::gmtime(&t)->tm_isdst > 0 ? "active" : "inactive")) << std::endl;
}

Live On Coliru

caps
  • 1,225
  • 14
  • 24
0

Assuming you speak only of Windows and that you only want users in different time zones to get the same result if they request the time simultaneously, but don't care about the specific time zone, the answer is simple: GetSystemTime().

It gives you the UTC time, regardless of timezone.

conio
  • 3,681
  • 1
  • 20
  • 34