Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

time: LoadLocation on Windows does not read zone information from the Windows API #38453

Open
mappu opened this issue Apr 14, 2020 · 5 comments
Labels
help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows
Milestone

Comments

@mappu
Copy link

mappu commented Apr 14, 2020

What version of Go are you using (go version)?

go version go1.13.4 windows/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env

What did you do?

https://play.golang.org/p/VuJ3ofkdk8

package main

import (
	"fmt"
	"time"
)

func main() {
	loc, err := time.LoadLocation("Europe/Paris")
	if err != nil {
		panic(err)
	}
	
	fmt.Println(loc)
}

I built this basic go code and generated an executable file.

I have an error when I run this executable on a windows machine without Go installed because time.LoadLocation needs to access to "zoneinfo.zip" located at $GOROOT/lib/time/zoneinfo.zip.

What did you expect to see?

Europe/Paris

What did you see instead?

open c:\go\lib\time\zoneinfo.zip: The system cannot find the file specified.


This is a followup to ticket #21881 .

Some workarounds are available:

  1. Ship a copy of zoneinfo.zip and use LoadLocationFromTZData (added in go1.10)

  2. Ship a copy of zoneinfo.zip embedded into the Go binary, by the new import statement import _ "time/tzdata" (will land in go1.15)

However, the ability to ship a fixed, unchanging copy of the zone database is an orthogonal solution to properly using the available, up-to-date copy maintained by the OS. It has quite different properties and is not the same solution.

  • this quickly gets out of date
    • (e.g. Brazil DST rules changed recently in 2019, affecting > 200 million people)
  • this makes the release artifacts much larger
  • (for case 1) it is difficult to ensure any imported packages do this
  • (for case 2) it is difficult to prevent any imported packages from doing this
  • in neither case is the solution automatic

Shipping a copy of the zone database is an interesting solution if the system timezone information is unreliable, but this is really not the case in most environments where the system timezone database is continually updated by the host OS. It may also be preferable for Go to use the same timezone information as other programs on the host OS even if the database is not fully up-to-date.

On Linux, this has long since been a non-issue as Go always relies on the system timezone information. The default behavior should be to do the same on Windows.

There is real, system-updated timezone information available from the Windows API, that can resolve the above points. Go programs should make use of it, instead of bundling a large archive that quickly becomes outdated.


The classic win32 Windows API is not a 1:1 match for Go's existing timezone APIs, but there is a mapping table in CLDR:

Most of this information is already included in the time package for parsing the current Windows timezone:

It would be possible to extend this to support all the other timezone APIs in Go:


Alternatively, more recent versions of Windows do include the full zone database:

With a more extensive look at the available API surface in supported versions of Windows, other data sources may be found for this information too.

@ianlancetaylor ianlancetaylor added help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows labels Apr 15, 2020
@ianlancetaylor ianlancetaylor added this to the Backlog milestone Apr 15, 2020
@iwdgo
Copy link
Contributor

iwdgo commented May 24, 2020

The provided code returns the expected name "Europe/Paris" on tip and go version go1.14.3 windows/amd64. Issue seems to have been solved by #34917

@ianlancetaylor
Copy link
Contributor

@iwdgo This issue is specifically about reading the timezone information provided by Windows. The Go standard library definitely doesn't do that. Perhaps we need a different example.

@benridley
Copy link

benridley commented Jun 19, 2020

According to microsoft/WSL#3747, the WinRT/UWP function Windows::Globalization::Calendar().GetTimeZone() uses the %WINDIR%\Globalization\Time Zone\timezoneMapping.xml file so it seems like a reliable source of this info. I think it would make sense for Go to leverage the same thing and that way we don't need to rely on embedding the timezone database in binaries on Windows, and users also don't need to update their applications if timezones happen to change.

@benridley
Copy link

@ianlancetaylor I'd be keen to do some work on this, but if we decide to parse the Windows XML file it would only work on Windows 8.1/Server 2012R2 and above.. Go on Windows minimum requirements are currently Server 2008 R2 which doesn't have the file. Would this be worth doing if it means breaking feature parity on those older versions?

@ianlancetaylor
Copy link
Contributor

Thanks. I think it's fine to break feature parity with operating systems that are 8 years old. Of course they must continue to work. But it's OK if they sometimes get stale timezone information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows
Projects
None yet
Development

No branches or pull requests

4 participants