Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign uptime: LoadLocation doesn't work on windows if Go is not installed #21881
Comments
ianlancetaylor
changed the title from
time.LoadLocation doesn't work on windows if go is not installed
to
time: LoadLocation doesn't work on windows if go is not installed
Sep 14, 2017
ianlancetaylor
added
the
OS-Windows
label
Sep 14, 2017
ianlancetaylor
added this to the Unplanned milestone
Sep 14, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ianlancetaylor
Sep 14, 2017
Contributor
I don't see how we can fix this, at least not without bloating the size of almost every Go binary on Windows. I'm open to suggestions.
|
I don't see how we can fix this, at least not without bloating the size of almost every Go binary on Windows. I'm open to suggestions. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
skirmish
Sep 14, 2017
On windows couldn't it (default to|try) the (current working directory|executable location) to load the zoneinfo.zip? That way you only can include the file when it is required. Yeah, it's an extra hoop to jump through for us windows users, but I guess it's not too big of an ordeal seeing as the executable has to be distributed somehow, one extra file might not be too bad...
skirmish
commented
Sep 14, 2017
|
On windows couldn't it (default to|try) the (current working directory|executable location) to load the zoneinfo.zip? That way you only can include the file when it is required. Yeah, it's an extra hoop to jump through for us windows users, but I guess it's not too big of an ordeal seeing as the executable has to be distributed somehow, one extra file might not be too bad... |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
alexbrainman
Sep 14, 2017
Member
On windows couldn't it (default to|try) the (current working directory|executable location) to load the zoneinfo.zip?
Sounds simple enough for me.
Alex
Sounds simple enough for me. Alex |
ianlancetaylor
added
the
NeedsFix
label
Sep 15, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
glycerine
Sep 21, 2017
zoneinfo.zip is a mere 366776 bytes, a small number amongst friends. I think of a typical go binary as a 10MB +/- 5MB affair, and I would happily increase that by 366KB (3% of the mean, but small compared to the standard deviation) to have my binaries be portable to windows.
glycerine
commented
Sep 21, 2017
|
zoneinfo.zip is a mere 366776 bytes, a small number amongst friends. I think of a typical go binary as a 10MB +/- 5MB affair, and I would happily increase that by 366KB (3% of the mean, but small compared to the standard deviation) to have my binaries be portable to windows. |
iman75
changed the title from
time: LoadLocation doesn't work on windows if go is not installed
to
time: LoadLocation doesn't work on windows if Go is not installed
Sep 22, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
leighmcculloch
Nov 6, 2017
Contributor
I don't see how we can fix this, at least not without bloating the size of almost every Go binary on Windows.
Providing the tzdata ourselves in the binary if a specific package is imported (e.g. time/zone) seems less worse to me than requiring every Windows user to install Go, which is much larger to download and is inconsistent with the static binary.
Could we duplicate the time.LoadLocation function to another package which also contains the tzdata, e.g. zone.LoadLocation. This new function would operate the same as time.LoadLocation, but would load from a tzdata file built into a new zone package. This would only introduce bloat to binaries that imported the zone package, and applications could choose to use time.LoadLocation or zone.LoadLocation. We could mark time.LoadLocation as deprecated, or at least mention in a comment on it about it's limitations and about the alternative. Having the basic time code and the zone code in separate packages would mean the bloat is only introduced if applications specifically need it.
Providing the tzdata ourselves in the binary if a specific package is imported (e.g. Could we duplicate the |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
alexbrainman
Nov 7, 2017
Member
Just an idea. On windows we use a particular Windows registry key to determine our timezone, and then we use a map that maps that string into std / dst values that are ultimately used to look in the tzdata blob. The "registry key" to "std / dst" map is hard coded in "abbrs" map in time package. This map contains 133 values at this moment. I wonder if we could strip tzdata blob to leave only the data we actually use on windows. I don't have time to try and implement this now, perhaps others do.
Alex
|
Just an idea. On windows we use a particular Windows registry key to determine our timezone, and then we use a map that maps that string into std / dst values that are ultimately used to look in the tzdata blob. The "registry key" to "std / dst" map is hard coded in "abbrs" map in time package. This map contains 133 values at this moment. I wonder if we could strip tzdata blob to leave only the data we actually use on windows. I don't have time to try and implement this now, perhaps others do. Alex |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
nathan-osman
Jan 20, 2018
It would be awesome if there was a function that we could call to pass the contents of zoneinfo.zip to the time package. That way, the caller is responsible for determining where they want to put zoneinfo.zip and they have the option of embedding its contents in the executable.
nathan-osman
commented
Jan 20, 2018
|
It would be awesome if there was a function that we could call to pass the contents of |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bradfitz
Jan 20, 2018
Member
@nathan-osman, Go 1.10 has https://beta.golang.org/pkg/time/#LoadLocationFromTZData (that was #20629)
|
@nathan-osman, Go 1.10 has https://beta.golang.org/pkg/time/#LoadLocationFromTZData (that was #20629) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
nathan-osman
commented
Jan 20, 2018
|
@bradfitz excellent, thanks! That will work perfectly. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
shabbyrobe
Mar 1, 2018
I was pretty astonished by this. I can trivially build and deploy binaries to Windows just like I can everywhere else, but as soon as I try to work with a timezone, my application blows up. Go's tooling lulls me into a false sense of ease upon which I grow to rely, but it's a false promise. I'd much rather a larger binary than an... ahem... time-bomb like this ticking away.
shabbyrobe
commented
Mar 1, 2018
•
|
I was pretty astonished by this. I can trivially build and deploy binaries to Windows just like I can everywhere else, but as soon as I try to work with a timezone, my application blows up. Go's tooling lulls me into a false sense of ease upon which I grow to rely, but it's a false promise. I'd much rather a larger binary than an... ahem... time-bomb like this ticking away. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
glycerine
Mar 2, 2018
All, what's the best current workaround for this? I need to distribute a windows binary, that uses time, and I'd like it not to blow up on user's boxes.
import "time/zone" would be great, eventually. But what's the solution today?
Thank you!
glycerine
commented
Mar 2, 2018
|
All, what's the best current workaround for this? I need to distribute a windows binary, that uses time, and I'd like it not to blow up on user's boxes.
Thank you! |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bradfitz
Mar 2, 2018
Member
The solution is to ship the tzdata yourself (linked into your binary or elsewhere) and then call https://golang.org/pkg/time/#LoadLocationFromTZData.
Or set the %ZONEINFO% environment variable to point to your shipped zoneinfo.zip.
|
The solution is to ship the tzdata yourself (linked into your binary or elsewhere) and then call https://golang.org/pkg/time/#LoadLocationFromTZData. Or set the %ZONEINFO% environment variable to point to your shipped zoneinfo.zip. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
glycerine
Mar 2, 2018
Thanks Brad.
For others, the data that is passed to LoadLocationFromTZData is a file extracted from inside zoneinfo.zip, such as the file America/New_York, not zoneinfo.zip itself.
glycerine
commented
Mar 2, 2018
|
Thanks Brad. For others, the data that is passed to LoadLocationFromTZData is a file extracted from inside |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
shabbyrobe
Mar 2, 2018
This is the quickie solution I used yesterday to get moving again: https://gist.github.com/shabbyrobe/b9a7a56e25bd8e441b7b3fe39dbb04fa
It relies on something not unlike the now-infamous https://github.com/jteeuwen/go-bindata to generate a go file with that tzfiles map referenced in the gist, which contains the base64-encoded zoneinfo.zip file I grabbed from the GOROOT of another Windows machine that was allowed to have Go installed on it (not always an option).
The code was dashed out under the duress of extreme time pressure so it's not exactly nice (and comes with absolutely no warranty whatsoever) but hopefully it can help someone else get out of the same jam.
shabbyrobe
commented
Mar 2, 2018
|
This is the quickie solution I used yesterday to get moving again: https://gist.github.com/shabbyrobe/b9a7a56e25bd8e441b7b3fe39dbb04fa It relies on something not unlike the now-infamous https://github.com/jteeuwen/go-bindata to generate a go file with that tzfiles map referenced in the gist, which contains the base64-encoded zoneinfo.zip file I grabbed from the GOROOT of another Windows machine that was allowed to have Go installed on it (not always an option). The code was dashed out under the duress of extreme time pressure so it's not exactly nice (and comes with absolutely no warranty whatsoever) but hopefully it can help someone else get out of the same jam. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
leighmcculloch
Mar 3, 2018
Contributor
I created 4d63.com/tz because I find it more convenient to import a package than manually including a file to ride alongside an executable. It embeds Go's zoneinfo.zip and exports tz.LoadLocation(name) to load locations from the embedded tzdata.
|
I created 4d63.com/tz because I find it more convenient to import a package than manually including a file to ride alongside an executable. It embeds Go's |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
glycerine
Mar 3, 2018
Awesome @leighmcculloch. That should really become part of the standard library (or rather just be the implementation of time.LoadLocation on Windows), but while waiting for that, its just great to have it available. In the meantime, all calls to time.LoadLocation, in order to not crash on windows/OS without zoneinfo, need to become calls to tz.LoadLocation() after
import "4d63.com/tz".
glycerine
commented
Mar 3, 2018
•
|
Awesome @leighmcculloch. That should really become part of the standard library (or rather just be the implementation of time.LoadLocation on Windows), but while waiting for that, its just great to have it available. In the meantime, all calls to time.LoadLocation, in order to not crash on windows/OS without zoneinfo, need to become calls to tz.LoadLocation() after |
iman75 commentedSep 14, 2017
•
edited
What version of Go are you using (
go version)?go version go1.8.3 windows/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env)?set GOARCH=amd64
set GOBIN=
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\Users\Iman Akabi\go
set GORACE=
set GOROOT=C:\Go
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0
set CXX=g++
set CGO_ENABLED=1
set PKG_CONFIG=pkg-config
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
What did you do?
https://play.golang.org/p/VuJ3ofkdk8
package main
import (
"fmt"
"time"
"log"
)
func main() {
var ParisLocation, err = time.LoadLocation("Europe/Paris")
if(err != nil) {
log.Fatal(err)
}
}
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 aceess 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.