Repository: go
Issue: time: LoadLocation on Windows does not read zone information from the Windows API
Labels: help wanted,OS-Windows,NeedsInvestigation

### What version of Go are you using (`go version`)?

<pre>
go version go1.13.4 windows/amd64
</pre>

### Does this issue reproduce with the latest release?

Yes

### What operating system and processor architecture are you using (`go env`)?

<details><summary><code>go env</code> Output</summary><br><pre>
$ go env

</pre></details>

### What did you do?

https://play.golang.org/p/VuJ3ofkdk8

```golang
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:

- http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml

Most of this information is already included in the time package for parsing the current Windows timezone:

- https://github.com/golang/go/blob/master/src/time/zoneinfo_abbrs_windows.go

It would be possible to extend this to support all the other timezone APIs in Go:

- https://github.com/golang/go/issues/21881#issuecomment-342347609

---

Alternatively, more recent versions of Windows do include the full zone database:

- https://github.com/golang/go/issues/21881#issuecomment-552239335

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.