Skip to content

Conversation

@stakach
Copy link
Contributor

@stakach stakach commented Oct 26, 2025

on windows: puts ::Time::Location.load("GMT") will raise:

Unhandled exception: Invalid location name: GMT (Time::Location::InvalidLocationNameError)
  from C:\Users\steve\AppData\Local\Programs\Crystal\src\time\location.cr:344 in 'load'
  from test.cr:1 in '__crystal_main'
  from C:\Users\steve\AppData\Local\Programs\Crystal\src\crystal\main.cr:129 in 'main_user_code'
  from C:\Users\steve\AppData\Local\Programs\Crystal\src\crystal\main.cr:115 in 'main'
  from C:\Users\steve\AppData\Local\Programs\Crystal\src\crystal\main.cr:141 in 'main'
  from C:\Users\steve\AppData\Local\Programs\Crystal\src\crystal\system\win32\wmain.cr:36 in 'wmain'
  from D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288 in '__scrt_common_main_seh'
  from C:\windows\System32\KERNEL32.DLL +190679 in 'BaseThreadInitThunk'
  from C:\windows\SYSTEM32\ntdll.dll +574780 in 'RtlUserThreadStart'

Issue I am having: https://github.com/spider-gazelle/openssl_ext/actions/runs/18819046827/job/53691685453#step:5:144

@ysbaddaden
Copy link
Contributor

This is an auto generated file. Please check the script and data source.

@straight-shoota
Copy link
Member

GMT seems to be not available in the Windows zone mappings. Windows itself does have a GMT zone though as an alias to UTC:

$ Get-TimeZone -Id "GMT"

Id                         : GMT
HasIanaId                  : True
DisplayName                : (UTC) Co-ordinated Universal Time
StandardName               : Co-ordinated Universal Time
DaylightName               : Co-ordinated Universal Time
BaseUtcOffset              : 00:00:00
SupportsDaylightSavingTime : False

Maybe we should add such a custom alias in Crystal::System::Time.load_iana_zone?

@straight-shoota straight-shoota added kind:bug A bug in the code. Does not apply to documentation, specs, etc. platform:windows Windows support based on the MSVC toolchain / Win32 API topic:stdlib:time labels Oct 27, 2025
@ysbaddaden
Copy link
Contributor

ysbaddaden commented Oct 27, 2025

@straight-shoota You might also have aliases for GMT-14 - GMT+12 (to UTC+14 - UTC-12). I don't even have GMT on my tiny11 core VM.

@ysbaddaden
Copy link
Contributor

Searching a bit, I found a stackoverflow question that led me to the C# TimezoneConverter library that injects the GMT alias to UTC.

@HertzDevil
Copy link
Contributor

HertzDevil commented Oct 27, 2025

The built-in PowerShell 5.x does not use ICU, only the newer 7.x does, which needs to be manually installed. In that case Get-TimeZone ultimately forwards to ucal_getWindowsTimeZoneID (1 2 3 4 5 6), and it indeed aliases GMT to UTC (note that ICU is a system library on Windows):

@[Link("icu")]
lib LibICU
  alias Char = UInt16

  enum ErrorCode
    U_ZERO_ERROR = 0
  end

  fun ucal_getWindowsTimeZoneID(id : Char*, len : Int32, winid : Char*, winidCapacity : Int32, status : ErrorCode*) : Int32
end

status = LibICU::ErrorCode::U_ZERO_ERROR
id = "GMT"
winid = uninitialized UInt16[100]
len = LibICU.ucal_getWindowsTimeZoneID(id.to_utf16, -1, winid, winid.size, pointerof(status))
if len != 0
  p String.from_utf16(winid.to_slice[0, len]) # => "UTC"
end

Judging from the ICU specs, the GMT name probably originates from the tzdb etcetera file.

@stakach
Copy link
Contributor Author

stakach commented Oct 27, 2025

Should we close this and change this pull to an issue? as I am unsure how to solve...
The problem I'm having is that OpenSSL outputs date strings with GMT and those are not being successfully parsed on Windows.

@HertzDevil
Copy link
Contributor

HertzDevil commented Oct 27, 2025

You could simply do rchop(" GMT") as it is not meant to be changeable anyway. If you are not convinced:

  • The default format is claimed to be RFC 822, but that is wrong since the time-of-day should go after the year, not before. In C you could pass the ASN1_DTFLGS_ISO8601 flag to ASN1_TIME_print_ex since ISO 8601 is easier to parse. It was only added in OpenSSL 3.0 though, so for older versions you might have to use the ASN1_STRING_* functions instead and parse the ASN.1 datetime directly.
  • For the openssl command-line tool, you could pass -dateopt iso_8601 for the same effect.

@stakach
Copy link
Contributor Author

stakach commented Oct 28, 2025

Yeah I am using asn1_time_print - will rchop(" GMT") but still seems like something that should be resolved to make Windows act like linux and macos instead of being worked around

There are datetime strings out there with GMT in them that most people will expect crystal to be able to parse no matter which platform they're on

@straight-shoota
Copy link
Member

Chopping GMT sounds like a good workaround.

But I think it makes sense to support GMT as a valid time zone identifier on Windows. Historically, it has been used as a generic name in a similar manner as UTC.
This use case shows that GMT is relevant for data exchange.
We should make sure to support it as a legacy alias for UTC.

straight-shoota added a commit that referenced this pull request Oct 31, 2025
Support GMT as a valid time zone identifier, even without a zoneinfo database. Historically, it has been used as a generic name in a similar manner as UTC.
As the use case in #16277 shows, GMT is relevant for data exchange.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind:bug A bug in the code. Does not apply to documentation, specs, etc. platform:windows Windows support based on the MSVC toolchain / Win32 API topic:stdlib:time

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants