Skip to content

Commit

Permalink
time: revise for go1.12
Browse files Browse the repository at this point in the history
Update #3
  • Loading branch information
changkun committed Jan 27, 2019
1 parent 109ad9c commit 37b5a51
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 20 deletions.
13 changes: 8 additions & 5 deletions gosrc/1.11.5/time/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -1120,7 +1120,8 @@ func parseTimeZone(value string) (length int, ok bool) {
// Special Case 3: Some time zones are not named, but have +/-00 format
if value[0] == '+' || value[0] == '-' {
length = parseSignedOffset(value)
return length, true
ok := length > 0 // parseSignedOffset returns 0 in case of bad input
return length, ok
}
// How many upper-case letters are there? Need at least three, at most five.
var nUpper int
Expand Down Expand Up @@ -1152,7 +1153,7 @@ func parseTimeZone(value string) (length int, ok bool) {

// parseGMT parses a GMT time zone. The input string is known to start "GMT".
// The function checks whether that is followed by a sign and a number in the
// range -14 through 12 excluding zero.
// range -23 through +23 excluding zero.
func parseGMT(value string) int {
value = value[3:]
if len(value) == 0 {
Expand All @@ -1163,21 +1164,23 @@ func parseGMT(value string) int {
}

// parseSignedOffset parses a signed timezone offset (e.g. "+03" or "-04").
// The function checks for a signed number in the range -14 through +12 excluding zero.
// The function checks for a signed number in the range -23 through +23 excluding zero.
// Returns length of the found offset string or 0 otherwise
func parseSignedOffset(value string) int {
sign := value[0]
if sign != '-' && sign != '+' {
return 0
}
x, rem, err := leadingInt(value[1:])
if err != nil {

// fail if nothing consumed by leadingInt
if err != nil || value[1:] == rem {
return 0
}
if sign == '-' {
x = -x
}
if x == 0 || x < -14 || 12 < x {
if x < -23 || 23 < x {
return 0
}
return len(value) - len(rem)
Expand Down
3 changes: 0 additions & 3 deletions gosrc/1.11.5/time/sleep.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ package time
// A negative or zero duration causes Sleep to return immediately.
func Sleep(d Duration)

// runtimeNano returns the current value of the runtime clock in nanoseconds.
func runtimeNano() int64

// Interface to timers implemented in package runtime.
// Must be in sync with ../runtime/time.go:/^type timer
type runtimeTimer struct {
Expand Down
2 changes: 1 addition & 1 deletion gosrc/1.11.5/time/sys_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin dragonfly freebsd js,wasm linux nacl netbsd openbsd solaris
// +build aix darwin dragonfly freebsd js,wasm linux nacl netbsd openbsd solaris

package time

Expand Down
44 changes: 39 additions & 5 deletions gosrc/1.11.5/time/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@
//
package time

import "errors"
import (
"errors"
_ "unsafe" // for go:linkname
)

// A Time represents an instant in time with nanosecond precision.
//
Expand All @@ -102,6 +105,10 @@ import "errors"
// change the instant in time being denoted and therefore does not affect the
// computations described in earlier paragraphs.
//
// Representations of a Time value saved by the GobEncode, MarshalBinary,
// MarshalJSON, and MarshalText methods store the Time.Location's offset, but not
// the location name. They therefore lose information about Daylight Saving Time.
//
// In addition to the required “wall clock” reading, a Time may contain an optional
// reading of the current process's monotonic clock, to provide additional precision
// for comparison or subtraction.
Expand Down Expand Up @@ -908,13 +915,27 @@ func (t Time) Sub(u Time) Duration {
// Since returns the time elapsed since t.
// It is shorthand for time.Now().Sub(t).
func Since(t Time) Duration {
return Now().Sub(t)
var now Time
if t.wall&hasMonotonic != 0 {
// Common case optimization: if t has monotomic time, then Sub will use only it.
now = Time{hasMonotonic, runtimeNano() - startNano, nil}
} else {
now = Now()
}
return now.Sub(t)
}

// Until returns the duration until t.
// It is shorthand for t.Sub(time.Now()).
func Until(t Time) Duration {
return t.Sub(Now())
var now Time
if t.wall&hasMonotonic != 0 {
// Common case optimization: if t has monotomic time, then Sub will use only it.
now = Time{hasMonotonic, runtimeNano() - startNano, nil}
} else {
now = Now()
}
return t.Sub(now)
}

// AddDate returns the time corresponding to adding the
Expand All @@ -933,7 +954,7 @@ func (t Time) AddDate(years int, months int, days int) Time {

const (
secondsPerMinute = 60
secondsPerHour = 60 * 60
secondsPerHour = 60 * secondsPerMinute
secondsPerDay = 24 * secondsPerHour
secondsPerWeek = 7 * secondsPerDay
daysPer400Years = 365*400 + 97
Expand Down Expand Up @@ -1050,9 +1071,22 @@ func daysIn(m Month, year int) int {
// Provided by package runtime.
func now() (sec int64, nsec int32, mono int64)

// runtimeNano returns the current value of the runtime clock in nanoseconds.
//go:linkname runtimeNano runtime.nanotime
func runtimeNano() int64

// Monotonic times are reported as offsets from startNano.
// We initialize startNano to runtimeNano() - 1 so that on systems where
// monotonic time resolution is fairly low (e.g. Windows 2008
// which appears to have a default resolution of 15ms),
// we avoid ever reporting a monotonic time of 0.
// (Callers may want to use 0 as "time not set".)
var startNano int64 = runtimeNano() - 1

// Now returns the current local time.
func Now() Time {
sec, nsec, mono := now()
mono -= startNano
sec += unixToInternal - minWall
if uint64(sec)>>33 != 0 {
return Time{uint64(nsec), sec + minWall, Local}
Expand All @@ -1076,7 +1110,7 @@ func (t Time) Local() Time {
return t
}

// In returns a copy of t representating the same time instant, but
// In returns a copy of t representing the same time instant, but
// with the copy's location information set to loc for display
// purposes.
//
Expand Down
13 changes: 11 additions & 2 deletions gosrc/1.11.5/time/zoneinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ func (l *Location) lookupFirstZone() int {
return 0
}

// firstZoneUsed returns whether the first zone is used by some
// firstZoneUsed reports whether the first zone is used by some
// transition.
func (l *Location) firstZoneUsed() bool {
for _, tx := range l.tx {
Expand Down Expand Up @@ -288,14 +288,23 @@ func LoadLocation(name string) (*Location, error) {
env, _ := syscall.Getenv("ZONEINFO")
zoneinfo = &env
})
var firstErr error
if *zoneinfo != "" {
if zoneData, err := loadTzinfoFromDirOrZip(*zoneinfo, name); err == nil {
if z, err := LoadLocationFromTZData(name, zoneData); err == nil {
return z, nil
}
firstErr = err
} else if err != syscall.ENOENT {
firstErr = err
}
}
return loadLocation(name, zoneSources)
if z, err := loadLocation(name, zoneSources); err == nil {
return z, nil
} else if firstErr == nil {
firstErr = err
}
return nil, firstErr
}

// containsDotDot reports whether s contains "..".
Expand Down
15 changes: 12 additions & 3 deletions gosrc/1.11.5/time/zoneinfo_read.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ package time

import (
"errors"
"runtime"
"syscall"
)

Expand Down Expand Up @@ -55,7 +56,7 @@ func (d *dataIO) big4() (n uint32, ok bool) {
d.error = true
return 0, false
}
return uint32(p[0])<<24 | uint32(p[1])<<16 | uint32(p[2])<<8 | uint32(p[3]), true
return uint32(p[3]) | uint32(p[2])<<8 | uint32(p[1])<<16 | uint32(p[0])<<24, true
}

func (d *dataIO) byte() (n byte, ok bool) {
Expand Down Expand Up @@ -172,6 +173,14 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
return nil, badData
}
zone[i].name = byteString(abbrev[b:])
if runtime.GOOS == "aix" && len(name) > 8 && (name[:8] == "Etc/GMT+" || name[:8] == "Etc/GMT-") {
// There is a bug with AIX 7.2 TL 0 with files in Etc,
// GMT+1 will return GMT-1 instead of GMT+1 or -01.
if name != "Etc/GMT+0" {
// GMT+0 is OK
zone[i].name = name[4:]
}
}
}

// Now the transition time info.
Expand Down Expand Up @@ -262,7 +271,7 @@ func get2(b []byte) int {
func loadTzinfoFromZip(zipfile, name string) ([]byte, error) {
fd, err := open(zipfile)
if err != nil {
return nil, errors.New("open " + zipfile + ": " + err.Error())
return nil, err
}
defer closefd(fd)

Expand Down Expand Up @@ -364,7 +373,7 @@ func loadTzinfoFromZip(zipfile, name string) ([]byte, error) {
return buf, nil
}

return nil, errors.New("cannot find " + name + " in zip file " + zipfile)
return nil, syscall.ENOENT
}

// loadTzinfoFromTzdata returns the time zone information of the time zone
Expand Down
2 changes: 1 addition & 1 deletion gosrc/1.11.5/time/zoneinfo_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin,386 darwin,amd64 dragonfly freebsd js,wasm linux,!android nacl netbsd openbsd solaris
// +build aix darwin,386 darwin,amd64 dragonfly freebsd linux,!android nacl netbsd openbsd solaris

// Parse "zoneinfo" time zone file.
// This is a fairly standard file format used on OS X, Linux, BSD, Sun, and others.
Expand Down

0 comments on commit 37b5a51

Please sign in to comment.