1

System is in UTC, Is there a way to get a local time of a specific timezone?

Most windows api's return values based on system time.

If there is any api where we could pass the timezone indication and get the localtime?

Also, read different api's windows provides, and thought this one : "EnumDynamicTimeZoneInformation"

could be of use to me, but i cant get this to run, i see a undefined identifier error. error C3861: 'EnumDynamicTimeZoneInformation': identifier not found

Included windows.h as mentioned in this link: https://learn.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-enumdynamictimezoneinformation?redirectedfrom=MSDN

On getting info from the above api, i can try passing the same to :

SystemTimeToTzSpecificLocalTime

and hoping that would do it. Can anyone suggest what i'm missing.

Trying this on VS2010

File: time.cpp

#ifndef WINVER             
#define WINVER 0x0602      
#endif

#ifndef _WIN32_WINNT       
#define _WIN32_WINNT 0x0602
#endif

#include <windows.h>
#include<time.h>
#include<iostream>

int main(){
    DYNAMIC_TIME_ZONE_INFORMATION d_tz;
    memset(&d_tz,0,sizeof(d_tz));
    DWORD res=0;
    res = EnumDynamicTimeZoneInformation(1, &d_tz);//fetch specific timezone info

    /*Use this next*/
    //SystemTimeToTzSpecificLocalTime();

    return 0;
}
Sash
  • 45
  • 7
  • What is ur target Windows version? `EnumDynamicTimeZoneInformation` has only been supported since Windows 8. – Sprite Feb 02 '21 at 08:50
  • Windows server2012. could see from the link that this version is supported – Sash Feb 02 '21 at 08:51
  • Could you paste some codes you have tried so far? – Sprite Feb 02 '21 at 08:53
  • Did you include the `` header? – Sprite Feb 02 '21 at 08:59
  • windows.h is required from the description, thats included – Sash Feb 02 '21 at 09:01
  • Starting with C++20 there's [std::chrono::zoned_time](https://en.cppreference.com/w/cpp/chrono/zoned_time). Though probably not available in a compiler that's more than a decade old. – IInspectable Feb 02 '21 at 09:02
  • yeah! but no use in this case – Sash Feb 02 '21 at 09:04
  • 2
    According to the documentation, [EnumDynamicTimeZoneInformation](https://learn.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-enumdynamictimezoneinformation) is available starting with Windows 8. To make it visible to the compiler, you're going to have to set your minimum target version to `_WIN32_WINNT_WIN8` (0x0602). See [Using the Windows Headers](https://learn.microsoft.com/en-us/windows/win32/winprog/using-the-windows-headers) for details. – IInspectable Feb 02 '21 at 09:13
  • Thanks! will try that, but don't think will be able to proceed with that. – Sash Feb 02 '21 at 09:43
  • have to figure out a way using api's available – Sash Feb 02 '21 at 09:43
  • You already know the answer to that: The SDK headers are feature-gated by a preprocessor macro that defines the minimum supported target OS. – IInspectable Feb 02 '21 at 10:05
  • added this at the top of the file: #ifndef WINVER #define WINVER 0x0602 #endif #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0602 #endif anything missing here? – Sash Feb 02 '21 at 10:20
  • We don't know what *"the file"* means to you. That may or may not be correct. Although it's generally desirable to control preprocessor macros through the command line. – IInspectable Feb 02 '21 at 10:56
  • this is a separate test project created, nothing else in there only this one file with above code. ideally, this should work, right? – Sash Feb 02 '21 at 11:19
  • if you lookup TIME_ZONE_INFORMATION on msdn it says that "settings for each time zone are stored in the registry". So you can read the TZI key for the zone that you need into a TIME_ZONE_INFORMATION struct and call SystemTimeToTzSpecificLocalTime ? – Remko Feb 02 '21 at 11:20
  • yes, that would be the last resort, but if something can work the api's provided, thats better. – Sash Feb 02 '21 at 11:27
  • Again, we cannot comment on whether your code is correct or not without seeing either the code or your compiler invocation. You aren't going to solve your issue without producing a [mcve]. – IInspectable Feb 02 '21 at 11:33
  • Thanks for the feedback and apologies for not mentioning it earlier. – Sash Feb 02 '21 at 11:41
  • Drop the `#ifndef`s, unless you want to allow someone else to break your build. – IInspectable Feb 02 '21 at 13:22
  • Why are you using VS 2010. That is an 11 year old product. It is well past its [end of life](https://learn.microsoft.com/en-us/lifecycle/products/visual-studio-2010) and [VS 2019 Community Edition](https://visualstudio.microsoft.com/vs/community/) is free. – Matt Johnson-Pint Feb 02 '21 at 18:23
  • It would be helpful if you gave an example of the time zone id you are trying to look up. Also, in most cases you should no longer use the `TIME_ZONE_INFORMATION` structure, but always use the `DYNAMIC_TIME_ZONE_INFORMATION` structure instead. Use the "Ex" APIs when necessary, such as [`SystemTimeToTzSpecificLocalTimeEx`](https://learn.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-systemtimetotzspecificlocaltimeex). – Matt Johnson-Pint Feb 02 '21 at 18:25
  • Yes, will use the dynamic time zone info struct, but i'm kinda stuck at the EnumDynamicTimeZoneInformation() – Sash Feb 03 '21 at 12:12

1 Answers1

1

Comprehensive comments, the following example works for me:

#define WINVER 0x0602         
#define _WIN32_WINNT 0x0602

#include <windows.h>
#include<time.h>
#include<iostream>

int main() {
    DYNAMIC_TIME_ZONE_INFORMATION d_tz;
    memset(&d_tz, 0, sizeof(d_tz));
    DWORD res = 0;
    res = EnumDynamicTimeZoneInformation(1, &d_tz);//fetch specific timezone info

    /*Use this next*/
    SYSTEMTIME st = { 0 };
    SYSTEMTIME lt = { 0 };
    GetSystemTime(&st);
    SystemTimeToTzSpecificLocalTimeEx(&d_tz,&st, &lt);
    WCHAR time[250] = { 0 };

    GetTimeFormatEx(LOCALE_NAME_USER_DEFAULT, 0, &lt, L"HH':'mm':'ss tt", time, 250);
    std::wcout << L"Timezone: " << d_tz.TimeZoneKeyName << std::endl;
    std::wcout << lt.wYear << L"/" << lt.wMonth << L"/" << lt.wDay << L" " << time << std::endl;
    return 0;
}

Use EnumDynamicTimeZoneInformation get a DYNAMIC_TIME_ZONE_INFORMATION instance and then pass it to SystemTimeToTzSpecificLocalTimeEx with your SYSTEMTIME. Finally get the specific local time.

Result:

Timezone: Alaskan Standard Time
2021/2/2 17:25:39 PM
Drake Wu
  • 6,927
  • 1
  • 7
  • 30
  • did that work on vs 2010? I'm looking for specifically with vs2010. – Sash Feb 03 '21 at 12:10
  • @DrakeWu - Your example is good, but in general, one should use the `TimeZoneKeyName` to identify the time zone. The string in `StandardName` is the localized string that applies when DST is *not* in effect (as contrasted with `DaylightName`, which is the localized string that applies when DST *is* in effect). – Matt Johnson-Pint Feb 03 '21 at 19:41
  • @Sash - As I asked in the question comments - why vs2010 when it's past end of life and vs2019 community edition is free? Why create unnecessary pain for yourself? – Matt Johnson-Pint Feb 03 '21 at 19:43
  • @MattJohnson-Pint Thanks for explanation. – Drake Wu Feb 04 '21 at 01:32
  • @MattJohnson-Pint its a pretty old project, so im stuck with vs2010, i get your point, but trust me, i dont want to go through this pain too. – Sash Feb 04 '21 at 08:52
  • Does it work with my updated code? (Remove `#ifndef` condition) Does the SDK version you use support `EnumDynamicTimeZoneInformation`? That is, does the `timezoneapi.h` in the SDK you use contain the declaration of `EnumDynamicTimeZoneInformation`? – Drake Wu Feb 05 '21 at 07:19