Why doesn't Go time.Parse () parse the timezone identifier?

Consider the following code:

package main

import (
    "time"
    "fmt"
)

const (
    format = "2006 01 02 15:04 MST"

    date = "2018 08 01 12:00 EDT"
)

func main() {
    aloc, _ := time.LoadLocation("America/New_York")
    eloc, _ := time.LoadLocation("Europe/Berlin")
    tn, _ := time.Parse(format, date)
    tl, _ := time.ParseInLocation(format, date, aloc)

    fmt.Println(tn) // Says +0000 despite EDT being -0400
    fmt.Println(tn.In(eloc)) // Expect 18:00, but get 14:00
    fmt.Println(tl) // Correctly -0400
    fmt.Println(tl.In(eloc)) // Correctly 18:00
}

You can also try it on the Go Playground .

When I run it, I get this result (both on my own system and through the Playground):

2018-08-01 12:00:00 +0000 EDT
2018-08-01 14:00:00 +0200 CEST
2018-08-01 12:00:00 -0400 EDT
2018-08-01 18:00:00 +0200 CEST

I expected the first and third lines to be the same, and the second and fourth to be the same.

It seems to me that the Go time library does not parse the time zone identifier "EDT" that I wrote on the date line, despite the fact that it is part of the format.

My own system (Fedora 26) also recognizes EST / EDT as a time zone:

$ TZ='America/New_York' date 080112002018
Wed  1 Aug 12:00:00 EDT 2018

, , ParseInLocation(), , . "EDT" "America/New_York".

- ?

+4
1

, go/1.10/libexec/src/time/zoneinfo.go:226

func (l *Location) lookupName(name string, unix int64) (offset int, ok bool) {
    l = l.get()

    // First try for a zone with the right name that was actually
    // in effect at the given time. (In Sydney, Australia, both standard
    // and daylight-savings time are abbreviated "EST". Using the
    // offset helps us pick the right one for the given time.
    // It not perfect: during the backward transition we might pick
    // either one.)
    for i := range l.zone {
        zone := &l.zone[i]
        if zone.name == name {
            nam, offset, _, _, _ := l.lookup(unix - int64(zone.offset))
            if nam == zone.name {
                return offset, true
            }
        }
    }

    // Otherwise fall back to an ordinary name match.
    for i := range l.zone {
        zone := &l.zone[i]
        if zone.name == name {
            return zone.offset, true
        }
    }

    // Otherwise, give up.
    return
}

OSX ( , CET ) l.get() , 4 CET, CEST, CET CEST . , GMT UTC . "" , EDT.

+2

Source: https://habr.com/ru/post/1694398/


All Articles