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: misleading "zoneinfo.zip: no such file or directory" error when trying to load non-existent timezone #20969

Closed
Dieterbe opened this issue Jul 10, 2017 · 17 comments

Comments

@Dieterbe
Copy link
Contributor

@Dieterbe Dieterbe commented Jul 10, 2017

Please answer these questions before submitting your issue. Thanks!

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

go version devel +be855e3f28 Mon Jun 19 23:26:32 2017 +0000 linux/amd64

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

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/dieter/go"
GORACE=""
GOROOT="/home/dieter/code/go"
GOTOOLDIR="/home/dieter/code/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -fmessage-length=0 -fdebug-prefix-map=/tmp/dieter/go-build409613068=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="0"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"

What did you do?

> cat main.go
package main

import (
	"fmt"
	"time"
)

func main() {
	tz, err := time.LoadLocation("America/New_York")
	fmt.Printf("New_York %q %q\n", tz, err)
	tz, err = time.LoadLocation("America/New_Yaark")
	fmt.Printf("New_Yaark %q %q\n", tz, err)
}
> cat Dockerfile
FROM alpine
RUN apk add -U tzdata
COPY main /usr/bin/
ENTRYPOINT ["/usr/bin/main"]

go build -o main
docker build .
docker run ea1f31431e4d

What did you expect to see?

New_York "America/New_York" %!q(<nil>)
New_Yaark "UTC" "can't find timezone America/New_Yaark or something"

What did you see instead?

New_York "America/New_York" %!q(<nil>)
New_Yaark "UTC" "open /home/dieter/code/go/lib/time/zoneinfo.zip: no such file or directory"

note that when I run it on my host which does have a zoneinfo.zip I get:

go run main.go
New_York "America/New_York" %!q(<nil>)
New_Yaark "UTC" "cannot find America/New_Yaark in zip file /home/dieter/code/go/lib/time/zoneinfo.zip"
@bradfitz bradfitz changed the title misleading "zoneinfo.zip: no such file or directory" error when trying to load non-existant timezone time: misleading "zoneinfo.zip: no such file or directory" error when trying to load non-existent timezone Jul 10, 2017
@bradfitz
Copy link
Contributor

@bradfitz bradfitz commented Jul 10, 2017

Not a regression from Go 1.8 (or any other prior release), so targeting Go 1.10 for consideration.

I don't think it's a good idea to get rid of the part of the error message that says where it was looking to find the answer (which zip file path). You want it to say both things? Failed to find New_Yaark and also the zip file path?

@bradfitz bradfitz added this to the Go1.10 milestone Jul 10, 2017
@Dieterbe
Copy link
Contributor Author

@Dieterbe Dieterbe commented Jul 10, 2017

i'm not sure TBH. to be clear, is it perfectly normal to have situations where only a few timezones are installed, and where it can only know for sure that a tz doesn't exist if it can check against a zoneinfo.zip file?

@ALTree
Copy link
Member

@ALTree ALTree commented Jul 11, 2017

@Dieterbe the alternative would be to embed the whole IANA Time Zone database in the binary(?)

I agree we could try to print a better error, though (even if the current one is technically correct).

@bradfitz
Copy link
Contributor

@bradfitz bradfitz commented Jul 11, 2017

@ALTree, some discussion of that is in #20629 (comment).

@Dieterbe
Copy link
Contributor Author

@Dieterbe Dieterbe commented Jul 11, 2017

can somebody answer:

to be clear, is it perfectly normal to have situations where only a few timezones are installed, and where it can only know for sure that a tz doesn't exist if it can check against a zoneinfo.zip file?

(i hope that question did not come across snarky or sarcastic. I just need clarity on that before I can think of suggestions for improvement)

@bradfitz
Copy link
Contributor

@bradfitz bradfitz commented Jul 11, 2017

@Dieterbe, oh, I see what you're suggesting now. That if, say, /usr/share/zoneinfo exists on disk and is not empty, that it's the only source of truth and that the zip file shouldn't be used as a backup (and thus the error message of its non-existence would never occur).

That's a possibility. I don't believe the intent of the current code is to blend two sources of information (zoneinfo dir and zip), but just to try the zip if the file on disk doesn't exist. IIRC, currently the code just tries to open a single file under /usr/share/zoneinfo and doesn't try to determine whether sibling files exist.

@agnivade
Copy link
Contributor

@agnivade agnivade commented Jun 30, 2018

Analysis: The code directly checks for a file under /usr/share/zoneinfo without checking for the directory. And it only accepts a non syscall.ENOENT error as a valid error to hold in the error variable as it iterates through the list of zoneSources. That is the reason why the error where it was unable to access /usr/share/zoneinfo/<file> was getting eaten up.

So we need to check for the existence of a zoneinfo dir first, and then check for the file inside the dir if it exists and return a similar non ENOENT error ("cannot find <file> in <dir>") like others.

Only thing is, I will need to copy over a minimal implementation of syscall.Stat (to check for dir existence) to prevent dependency on os package. Luckily, for plan9 and windows, the .zip file is the only zoneSource so nothing to do over there.

Will send a CL.

@agnivade agnivade self-assigned this Jun 30, 2018
@gopherbot
Copy link

@gopherbot gopherbot commented Jul 1, 2018

Change https://golang.org/cl/121877 mentions this issue: time: improve error message for LoadLocation

@gopherbot
Copy link

@gopherbot gopherbot commented Sep 14, 2018

Change https://golang.org/cl/135416 mentions this issue: time: return ENOENT from androidLoadTzinfoFromTzdata if zone not found

gopherbot pushed a commit that referenced this issue Sep 15, 2018
This makes Android consistent with the change in CL 121877.

Updates #20969

Change-Id: I1f114556fd1d4654c8e4e6a59513bddd5dc3d1a0
Reviewed-on: https://go-review.googlesource.com/135416
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Elias Naur <elias.naur@gmail.com>
@gopherbot
Copy link

@gopherbot gopherbot commented Dec 21, 2018

Change https://golang.org/cl/155538 mentions this issue: time: Return ENOENT if a zoneinfo zip file is not found.

gopherbot pushed a commit that referenced this issue Dec 24, 2018
Updates #20969

Change-Id: Ibcf0bf932d5b1de67c22c63dd8514ed7a5d198fb
Reviewed-on: https://go-review.googlesource.com/c/155538
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
@pagidi
Copy link

@pagidi pagidi commented Jul 20, 2019

May I know what is the fix for this issue?

I ran into the same issue, go runtime fails to convert time if the timezone is "Asia/kolkata" but works with "Asia/Calcutta"

it runs of my local machine(go version 1.11.4 , Ubuntu 18.X) but not on server (Ubuntu 16.x).

I appreciate your help !!

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jul 20, 2019

@pagidi This issue was closed months ago. For help with Go, please see https://golang.org/wiki/Questions.

On Ubuntu timezone information comes from files in the /usr/share/zoneinfo directory. So if a timezone works on one system but not another, it means that the two systems have different zoneinfo files.

@tsuz
Copy link

@tsuz tsuz commented Aug 22, 2019

@pagidi

ADD https://github.com/golang/go/raw/master/lib/time/zoneinfo.zip /usr/local/go/lib/time/zoneinfo.zip

is what made it work for me full gist

@pagidi
Copy link

@pagidi pagidi commented Sep 9, 2019

Thanks @tsuz

But My problem seems different.
It works in my development machine since it has go runtime
I don't have go run time in the server (it runs as .deb executable), but the go application expects zoneinfo file in the location /usr/local/go/lib/time/zoneinfo.zip

Is there way, we can give path in the Go program to look for the zoneinfo.zip???

@agnivade
Copy link
Contributor

@agnivade agnivade commented Sep 9, 2019

Please look into the documentation - https://golang.org/pkg/time/#LoadLocation.

LoadLocation looks in the directory or uncompressed zip file named by the ZONEINFO environment variable, if any, then looks in known installation locations on Unix systems, and finally looks in $GOROOT/lib/time/zoneinfo.zip.

I would suggest to update the zone information on your remote server. If that does not work, use the ZONEINFO variable.

In future, for Go related questions please use the forums in https://golang.org/wiki/Questions. Closed issues are not monitored. Thanks.

@pagidi
Copy link

@pagidi pagidi commented Sep 9, 2019

Thanks for the help! @agnivade

Though I have used ZONEINFO variable it didn't work, am I missing something here?

$ locate zoneinfo
/usr/share/zoneinfo/right/Asia/Brunei
/usr/share/zoneinfo/right/Asia/Calcutta
/usr/share/zoneinfo/right/Asia/Chita
/usr/share/zoneinfo/right/Asia/Choibalsan
/usr/share/zoneinfo/right/Asia/Chongqing
/usr/share/zoneinfo/right/Asia/Kolkata

it means zoneinfo is located in user/share/zoneinfo/

$export ZONEINFO=/usr/share/zoneinfo/

Still I see application throws below Error.
cannot find "Asia/Kolkata" in zip file /usr/local/go/lib/time/zoneinfo.zip

@mvrhov
Copy link

@mvrhov mvrhov commented Sep 9, 2019

Because you use the wrong directory in your export
$export ZONEINFO=/usr/share/zoneinfo/right

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
10 participants
You can’t perform that action at this time.