summaryrefslogtreecommitdiff
path: root/src/pkg/time
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/time')
-rw-r--r--src/pkg/time/Makefile41
-rw-r--r--src/pkg/time/format.go637
-rw-r--r--src/pkg/time/sleep.go177
-rw-r--r--src/pkg/time/sleep_test.go189
-rw-r--r--src/pkg/time/sys.go51
-rw-r--r--src/pkg/time/sys_plan9.go18
-rw-r--r--src/pkg/time/sys_posix.go18
-rw-r--r--src/pkg/time/tick.go177
-rw-r--r--src/pkg/time/tick_test.go58
-rw-r--r--src/pkg/time/time.go204
-rw-r--r--src/pkg/time/time_test.go414
-rw-r--r--src/pkg/time/zoneinfo_plan9.go59
-rw-r--r--src/pkg/time/zoneinfo_posix.go62
-rw-r--r--src/pkg/time/zoneinfo_unix.go215
-rw-r--r--src/pkg/time/zoneinfo_windows.go192
15 files changed, 0 insertions, 2512 deletions
diff --git a/src/pkg/time/Makefile b/src/pkg/time/Makefile
deleted file mode 100644
index 023e8775e..000000000
--- a/src/pkg/time/Makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2009 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-include ../../Make.inc
-
-TARG=time
-GOFILES=\
- format.go\
- sleep.go\
- sys.go\
- tick.go\
- time.go\
-
-GOFILES_freebsd=\
- sys_posix.go\
- zoneinfo_posix.go\
- zoneinfo_unix.go\
-
-GOFILES_darwin=\
- sys_posix.go\
- zoneinfo_posix.go\
- zoneinfo_unix.go\
-
-GOFILES_linux=\
- sys_posix.go\
- zoneinfo_posix.go\
- zoneinfo_unix.go\
-
-GOFILES_windows=\
- sys_posix.go\
- zoneinfo_windows.go\
-
-GOFILES_plan9=\
- sys_plan9.go\
- zoneinfo_posix.go\
- zoneinfo_plan9.go\
-
-GOFILES+=$(GOFILES_$(GOOS))
-
-include ../../Make.pkg
diff --git a/src/pkg/time/format.go b/src/pkg/time/format.go
deleted file mode 100644
index 26f40d141..000000000
--- a/src/pkg/time/format.go
+++ /dev/null
@@ -1,637 +0,0 @@
-package time
-
-import (
- "bytes"
- "os"
- "strconv"
-)
-
-const (
- numeric = iota
- alphabetic
- separator
- plus
- minus
-)
-
-// These are predefined layouts for use in Time.Format.
-// The standard time used in the layouts is:
-// Mon Jan 2 15:04:05 MST 2006 (MST is GMT-0700)
-// which is Unix time 1136243045.
-// (Think of it as 01/02 03:04:05PM '06 -0700.)
-// To define your own format, write down what the standard
-// time would look like formatted your way.
-//
-// Within the format string, an underscore _ represents a space that may be
-// replaced by a digit if the following number (a day) has two digits; for
-// compatibility with fixed-width Unix time formats.
-//
-// Numeric time zone offsets format as follows:
-// -0700 ±hhmm
-// -07:00 ±hh:mm
-// Replacing the sign in the format with a Z triggers
-// the ISO 8601 behavior of printing Z instead of an
-// offset for the UTC zone. Thus:
-// Z0700 Z or ±hhmm
-// Z07:00 Z or ±hh:mm
-const (
- ANSIC = "Mon Jan _2 15:04:05 2006"
- UnixDate = "Mon Jan _2 15:04:05 MST 2006"
- RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
- RFC822 = "02 Jan 06 1504 MST"
- // RFC822 with Zulu time.
- RFC822Z = "02 Jan 06 1504 -0700"
- RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
- RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
- RFC3339 = "2006-01-02T15:04:05Z07:00"
- Kitchen = "3:04PM"
-)
-
-const (
- stdLongMonth = "January"
- stdMonth = "Jan"
- stdNumMonth = "1"
- stdZeroMonth = "01"
- stdLongWeekDay = "Monday"
- stdWeekDay = "Mon"
- stdDay = "2"
- stdUnderDay = "_2"
- stdZeroDay = "02"
- stdHour = "15"
- stdHour12 = "3"
- stdZeroHour12 = "03"
- stdMinute = "4"
- stdZeroMinute = "04"
- stdSecond = "5"
- stdZeroSecond = "05"
- stdLongYear = "2006"
- stdYear = "06"
- stdPM = "PM"
- stdpm = "pm"
- stdTZ = "MST"
- stdISO8601TZ = "Z0700" // prints Z for UTC
- stdISO8601ColonTZ = "Z07:00" // prints Z for UTC
- stdNumTZ = "-0700" // always numeric
- stdNumShortTZ = "-07" // always numeric
- stdNumColonTZ = "-07:00" // always numeric
-)
-
-// nextStdChunk finds the first occurrence of a std string in
-// layout and returns the text before, the std string, and the text after.
-func nextStdChunk(layout string) (prefix, std, suffix string) {
- for i := 0; i < len(layout); i++ {
- switch layout[i] {
- case 'J': // January, Jan
- if len(layout) >= i+7 && layout[i:i+7] == stdLongMonth {
- return layout[0:i], stdLongMonth, layout[i+7:]
- }
- if len(layout) >= i+3 && layout[i:i+3] == stdMonth {
- return layout[0:i], stdMonth, layout[i+3:]
- }
-
- case 'M': // Monday, Mon, MST
- if len(layout) >= i+6 && layout[i:i+6] == stdLongWeekDay {
- return layout[0:i], stdLongWeekDay, layout[i+6:]
- }
- if len(layout) >= i+3 {
- if layout[i:i+3] == stdWeekDay {
- return layout[0:i], stdWeekDay, layout[i+3:]
- }
- if layout[i:i+3] == stdTZ {
- return layout[0:i], stdTZ, layout[i+3:]
- }
- }
-
- case '0': // 01, 02, 03, 04, 05, 06
- if len(layout) >= i+2 && '1' <= layout[i+1] && layout[i+1] <= '6' {
- return layout[0:i], layout[i : i+2], layout[i+2:]
- }
-
- case '1': // 15, 1
- if len(layout) >= i+2 && layout[i+1] == '5' {
- return layout[0:i], stdHour, layout[i+2:]
- }
- return layout[0:i], stdNumMonth, layout[i+1:]
-
- case '2': // 2006, 2
- if len(layout) >= i+4 && layout[i:i+4] == stdLongYear {
- return layout[0:i], stdLongYear, layout[i+4:]
- }
- return layout[0:i], stdDay, layout[i+1:]
-
- case '_': // _2
- if len(layout) >= i+2 && layout[i+1] == '2' {
- return layout[0:i], stdUnderDay, layout[i+2:]
- }
-
- case '3', '4', '5': // 3, 4, 5
- return layout[0:i], layout[i : i+1], layout[i+1:]
-
- case 'P': // PM
- if len(layout) >= i+2 && layout[i+1] == 'M' {
- return layout[0:i], layout[i : i+2], layout[i+2:]
- }
-
- case 'p': // pm
- if len(layout) >= i+2 && layout[i+1] == 'm' {
- return layout[0:i], layout[i : i+2], layout[i+2:]
- }
-
- case '-': // -0700, -07:00, -07
- if len(layout) >= i+5 && layout[i:i+5] == stdNumTZ {
- return layout[0:i], layout[i : i+5], layout[i+5:]
- }
- if len(layout) >= i+6 && layout[i:i+6] == stdNumColonTZ {
- return layout[0:i], layout[i : i+6], layout[i+6:]
- }
- if len(layout) >= i+3 && layout[i:i+3] == stdNumShortTZ {
- return layout[0:i], layout[i : i+3], layout[i+3:]
- }
- case 'Z': // Z0700, Z07:00
- if len(layout) >= i+5 && layout[i:i+5] == stdISO8601TZ {
- return layout[0:i], layout[i : i+5], layout[i+5:]
- }
- if len(layout) >= i+6 && layout[i:i+6] == stdISO8601ColonTZ {
- return layout[0:i], layout[i : i+6], layout[i+6:]
- }
- }
- }
- return layout, "", ""
-}
-
-var longDayNames = []string{
- "Sunday",
- "Monday",
- "Tuesday",
- "Wednesday",
- "Thursday",
- "Friday",
- "Saturday",
-}
-
-var shortDayNames = []string{
- "Sun",
- "Mon",
- "Tue",
- "Wed",
- "Thu",
- "Fri",
- "Sat",
-}
-
-var shortMonthNames = []string{
- "---",
- "Jan",
- "Feb",
- "Mar",
- "Apr",
- "May",
- "Jun",
- "Jul",
- "Aug",
- "Sep",
- "Oct",
- "Nov",
- "Dec",
-}
-
-var longMonthNames = []string{
- "---",
- "January",
- "February",
- "March",
- "April",
- "May",
- "June",
- "July",
- "August",
- "September",
- "October",
- "November",
- "December",
-}
-
-func lookup(tab []string, val string) (int, string, os.Error) {
- for i, v := range tab {
- if len(val) >= len(v) && val[0:len(v)] == v {
- return i, val[len(v):], nil
- }
- }
- return -1, val, errBad
-}
-
-func pad(i int, padding string) string {
- s := strconv.Itoa(i)
- if i < 10 {
- s = padding + s
- }
- return s
-}
-
-func zeroPad(i int) string { return pad(i, "0") }
-
-// Format returns a textual representation of the time value formatted
-// according to layout. The layout defines the format by showing the
-// representation of a standard time, which is then used to describe
-// the time to be formatted. Predefined layouts ANSIC, UnixDate,
-// RFC3339 and others describe standard representations. For more
-// information about the formats, see the documentation for ANSIC.
-func (t *Time) Format(layout string) string {
- b := new(bytes.Buffer)
- // Each iteration generates one std value.
- for {
- prefix, std, suffix := nextStdChunk(layout)
- b.WriteString(prefix)
- if std == "" {
- break
- }
- var p string
- switch std {
- case stdYear:
- p = zeroPad(int(t.Year % 100))
- case stdLongYear:
- p = strconv.Itoa64(t.Year)
- case stdMonth:
- p = shortMonthNames[t.Month]
- case stdLongMonth:
- p = longMonthNames[t.Month]
- case stdNumMonth:
- p = strconv.Itoa(t.Month)
- case stdZeroMonth:
- p = zeroPad(t.Month)
- case stdWeekDay:
- p = shortDayNames[t.Weekday]
- case stdLongWeekDay:
- p = longDayNames[t.Weekday]
- case stdDay:
- p = strconv.Itoa(t.Day)
- case stdUnderDay:
- p = pad(t.Day, " ")
- case stdZeroDay:
- p = zeroPad(t.Day)
- case stdHour:
- p = zeroPad(t.Hour)
- case stdHour12:
- // Noon is 12PM, midnight is 12AM.
- hr := t.Hour % 12
- if hr == 0 {
- hr = 12
- }
- p = strconv.Itoa(hr)
- case stdZeroHour12:
- // Noon is 12PM, midnight is 12AM.
- hr := t.Hour % 12
- if hr == 0 {
- hr = 12
- }
- p = zeroPad(hr)
- case stdMinute:
- p = strconv.Itoa(t.Minute)
- case stdZeroMinute:
- p = zeroPad(t.Minute)
- case stdSecond:
- p = strconv.Itoa(t.Second)
- case stdZeroSecond:
- p = zeroPad(t.Second)
- case stdISO8601TZ, stdISO8601ColonTZ, stdNumTZ, stdNumColonTZ:
- // Ugly special case. We cheat and take the "Z" variants
- // to mean "the time zone as formatted for ISO 8601".
- if t.ZoneOffset == 0 && std[0] == 'Z' {
- p = "Z"
- break
- }
- zone := t.ZoneOffset / 60 // convert to minutes
- if zone < 0 {
- p = "-"
- zone = -zone
- } else {
- p = "+"
- }
- p += zeroPad(zone / 60)
- if std == stdISO8601ColonTZ || std == stdNumColonTZ {
- p += ":"
- }
- p += zeroPad(zone % 60)
- case stdPM:
- if t.Hour >= 12 {
- p = "PM"
- } else {
- p = "AM"
- }
- case stdpm:
- if t.Hour >= 12 {
- p = "pm"
- } else {
- p = "am"
- }
- case stdTZ:
- if t.Zone != "" {
- p = t.Zone
- } else {
- // No time zone known for this time, but we must print one.
- // Use the -0700 format.
- zone := t.ZoneOffset / 60 // convert to minutes
- if zone < 0 {
- p = "-"
- zone = -zone
- } else {
- p = "+"
- }
- p += zeroPad(zone / 60)
- p += zeroPad(zone % 60)
- }
- }
- b.WriteString(p)
- layout = suffix
- }
- return b.String()
-}
-
-// String returns a Unix-style representation of the time value.
-func (t *Time) String() string {
- if t == nil {
- return "<nil>"
- }
- return t.Format(UnixDate)
-}
-
-var errBad = os.NewError("bad") // just a marker; not returned to user
-
-// ParseError describes a problem parsing a time string.
-type ParseError struct {
- Layout string
- Value string
- LayoutElem string
- ValueElem string
- Message string
-}
-
-// String is the string representation of a ParseError.
-func (e *ParseError) String() string {
- if e.Message == "" {
- return "parsing time " +
- strconv.Quote(e.Value) + " as " +
- strconv.Quote(e.Layout) + ": cannot parse " +
- strconv.Quote(e.ValueElem) + " as " +
- strconv.Quote(e.LayoutElem)
- }
- return "parsing time " +
- strconv.Quote(e.Value) + e.Message
-}
-
-// getnum parses s[0:1] or s[0:2] (fixed forces the latter)
-// as a decimal integer and returns the integer and the
-// remainder of the string.
-func getnum(s string, fixed bool) (int, string, os.Error) {
- if len(s) == 0 || s[0] < '0' || s[0] > '9' {
- return 0, s, errBad
- }
- if len(s) == 1 || s[1] < '0' || s[1] > '9' {
- if fixed {
- return 0, s, errBad
- }
- return int(s[0] - '0'), s[1:], nil
- }
- return int(s[0]-'0')*10 + int(s[1]-'0'), s[2:], nil
-}
-
-func cutspace(s string) string {
- for len(s) > 0 && s[0] == ' ' {
- s = s[1:]
- }
- return s
-}
-
-// skip removes the given prefix from value,
-// treating runs of space characters as equivalent.
-func skip(value, prefix string) (string, os.Error) {
- for len(prefix) > 0 {
- if prefix[0] == ' ' {
- if len(value) > 0 && value[0] != ' ' {
- return "", errBad
- }
- prefix = cutspace(prefix)
- value = cutspace(value)
- continue
- }
- if len(value) == 0 || value[0] != prefix[0] {
- return "", errBad
- }
- prefix = prefix[1:]
- value = value[1:]
- }
- return value, nil
-}
-
-// Parse parses a formatted string and returns the time value it represents.
-// The layout defines the format by showing the representation of a standard
-// time, which is then used to describe the string to be parsed. Predefined
-// layouts ANSIC, UnixDate, RFC3339 and others describe standard
-// representations.For more information about the formats, see the
-// documentation for ANSIC.
-//
-// Only those elements present in the value will be set in the returned time
-// structure. Also, if the input string represents an inconsistent time
-// (such as having the wrong day of the week), the returned value will also
-// be inconsistent. In any case, the elements of the returned time will be
-// sane: hours in 0..23, minutes in 0..59, day of month in 0..31, etc.
-// Years must be in the range 0000..9999.
-func Parse(alayout, avalue string) (*Time, os.Error) {
- var t Time
- rangeErrString := "" // set if a value is out of range
- amSet := false // do we need to subtract 12 from the hour for midnight?
- pmSet := false // do we need to add 12 to the hour?
- layout, value := alayout, avalue
- // Each iteration processes one std value.
- for {
- var err os.Error
- prefix, std, suffix := nextStdChunk(layout)
- value, err = skip(value, prefix)
- if err != nil {
- return nil, &ParseError{alayout, avalue, prefix, value, ""}
- }
- if len(std) == 0 {
- if len(value) != 0 {
- return nil, &ParseError{alayout, avalue, "", value, ": extra text: " + value}
- }
- break
- }
- layout = suffix
- var p string
- switch std {
- case stdYear:
- if len(value) < 2 {
- err = errBad
- break
- }
- p, value = value[0:2], value[2:]
- t.Year, err = strconv.Atoi64(p)
- if t.Year >= 69 { // Unix time starts Dec 31 1969 in some time zones
- t.Year += 1900
- } else {
- t.Year += 2000
- }
- case stdLongYear:
- if len(value) < 4 || value[0] < '0' || value[0] > '9' {
- err = errBad
- break
- }
- p, value = value[0:4], value[4:]
- t.Year, err = strconv.Atoi64(p)
- case stdMonth:
- t.Month, value, err = lookup(shortMonthNames, value)
- case stdLongMonth:
- t.Month, value, err = lookup(longMonthNames, value)
- case stdNumMonth, stdZeroMonth:
- t.Month, value, err = getnum(value, std == stdZeroMonth)
- if t.Month <= 0 || 12 < t.Month {
- rangeErrString = "month"
- }
- case stdWeekDay:
- t.Weekday, value, err = lookup(shortDayNames, value)
- case stdLongWeekDay:
- t.Weekday, value, err = lookup(longDayNames, value)
- case stdDay, stdUnderDay, stdZeroDay:
- if std == stdUnderDay && len(value) > 0 && value[0] == ' ' {
- value = value[1:]
- }
- t.Day, value, err = getnum(value, std == stdZeroDay)
- if t.Day < 0 || 31 < t.Day {
- // TODO: be more thorough in date check?
- rangeErrString = "day"
- }
- case stdHour:
- t.Hour, value, err = getnum(value, false)
- if t.Hour < 0 || 24 <= t.Hour {
- rangeErrString = "hour"
- }
- case stdHour12, stdZeroHour12:
- t.Hour, value, err = getnum(value, std == stdZeroHour12)
- if t.Hour < 0 || 12 < t.Hour {
- rangeErrString = "hour"
- }
- case stdMinute, stdZeroMinute:
- t.Minute, value, err = getnum(value, std == stdZeroMinute)
- if t.Minute < 0 || 60 <= t.Minute {
- rangeErrString = "minute"
- }
- case stdSecond, stdZeroSecond:
- t.Second, value, err = getnum(value, std == stdZeroSecond)
- if t.Second < 0 || 60 <= t.Second {
- rangeErrString = "second"
- }
- case stdISO8601TZ, stdISO8601ColonTZ, stdNumTZ, stdNumShortTZ, stdNumColonTZ:
- if std[0] == 'Z' && len(value) >= 1 && value[0] == 'Z' {
- value = value[1:]
- t.Zone = "UTC"
- break
- }
- var sign, hh, mm string
- if std == stdISO8601ColonTZ || std == stdNumColonTZ {
- if len(value) < 6 {
- err = errBad
- break
- }
- if value[3] != ':' {
- err = errBad
- break
- }
- sign, hh, mm, value = value[0:1], value[1:3], value[4:6], value[6:]
- } else if std == stdNumShortTZ {
- if len(value) < 3 {
- err = errBad
- break
- }
- sign, hh, mm, value = value[0:1], value[1:3], "00", value[3:]
- } else {
- if len(value) < 5 {
- err = errBad
- break
- }
- sign, hh, mm, value = value[0:1], value[1:3], value[3:5], value[5:]
- }
- var hr, min int
- hr, err = strconv.Atoi(hh)
- if err == nil {
- min, err = strconv.Atoi(mm)
- }
- t.ZoneOffset = (hr*60 + min) * 60 // offset is in seconds
- switch sign[0] {
- case '+':
- case '-':
- t.ZoneOffset = -t.ZoneOffset
- default:
- err = errBad
- }
- case stdPM:
- if len(value) < 2 {
- err = errBad
- break
- }
- p, value = value[0:2], value[2:]
- switch p {
- case "PM":
- pmSet = true
- case "AM":
- amSet = true
- default:
- err = errBad
- }
- case stdpm:
- if len(value) < 2 {
- err = errBad
- break
- }
- p, value = value[0:2], value[2:]
- switch p {
- case "pm":
- pmSet = true
- case "am":
- amSet = true
- default:
- err = errBad
- }
- case stdTZ:
- // Does it look like a time zone?
- if len(value) >= 3 && value[0:3] == "UTC" {
- t.Zone, value = value[0:3], value[3:]
- break
- }
-
- if len(value) >= 3 && value[2] == 'T' {
- p, value = value[0:3], value[3:]
- } else if len(value) >= 4 && value[3] == 'T' {
- p, value = value[0:4], value[4:]
- } else {
- err = errBad
- break
- }
- for i := 0; i < len(p); i++ {
- if p[i] < 'A' || 'Z' < p[i] {
- err = errBad
- }
- }
- if err != nil {
- break
- }
- // It's a valid format.
- t.Zone = p
- // Can we find its offset?
- if offset, found := lookupByName(p); found {
- t.ZoneOffset = offset
- }
- }
- if rangeErrString != "" {
- return nil, &ParseError{alayout, avalue, std, value, ": " + rangeErrString + " out of range"}
- }
- if err != nil {
- return nil, &ParseError{alayout, avalue, std, value, ""}
- }
- }
- if pmSet && t.Hour < 12 {
- t.Hour += 12
- } else if amSet && t.Hour == 12 {
- t.Hour = 0
- }
- return &t, nil
-}
diff --git a/src/pkg/time/sleep.go b/src/pkg/time/sleep.go
deleted file mode 100644
index 314622d0d..000000000
--- a/src/pkg/time/sleep.go
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time
-
-import (
- "container/heap"
- "sync"
-)
-
-// The Timer type represents a single event.
-// When the Timer expires, the current time will be sent on C
-// unless the Timer represents an AfterFunc event.
-type Timer struct {
- C <-chan int64
- t int64 // The absolute time that the event should fire.
- f func(int64) // The function to call when the event fires.
- i int // The event's index inside eventHeap.
-}
-
-type timerHeap []*Timer
-
-// forever is the absolute time (in ns) of an event that is forever away.
-const forever = 1 << 62
-
-// maxSleepTime is the maximum length of time that a sleeper
-// sleeps for before checking if it is defunct.
-const maxSleepTime = 1e9
-
-var (
- // timerMutex guards the variables inside this var group.
- timerMutex sync.Mutex
-
- // timers holds a binary heap of pending events, terminated with a sentinel.
- timers timerHeap
-
- // currentSleeper is an ever-incrementing counter which represents
- // the current sleeper. It allows older sleepers to detect that they are
- // defunct and exit.
- currentSleeper int64
-)
-
-func init() {
- timers.Push(&Timer{t: forever}) // sentinel
-}
-
-// NewTimer creates a new Timer that will send
-// the current time on its channel after at least ns nanoseconds.
-func NewTimer(ns int64) *Timer {
- c := make(chan int64, 1)
- e := after(ns, func(t int64) { c <- t })
- e.C = c
- return e
-}
-
-// After waits at least ns nanoseconds before sending the current time
-// on the returned channel.
-// It is equivalent to NewTimer(ns).C.
-func After(ns int64) <-chan int64 {
- return NewTimer(ns).C
-}
-
-// AfterFunc waits at least ns nanoseconds before calling f
-// in its own goroutine. It returns a Timer that can
-// be used to cancel the call using its Stop method.
-func AfterFunc(ns int64, f func()) *Timer {
- return after(ns, func(_ int64) {
- go f()
- })
-}
-
-// Stop prevents the Timer from firing.
-// It returns true if the call stops the timer, false if the timer has already
-// expired or stopped.
-func (e *Timer) Stop() (ok bool) {
- timerMutex.Lock()
- // Avoid removing the first event in the queue so that
- // we don't start a new sleeper unnecessarily.
- if e.i > 0 {
- heap.Remove(timers, e.i)
- }
- ok = e.f != nil
- e.f = nil
- timerMutex.Unlock()
- return
-}
-
-// after is the implementation of After and AfterFunc.
-// When the current time is after ns, it calls f with the current time.
-// It assumes that f will not block.
-func after(ns int64, f func(int64)) (e *Timer) {
- now := Nanoseconds()
- t := now + ns
- if ns > 0 && t < now {
- panic("time: time overflow")
- }
- timerMutex.Lock()
- t0 := timers[0].t
- e = &Timer{nil, t, f, -1}
- heap.Push(timers, e)
- // Start a new sleeper if the new event is before
- // the first event in the queue. If the length of time
- // until the new event is at least maxSleepTime,
- // then we're guaranteed that the sleeper will wake up
- // in time to service it, so no new sleeper is needed.
- if t0 > t && (t0 == forever || ns < maxSleepTime) {
- currentSleeper++
- go sleeper(currentSleeper)
- }
- timerMutex.Unlock()
- return
-}
-
-// sleeper continually looks at the earliest event in the queue, waits until it happens,
-// then removes any events in the queue that are due. It stops when the queue
-// is empty or when another sleeper has been started.
-func sleeper(sleeperId int64) {
- timerMutex.Lock()
- e := timers[0]
- t := Nanoseconds()
- for e.t != forever {
- if dt := e.t - t; dt > 0 {
- if dt > maxSleepTime {
- dt = maxSleepTime
- }
- timerMutex.Unlock()
- sysSleep(dt)
- timerMutex.Lock()
- if currentSleeper != sleeperId {
- // Another sleeper has been started, making this one redundant.
- break
- }
- }
- e = timers[0]
- t = Nanoseconds()
- for t >= e.t {
- if e.f != nil {
- e.f(t)
- e.f = nil
- }
- heap.Pop(timers)
- e = timers[0]
- }
- }
- timerMutex.Unlock()
-}
-
-func (timerHeap) Len() int {
- return len(timers)
-}
-
-func (timerHeap) Less(i, j int) bool {
- return timers[i].t < timers[j].t
-}
-
-func (timerHeap) Swap(i, j int) {
- timers[i], timers[j] = timers[j], timers[i]
- timers[i].i = i
- timers[j].i = j
-}
-
-func (timerHeap) Push(x interface{}) {
- e := x.(*Timer)
- e.i = len(timers)
- timers = append(timers, e)
-}
-
-func (timerHeap) Pop() interface{} {
- // TODO: possibly shrink array.
- n := len(timers) - 1
- e := timers[n]
- timers[n] = nil
- timers = timers[0:n]
- e.i = -1
- return e
-}
diff --git a/src/pkg/time/sleep_test.go b/src/pkg/time/sleep_test.go
deleted file mode 100644
index a4a1a429f..000000000
--- a/src/pkg/time/sleep_test.go
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time_test
-
-import (
- "fmt"
- "os"
- "syscall"
- "testing"
- "sort"
- . "time"
-)
-
-func TestSleep(t *testing.T) {
- const delay = int64(100e6)
- go func() {
- Sleep(delay / 2)
- syscall.Kill(os.Getpid(), syscall.SIGCHLD)
- }()
- start := Nanoseconds()
- Sleep(delay)
- duration := Nanoseconds() - start
- if duration < delay {
- t.Fatalf("Sleep(%d) slept for only %d ns", delay, duration)
- }
-}
-
-// Test the basic function calling behavior. Correct queueing
-// behavior is tested elsewhere, since After and AfterFunc share
-// the same code.
-func TestAfterFunc(t *testing.T) {
- i := 10
- c := make(chan bool)
- var f func()
- f = func() {
- i--
- if i >= 0 {
- AfterFunc(0, f)
- Sleep(1e9)
- } else {
- c <- true
- }
- }
-
- AfterFunc(0, f)
- <-c
-}
-
-func BenchmarkAfterFunc(b *testing.B) {
- i := b.N
- c := make(chan bool)
- var f func()
- f = func() {
- i--
- if i >= 0 {
- AfterFunc(0, f)
- } else {
- c <- true
- }
- }
-
- AfterFunc(0, f)
- <-c
-}
-
-func BenchmarkAfter(b *testing.B) {
- for i := 0; i < b.N; i++ {
- <-After(1)
- }
-}
-
-func BenchmarkStop(b *testing.B) {
- for i := 0; i < b.N; i++ {
- NewTimer(1e9).Stop()
- }
-}
-
-func TestAfter(t *testing.T) {
- const delay = int64(100e6)
- start := Nanoseconds()
- end := <-After(delay)
- if duration := Nanoseconds() - start; duration < delay {
- t.Fatalf("After(%d) slept for only %d ns", delay, duration)
- }
- if min := start + delay; end < min {
- t.Fatalf("After(%d) expect >= %d, got %d", delay, min, end)
- }
-}
-
-func TestAfterTick(t *testing.T) {
- const (
- Delta = 100 * 1e6
- Count = 10
- )
- t0 := Nanoseconds()
- for i := 0; i < Count; i++ {
- <-After(Delta)
- }
- t1 := Nanoseconds()
- ns := t1 - t0
- target := int64(Delta * Count)
- slop := target * 2 / 10
- if ns < target-slop || ns > target+slop {
- t.Fatalf("%d ticks of %g ns took %g ns, expected %g", Count, float64(Delta), float64(ns), float64(target))
- }
-}
-
-func TestAfterStop(t *testing.T) {
- const msec = 1e6
- AfterFunc(100*msec, func() {})
- t0 := NewTimer(50 * msec)
- c1 := make(chan bool, 1)
- t1 := AfterFunc(150*msec, func() { c1 <- true })
- c2 := After(200 * msec)
- if !t0.Stop() {
- t.Fatalf("failed to stop event 0")
- }
- if !t1.Stop() {
- t.Fatalf("failed to stop event 1")
- }
- <-c2
- select {
- case <-t0.C:
- t.Fatalf("event 0 was not stopped")
- case <-c1:
- t.Fatalf("event 1 was not stopped")
- default:
- }
- if t1.Stop() {
- t.Fatalf("Stop returned true twice")
- }
-}
-
-func TestAfterQueuing(t *testing.T) {
- // This test flakes out on some systems,
- // so we'll try it a few times before declaring it a failure.
- const attempts = 3
- err := os.NewError("!=nil")
- for i := 0; i < attempts && err != nil; i++ {
- if err = testAfterQueuing(t); err != nil {
- t.Logf("attempt %v failed: %v", i, err)
- }
- }
- if err != nil {
- t.Fatal(err)
- }
-}
-
-var slots = []int{5, 3, 6, 6, 6, 1, 1, 2, 7, 9, 4, 8, 0}
-
-type afterResult struct {
- slot int
- t int64
-}
-
-func await(slot int, result chan<- afterResult, ac <-chan int64) {
- result <- afterResult{slot, <-ac}
-}
-
-func testAfterQueuing(t *testing.T) os.Error {
- const (
- Delta = 100 * 1e6
- )
- // make the result channel buffered because we don't want
- // to depend on channel queueing semantics that might
- // possibly change in the future.
- result := make(chan afterResult, len(slots))
-
- t0 := Nanoseconds()
- for _, slot := range slots {
- go await(slot, result, After(int64(slot)*Delta))
- }
- sort.Ints(slots)
- for _, slot := range slots {
- r := <-result
- if r.slot != slot {
- return fmt.Errorf("after queue got slot %d, expected %d", r.slot, slot)
- }
- ns := r.t - t0
- target := int64(slot * Delta)
- slop := int64(Delta) / 4
- if ns < target-slop || ns > target+slop {
- return fmt.Errorf("after queue slot %d arrived at %g, expected [%g,%g]", slot, float64(ns), float64(target-slop), float64(target+slop))
- }
- }
- return nil
-}
diff --git a/src/pkg/time/sys.go b/src/pkg/time/sys.go
deleted file mode 100644
index 9fde3b3b6..000000000
--- a/src/pkg/time/sys.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time
-
-import "os"
-
-// Seconds reports the number of seconds since the Unix epoch,
-// January 1, 1970 00:00:00 UTC.
-func Seconds() int64 {
- sec, _, err := os.Time()
- if err != nil {
- panic(err)
- }
- return sec
-}
-
-// Nanoseconds reports the number of nanoseconds since the Unix epoch,
-// January 1, 1970 00:00:00 UTC.
-func Nanoseconds() int64 {
- sec, nsec, err := os.Time()
- if err != nil {
- panic(err)
- }
- return sec*1e9 + nsec
-}
-
-// Sleep pauses the current goroutine for at least ns nanoseconds.
-// Higher resolution sleeping may be provided by syscall.Nanosleep
-// on some operating systems.
-func Sleep(ns int64) os.Error {
- _, err := sleep(Nanoseconds(), ns)
- return err
-}
-
-// sleep takes the current time and a duration,
-// pauses for at least ns nanoseconds, and
-// returns the current time and an error.
-func sleep(t, ns int64) (int64, os.Error) {
- // TODO(cw): use monotonic-time once it's available
- end := t + ns
- for t < end {
- err := sysSleep(end - t)
- if err != nil {
- return 0, err
- }
- t = Nanoseconds()
- }
- return t, nil
-}
diff --git a/src/pkg/time/sys_plan9.go b/src/pkg/time/sys_plan9.go
deleted file mode 100644
index abe8649a2..000000000
--- a/src/pkg/time/sys_plan9.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time
-
-import (
- "os"
- "syscall"
-)
-
-func sysSleep(t int64) os.Error {
- err := syscall.Sleep(t)
- if err != nil {
- return os.NewSyscallError("sleep", err)
- }
- return nil
-}
diff --git a/src/pkg/time/sys_posix.go b/src/pkg/time/sys_posix.go
deleted file mode 100644
index 0d1eb72fc..000000000
--- a/src/pkg/time/sys_posix.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time
-
-import (
- "os"
- "syscall"
-)
-
-func sysSleep(t int64) os.Error {
- errno := syscall.Sleep(t)
- if errno != 0 && errno != syscall.EINTR {
- return os.NewSyscallError("sleep", errno)
- }
- return nil
-}
diff --git a/src/pkg/time/tick.go b/src/pkg/time/tick.go
deleted file mode 100644
index 852bae9c9..000000000
--- a/src/pkg/time/tick.go
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time
-
-import (
- "os"
- "sync"
-)
-
-// A Ticker holds a synchronous channel that delivers `ticks' of a clock
-// at intervals.
-type Ticker struct {
- C <-chan int64 // The channel on which the ticks are delivered.
- c chan<- int64 // The same channel, but the end we use.
- ns int64
- shutdown chan bool // Buffered channel used to signal shutdown.
- nextTick int64
- next *Ticker
-}
-
-// Stop turns off a ticker. After Stop, no more ticks will be sent.
-func (t *Ticker) Stop() {
- select {
- case t.shutdown <- true:
- // ok
- default:
- // Stop in progress already
- }
-}
-
-// Tick is a convenience wrapper for NewTicker providing access to the ticking
-// channel only. Useful for clients that have no need to shut down the ticker.
-func Tick(ns int64) <-chan int64 {
- if ns <= 0 {
- return nil
- }
- return NewTicker(ns).C
-}
-
-type alarmer struct {
- wakeUp chan bool // wakeup signals sent/received here
- wakeMeAt chan int64
- wakeTime int64
-}
-
-// Set alarm to go off at time ns, if not already set earlier.
-func (a *alarmer) set(ns int64) {
- switch {
- case a.wakeTime > ns:
- // Next tick we expect is too late; shut down the late runner
- // and (after fallthrough) start a new wakeLoop.
- close(a.wakeMeAt)
- fallthrough
- case a.wakeMeAt == nil:
- // There's no wakeLoop, start one.
- a.wakeMeAt = make(chan int64)
- a.wakeUp = make(chan bool, 1)
- go wakeLoop(a.wakeMeAt, a.wakeUp)
- fallthrough
- case a.wakeTime == 0:
- // Nobody else is waiting; it's just us.
- a.wakeTime = ns
- a.wakeMeAt <- ns
- default:
- // There's already someone scheduled.
- }
-}
-
-// Channel to notify tickerLoop of new Tickers being created.
-var newTicker chan *Ticker
-
-func startTickerLoop() {
- newTicker = make(chan *Ticker)
- go tickerLoop()
-}
-
-// wakeLoop delivers ticks at scheduled times, sleeping until the right moment.
-// If another, earlier Ticker is created while it sleeps, tickerLoop() will start a new
-// wakeLoop and signal that this one is done by closing the wakeMeAt channel.
-func wakeLoop(wakeMeAt chan int64, wakeUp chan bool) {
- for wakeAt := range wakeMeAt {
- Sleep(wakeAt - Nanoseconds())
- wakeUp <- true
- }
-}
-
-// A single tickerLoop serves all ticks to Tickers. It waits for two events:
-// either the creation of a new Ticker or a tick from the alarm,
-// signaling a time to wake up one or more Tickers.
-func tickerLoop() {
- // Represents the next alarm to be delivered.
- var alarm alarmer
- var now, wakeTime int64
- var tickers *Ticker
- for {
- select {
- case t := <-newTicker:
- // Add Ticker to list
- t.next = tickers
- tickers = t
- // Arrange for a new alarm if this one precedes the existing one.
- alarm.set(t.nextTick)
- case <-alarm.wakeUp:
- now = Nanoseconds()
- wakeTime = now + 1e15 // very long in the future
- var prev *Ticker = nil
- // Scan list of tickers, delivering updates to those
- // that need it and determining the next wake time.
- // TODO(r): list should be sorted in time order.
- for t := tickers; t != nil; t = t.next {
- select {
- case <-t.shutdown:
- // Ticker is done; remove it from list.
- if prev == nil {
- tickers = t.next
- } else {
- prev.next = t.next
- }
- continue
- default:
- }
- if t.nextTick <= now {
- if len(t.c) == 0 {
- // Only send if there's room. We must not block.
- // The channel is allocated with a one-element
- // buffer, which is sufficient: if he hasn't picked
- // up the last tick, no point in sending more.
- t.c <- now
- }
- t.nextTick += t.ns
- if t.nextTick <= now {
- // Still behind; advance in one big step.
- t.nextTick += (now - t.nextTick + t.ns) / t.ns * t.ns
- }
- }
- if t.nextTick < wakeTime {
- wakeTime = t.nextTick
- }
- prev = t
- }
- if tickers != nil {
- // Please send wakeup at earliest required time.
- // If there are no tickers, don't bother.
- alarm.wakeTime = wakeTime
- alarm.wakeMeAt <- wakeTime
- } else {
- alarm.wakeTime = 0
- }
- }
- }
-}
-
-var onceStartTickerLoop sync.Once
-
-// NewTicker returns a new Ticker containing a channel that will
-// send the time, in nanoseconds, every ns nanoseconds. It adjusts the
-// intervals to make up for pauses in delivery of the ticks. The value of
-// ns must be greater than zero; if not, NewTicker will panic.
-func NewTicker(ns int64) *Ticker {
- if ns <= 0 {
- panic(os.NewError("non-positive interval for NewTicker"))
- }
- c := make(chan int64, 1) // See comment on send in tickerLoop
- t := &Ticker{
- C: c,
- c: c,
- ns: ns,
- shutdown: make(chan bool, 1),
- nextTick: Nanoseconds() + ns,
- }
- onceStartTickerLoop.Do(startTickerLoop)
- // must be run in background so global Tickers can be created
- go func() { newTicker <- t }()
- return t
-}
diff --git a/src/pkg/time/tick_test.go b/src/pkg/time/tick_test.go
deleted file mode 100644
index 4dcb63956..000000000
--- a/src/pkg/time/tick_test.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time_test
-
-import (
- "testing"
- . "time"
-)
-
-func TestTicker(t *testing.T) {
- const (
- Delta = 100 * 1e6
- Count = 10
- )
- ticker := NewTicker(Delta)
- t0 := Nanoseconds()
- for i := 0; i < Count; i++ {
- <-ticker.C
- }
- ticker.Stop()
- t1 := Nanoseconds()
- ns := t1 - t0
- target := int64(Delta * Count)
- slop := target * 2 / 10
- if ns < target-slop || ns > target+slop {
- t.Fatalf("%d ticks of %g ns took %g ns, expected %g", Count, float64(Delta), float64(ns), float64(target))
- }
- // Now test that the ticker stopped
- Sleep(2 * Delta)
- select {
- case <-ticker.C:
- t.Fatal("Ticker did not shut down")
- default:
- // ok
- }
-}
-
-// Test that a bug tearing down a ticker has been fixed. This routine should not deadlock.
-func TestTeardown(t *testing.T) {
- for i := 0; i < 3; i++ {
- ticker := NewTicker(1e8)
- <-ticker.C
- ticker.Stop()
- }
-}
-
-func BenchmarkTicker(b *testing.B) {
- ticker := NewTicker(1)
- b.ResetTimer()
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- <-ticker.C
- }
- b.StopTimer()
- ticker.Stop()
-}
diff --git a/src/pkg/time/time.go b/src/pkg/time/time.go
deleted file mode 100644
index a0480786a..000000000
--- a/src/pkg/time/time.go
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package time provides functionality for measuring and displaying time.
-package time
-
-// Days of the week.
-const (
- Sunday = iota
- Monday
- Tuesday
- Wednesday
- Thursday
- Friday
- Saturday
-)
-
-// Time is the struct representing a parsed time value.
-type Time struct {
- Year int64 // 2006 is 2006
- Month, Day int // Jan-2 is 1, 2
- Hour, Minute, Second int // 15:04:05 is 15, 4, 5.
- Weekday int // Sunday, Monday, ...
- ZoneOffset int // seconds east of UTC, e.g. -7*60*60 for -0700
- Zone string // e.g., "MST"
-}
-
-var nonleapyear = []int{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
-var leapyear = []int{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
-
-func months(year int64) []int {
- if year%4 == 0 && (year%100 != 0 || year%400 == 0) {
- return leapyear
- }
- return nonleapyear
-}
-
-const (
- secondsPerDay = 24 * 60 * 60
- daysPer400Years = 365*400 + 97
- daysPer100Years = 365*100 + 24
- daysPer4Years = 365*4 + 1
- days1970To2001 = 31*365 + 8
-)
-
-// SecondsToUTC converts sec, in number of seconds since the Unix epoch,
-// into a parsed Time value in the UTC time zone.
-func SecondsToUTC(sec int64) *Time {
- t := new(Time)
-
- // Split into time and day.
- day := sec / secondsPerDay
- sec -= day * secondsPerDay
- if sec < 0 {
- day--
- sec += secondsPerDay
- }
-
- // Time
- t.Hour = int(sec / 3600)
- t.Minute = int((sec / 60) % 60)
- t.Second = int(sec % 60)
-
- // Day 0 = January 1, 1970 was a Thursday
- t.Weekday = int((day + Thursday) % 7)
- if t.Weekday < 0 {
- t.Weekday += 7
- }
-
- // Change day from 0 = 1970 to 0 = 2001,
- // to make leap year calculations easier
- // (2001 begins 4-, 100-, and 400-year cycles ending in a leap year.)
- day -= days1970To2001
-
- year := int64(2001)
- if day < 0 {
- // Go back enough 400 year cycles to make day positive.
- n := -day/daysPer400Years + 1
- year -= 400 * n
- day += daysPer400Years * n
- }
-
- // Cut off 400 year cycles.
- n := day / daysPer400Years
- year += 400 * n
- day -= daysPer400Years * n
-
- // Cut off 100-year cycles
- n = day / daysPer100Years
- if n > 3 { // happens on last day of 400th year
- n = 3
- }
- year += 100 * n
- day -= daysPer100Years * n
-
- // Cut off 4-year cycles
- n = day / daysPer4Years
- if n > 24 { // happens on last day of 100th year
- n = 24
- }
- year += 4 * n
- day -= daysPer4Years * n
-
- // Cut off non-leap years.
- n = day / 365
- if n > 3 { // happens on last day of 4th year
- n = 3
- }
- year += n
- day -= 365 * n
-
- t.Year = year
-
- // If someone ever needs yearday,
- // tyearday = day (+1?)
-
- months := months(year)
- var m int
- yday := int(day)
- for m = 0; m < 12 && yday >= months[m]; m++ {
- yday -= months[m]
- }
- t.Month = m + 1
- t.Day = yday + 1
- t.Zone = "UTC"
-
- return t
-}
-
-// UTC returns the current time as a parsed Time value in the UTC time zone.
-func UTC() *Time { return SecondsToUTC(Seconds()) }
-
-// SecondsToLocalTime converts sec, in number of seconds since the Unix epoch,
-// into a parsed Time value in the local time zone.
-func SecondsToLocalTime(sec int64) *Time {
- z, offset := lookupTimezone(sec)
- t := SecondsToUTC(sec + int64(offset))
- t.Zone = z
- t.ZoneOffset = offset
- return t
-}
-
-// LocalTime returns the current time as a parsed Time value in the local time zone.
-func LocalTime() *Time { return SecondsToLocalTime(Seconds()) }
-
-// Seconds returns the number of seconds since January 1, 1970 represented by the
-// parsed Time value.
-func (t *Time) Seconds() int64 {
- // First, accumulate days since January 1, 2001.
- // Using 2001 instead of 1970 makes the leap-year
- // handling easier (see SecondsToUTC), because
- // it is at the beginning of the 4-, 100-, and 400-year cycles.
- day := int64(0)
-
- // Rewrite year to be >= 2001.
- year := t.Year
- if year < 2001 {
- n := (2001-year)/400 + 1
- year += 400 * n
- day -= daysPer400Years * n
- }
-
- // Add in days from 400-year cycles.
- n := (year - 2001) / 400
- year -= 400 * n
- day += daysPer400Years * n
-
- // Add in 100-year cycles.
- n = (year - 2001) / 100
- year -= 100 * n
- day += daysPer100Years * n
-
- // Add in 4-year cycles.
- n = (year - 2001) / 4
- year -= 4 * n
- day += daysPer4Years * n
-
- // Add in non-leap years.
- n = year - 2001
- day += 365 * n
-
- // Add in days this year.
- months := months(t.Year)
- for m := 0; m < t.Month-1; m++ {
- day += int64(months[m])
- }
- day += int64(t.Day - 1)
-
- // Convert days to seconds since January 1, 2001.
- sec := day * secondsPerDay
-
- // Add in time elapsed today.
- sec += int64(t.Hour) * 3600
- sec += int64(t.Minute) * 60
- sec += int64(t.Second)
-
- // Convert from seconds since 2001 to seconds since 1970.
- sec += days1970To2001 * secondsPerDay
-
- // Account for local time zone.
- sec -= int64(t.ZoneOffset)
- return sec
-}
diff --git a/src/pkg/time/time_test.go b/src/pkg/time/time_test.go
deleted file mode 100644
index eec8a7a5c..000000000
--- a/src/pkg/time/time_test.go
+++ /dev/null
@@ -1,414 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time_test
-
-import (
- "os"
- "strings"
- "testing"
- "testing/quick"
- . "time"
-)
-
-func init() {
- // Force US Pacific time for daylight-savings
- // tests below (localtests). Needs to be set
- // before the first call into the time library.
- os.Setenv("TZ", "America/Los_Angeles")
-}
-
-// We should be in PST/PDT, but if the time zone files are missing we
-// won't be. The purpose of this test is to at least explain why some of
-// the subsequent tests fail.
-func TestZoneData(t *testing.T) {
- lt := LocalTime()
- // PST is 8 hours west, PDT is 7 hours west. We could use the name but it's not unique.
- if off := lt.ZoneOffset; off != -8*60*60 && off != -7*60*60 {
- t.Errorf("Unable to find US Pacific time zone data for testing; time zone is %q offset %d", lt.Zone, off)
- t.Error("Likely problem: the time zone files have not been installed.")
- }
-}
-
-type TimeTest struct {
- seconds int64
- golden Time
-}
-
-var utctests = []TimeTest{
- {0, Time{1970, 1, 1, 0, 0, 0, Thursday, 0, "UTC"}},
- {1221681866, Time{2008, 9, 17, 20, 4, 26, Wednesday, 0, "UTC"}},
- {-1221681866, Time{1931, 4, 16, 3, 55, 34, Thursday, 0, "UTC"}},
- {-11644473600, Time{1601, 1, 1, 0, 0, 0, Monday, 0, "UTC"}},
- {599529660, Time{1988, 12, 31, 0, 1, 0, Saturday, 0, "UTC"}},
- {978220860, Time{2000, 12, 31, 0, 1, 0, Sunday, 0, "UTC"}},
- {1e18, Time{31688740476, 10, 23, 1, 46, 40, Friday, 0, "UTC"}},
- {-1e18, Time{-31688736537, 3, 10, 22, 13, 20, Tuesday, 0, "UTC"}},
- {0x7fffffffffffffff, Time{292277026596, 12, 4, 15, 30, 7, Sunday, 0, "UTC"}},
- {-0x8000000000000000, Time{-292277022657, 1, 27, 8, 29, 52, Sunday, 0, "UTC"}},
-}
-
-var localtests = []TimeTest{
- {0, Time{1969, 12, 31, 16, 0, 0, Wednesday, -8 * 60 * 60, "PST"}},
- {1221681866, Time{2008, 9, 17, 13, 4, 26, Wednesday, -7 * 60 * 60, "PDT"}},
-}
-
-func same(t, u *Time) bool {
- return t.Year == u.Year &&
- t.Month == u.Month &&
- t.Day == u.Day &&
- t.Hour == u.Hour &&
- t.Minute == u.Minute &&
- t.Second == u.Second &&
- t.Weekday == u.Weekday &&
- t.ZoneOffset == u.ZoneOffset &&
- t.Zone == u.Zone
-}
-
-func TestSecondsToUTC(t *testing.T) {
- for i := 0; i < len(utctests); i++ {
- sec := utctests[i].seconds
- golden := &utctests[i].golden
- tm := SecondsToUTC(sec)
- newsec := tm.Seconds()
- if newsec != sec {
- t.Errorf("SecondsToUTC(%d).Seconds() = %d", sec, newsec)
- }
- if !same(tm, golden) {
- t.Errorf("SecondsToUTC(%d):", sec)
- t.Errorf(" want=%+v", *golden)
- t.Errorf(" have=%+v", *tm)
- }
- }
-}
-
-func TestSecondsToLocalTime(t *testing.T) {
- for i := 0; i < len(localtests); i++ {
- sec := localtests[i].seconds
- golden := &localtests[i].golden
- tm := SecondsToLocalTime(sec)
- newsec := tm.Seconds()
- if newsec != sec {
- t.Errorf("SecondsToLocalTime(%d).Seconds() = %d", sec, newsec)
- }
- if !same(tm, golden) {
- t.Errorf("SecondsToLocalTime(%d):", sec)
- t.Errorf(" want=%+v", *golden)
- t.Errorf(" have=%+v", *tm)
- }
- }
-}
-
-func TestSecondsToUTCAndBack(t *testing.T) {
- f := func(sec int64) bool { return SecondsToUTC(sec).Seconds() == sec }
- f32 := func(sec int32) bool { return f(int64(sec)) }
- cfg := &quick.Config{MaxCount: 10000}
-
- // Try a reasonable date first, then the huge ones.
- if err := quick.Check(f32, cfg); err != nil {
- t.Fatal(err)
- }
- if err := quick.Check(f, cfg); err != nil {
- t.Fatal(err)
- }
-}
-
-type TimeFormatTest struct {
- time Time
- formattedValue string
-}
-
-var rfc3339Formats = []TimeFormatTest{
- {Time{2008, 9, 17, 20, 4, 26, Wednesday, 0, "UTC"}, "2008-09-17T20:04:26Z"},
- {Time{1994, 9, 17, 20, 4, 26, Wednesday, -18000, "EST"}, "1994-09-17T20:04:26-05:00"},
- {Time{2000, 12, 26, 1, 15, 6, Wednesday, 15600, "OTO"}, "2000-12-26T01:15:06+04:20"},
-}
-
-func TestRFC3339Conversion(t *testing.T) {
- for _, f := range rfc3339Formats {
- if f.time.Format(RFC3339) != f.formattedValue {
- t.Error("RFC3339:")
- t.Errorf(" want=%+v", f.formattedValue)
- t.Errorf(" have=%+v", f.time.Format(RFC3339))
- }
- }
-}
-
-type FormatTest struct {
- name string
- format string
- result string
-}
-
-var formatTests = []FormatTest{
- {"ANSIC", ANSIC, "Wed Feb 4 21:00:57 2009"},
- {"UnixDate", UnixDate, "Wed Feb 4 21:00:57 PST 2009"},
- {"RubyDate", RubyDate, "Wed Feb 04 21:00:57 -0800 2009"},
- {"RFC822", RFC822, "04 Feb 09 2100 PST"},
- {"RFC850", RFC850, "Wednesday, 04-Feb-09 21:00:57 PST"},
- {"RFC1123", RFC1123, "Wed, 04 Feb 2009 21:00:57 PST"},
- {"RFC3339", RFC3339, "2009-02-04T21:00:57-08:00"},
- {"Kitchen", Kitchen, "9:00PM"},
- {"am/pm", "3pm", "9pm"},
- {"AM/PM", "3PM", "9PM"},
- {"two-digit year", "06 01 02", "09 02 04"},
-}
-
-func TestFormat(t *testing.T) {
- // The numeric time represents Thu Feb 4 21:00:57 PST 2010
- time := SecondsToLocalTime(1233810057)
- for _, test := range formatTests {
- result := time.Format(test.format)
- if result != test.result {
- t.Errorf("%s expected %q got %q", test.name, test.result, result)
- }
- }
-}
-
-type ParseTest struct {
- name string
- format string
- value string
- hasTZ bool // contains a time zone
- hasWD bool // contains a weekday
- yearSign int64 // sign of year
-}
-
-var parseTests = []ParseTest{
- {"ANSIC", ANSIC, "Thu Feb 4 21:00:57 2010", false, true, 1},
- {"UnixDate", UnixDate, "Thu Feb 4 21:00:57 PST 2010", true, true, 1},
- {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1},
- {"RFC850", RFC850, "Thursday, 04-Feb-10 21:00:57 PST", true, true, 1},
- {"RFC1123", RFC1123, "Thu, 04 Feb 2010 21:00:57 PST", true, true, 1},
- {"RFC3339", RFC3339, "2010-02-04T21:00:57-08:00", true, false, 1},
- {"custom: \"2006-01-02 15:04:05-07\"", "2006-01-02 15:04:05-07", "2010-02-04 21:00:57-08", true, false, 1},
- // Amount of white space should not matter.
- {"ANSIC", ANSIC, "Thu Feb 4 21:00:57 2010", false, true, 1},
- {"ANSIC", ANSIC, "Thu Feb 4 21:00:57 2010", false, true, 1},
-}
-
-func TestParse(t *testing.T) {
- for _, test := range parseTests {
- time, err := Parse(test.format, test.value)
- if err != nil {
- t.Errorf("%s error: %v", test.name, err)
- } else {
- checkTime(time, &test, t)
- }
- }
-}
-
-var rubyTests = []ParseTest{
- {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1},
- // Ignore the time zone in the test. If it parses, it'll be OK.
- {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0000 2010", false, true, 1},
- {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 +0000 2010", false, true, 1},
- {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 +1130 2010", false, true, 1},
-}
-
-// Problematic time zone format needs special tests.
-func TestRubyParse(t *testing.T) {
- for _, test := range rubyTests {
- time, err := Parse(test.format, test.value)
- if err != nil {
- t.Errorf("%s error: %v", test.name, err)
- } else {
- checkTime(time, &test, t)
- }
- }
-}
-
-func checkTime(time *Time, test *ParseTest, t *testing.T) {
- // The time should be Thu Feb 4 21:00:57 PST 2010
- if test.yearSign*time.Year != 2010 {
- t.Errorf("%s: bad year: %d not %d", test.name, time.Year, 2010)
- }
- if time.Month != 2 {
- t.Errorf("%s: bad month: %d not %d", test.name, time.Month, 2)
- }
- if time.Day != 4 {
- t.Errorf("%s: bad day: %d not %d", test.name, time.Day, 4)
- }
- if time.Hour != 21 {
- t.Errorf("%s: bad hour: %d not %d", test.name, time.Hour, 21)
- }
- if time.Minute != 0 {
- t.Errorf("%s: bad minute: %d not %d", test.name, time.Minute, 0)
- }
- if time.Second != 57 {
- t.Errorf("%s: bad second: %d not %d", test.name, time.Second, 57)
- }
- if test.hasTZ && time.ZoneOffset != -28800 {
- t.Errorf("%s: bad tz offset: %d not %d", test.name, time.ZoneOffset, -28800)
- }
- if test.hasWD && time.Weekday != 4 {
- t.Errorf("%s: bad weekday: %d not %d", test.name, time.Weekday, 4)
- }
-}
-
-func TestFormatAndParse(t *testing.T) {
- const fmt = "Mon MST " + RFC3339 // all fields
- f := func(sec int64) bool {
- t1 := SecondsToLocalTime(sec)
- if t1.Year < 1000 || t1.Year > 9999 {
- // not required to work
- return true
- }
- t2, err := Parse(fmt, t1.Format(fmt))
- if err != nil {
- t.Errorf("error: %s", err)
- return false
- }
- if !same(t1, t2) {
- t.Errorf("different: %q %q", t1, t2)
- return false
- }
- return true
- }
- f32 := func(sec int32) bool { return f(int64(sec)) }
- cfg := &quick.Config{MaxCount: 10000}
-
- // Try a reasonable date first, then the huge ones.
- if err := quick.Check(f32, cfg); err != nil {
- t.Fatal(err)
- }
- if err := quick.Check(f, cfg); err != nil {
- t.Fatal(err)
- }
-}
-
-type ParseErrorTest struct {
- format string
- value string
- expect string // must appear within the error
-}
-
-var parseErrorTests = []ParseErrorTest{
- {ANSIC, "Feb 4 21:00:60 2010", "parse"}, // cannot parse Feb as Mon
- {ANSIC, "Thu Feb 4 21:00:57 @2010", "parse"},
- {ANSIC, "Thu Feb 4 21:00:60 2010", "second out of range"},
- {ANSIC, "Thu Feb 4 21:61:57 2010", "minute out of range"},
- {ANSIC, "Thu Feb 4 24:00:60 2010", "hour out of range"},
-}
-
-func TestParseErrors(t *testing.T) {
- for _, test := range parseErrorTests {
- _, err := Parse(test.format, test.value)
- if err == nil {
- t.Errorf("expected error for %q %q", test.format, test.value)
- } else if strings.Index(err.String(), test.expect) < 0 {
- t.Errorf("expected error with %q for %q %q; got %s", test.expect, test.format, test.value, err)
- }
- }
-}
-
-func TestNoonIs12PM(t *testing.T) {
- noon := Time{Hour: 12}
- const expect = "12:00PM"
- got := noon.Format("3:04PM")
- if got != expect {
- t.Errorf("got %q; expect %q", got, expect)
- }
- got = noon.Format("03:04PM")
- if got != expect {
- t.Errorf("got %q; expect %q", got, expect)
- }
-}
-
-func TestMidnightIs12AM(t *testing.T) {
- midnight := Time{Hour: 0}
- expect := "12:00AM"
- got := midnight.Format("3:04PM")
- if got != expect {
- t.Errorf("got %q; expect %q", got, expect)
- }
- got = midnight.Format("03:04PM")
- if got != expect {
- t.Errorf("got %q; expect %q", got, expect)
- }
-}
-
-func Test12PMIsNoon(t *testing.T) {
- noon, err := Parse("3:04PM", "12:00PM")
- if err != nil {
- t.Fatal("error parsing date:", err)
- }
- if noon.Hour != 12 {
- t.Errorf("got %d; expect 12", noon.Hour)
- }
- noon, err = Parse("03:04PM", "12:00PM")
- if err != nil {
- t.Fatal("error parsing date:", err)
- }
- if noon.Hour != 12 {
- t.Errorf("got %d; expect 12", noon.Hour)
- }
-}
-
-func Test12AMIsMidnight(t *testing.T) {
- midnight, err := Parse("3:04PM", "12:00AM")
- if err != nil {
- t.Fatal("error parsing date:", err)
- }
- if midnight.Hour != 0 {
- t.Errorf("got %d; expect 0", midnight.Hour)
- }
- midnight, err = Parse("03:04PM", "12:00AM")
- if err != nil {
- t.Fatal("error parsing date:", err)
- }
- if midnight.Hour != 0 {
- t.Errorf("got %d; expect 0", midnight.Hour)
- }
-}
-
-// Check that a time without a Zone still produces a (numeric) time zone
-// when formatted with MST as a requested zone.
-func TestMissingZone(t *testing.T) {
- time, err := Parse(RubyDate, "Tue Feb 02 16:10:03 -0500 2006")
- if err != nil {
- t.Fatal("error parsing date:", err)
- }
- expect := "Tue Feb 2 16:10:03 -0500 2006" // -0500 not EST
- str := time.Format(UnixDate) // uses MST as its time zone
- if str != expect {
- t.Errorf("expected %q got %q", expect, str)
- }
-}
-
-func TestMinutesInTimeZone(t *testing.T) {
- time, err := Parse(RubyDate, "Mon Jan 02 15:04:05 +0123 2006")
- if err != nil {
- t.Fatal("error parsing date:", err)
- }
- expected := (1*60 + 23) * 60
- if time.ZoneOffset != expected {
- t.Errorf("ZoneOffset incorrect, expected %d got %d", expected, time.ZoneOffset)
- }
-}
-
-func BenchmarkSeconds(b *testing.B) {
- for i := 0; i < b.N; i++ {
- Seconds()
- }
-}
-
-func BenchmarkNanoseconds(b *testing.B) {
- for i := 0; i < b.N; i++ {
- Nanoseconds()
- }
-}
-
-func BenchmarkFormat(b *testing.B) {
- time := SecondsToLocalTime(1265346057)
- for i := 0; i < b.N; i++ {
- time.Format("Mon Jan 2 15:04:05 2006")
- }
-}
-
-func BenchmarkParse(b *testing.B) {
- for i := 0; i < b.N; i++ {
- Parse(ANSIC, "Mon Jan 2 15:04:05 2006")
- }
-}
diff --git a/src/pkg/time/zoneinfo_plan9.go b/src/pkg/time/zoneinfo_plan9.go
deleted file mode 100644
index 3c3e7c424..000000000
--- a/src/pkg/time/zoneinfo_plan9.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parse Plan 9 timezone(2) files.
-
-package time
-
-import (
- "os"
- "strconv"
- "strings"
-)
-
-func parseZones(s string) (zt []zonetime) {
- f := strings.Fields(s)
- if len(f) < 4 {
- return
- }
-
- // standard timezone offset
- o, err := strconv.Atoi(f[1])
- if err != nil {
- return
- }
- std := &zone{name: f[0], utcoff: o, isdst: false}
-
- // alternate timezone offset
- o, err = strconv.Atoi(f[3])
- if err != nil {
- return
- }
- dst := &zone{name: f[2], utcoff: o, isdst: true}
-
- // transition time pairs
- f = f[4:]
- for i := 0; i < len(f); i++ {
- z := std
- if i%2 == 0 {
- z = dst
- }
- t, err := strconv.Atoi(f[i])
- if err != nil {
- return nil
- }
- t -= std.utcoff
- zt = append(zt, zonetime{time: int32(t), zone: z})
- }
- return
-}
-
-func setupZone() {
- t, err := os.Getenverror("timezone")
- if err != nil {
- // do nothing: use UTC
- return
- }
- zones = parseZones(t)
-}
diff --git a/src/pkg/time/zoneinfo_posix.go b/src/pkg/time/zoneinfo_posix.go
deleted file mode 100644
index b49216410..000000000
--- a/src/pkg/time/zoneinfo_posix.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time
-
-import "sync"
-
-// Parsed representation
-type zone struct {
- utcoff int
- isdst bool
- name string
-}
-
-type zonetime struct {
- time int32 // transition time, in seconds since 1970 GMT
- zone *zone // the zone that goes into effect at that time
- isstd, isutc bool // ignored - no idea what these mean
-}
-
-var zones []zonetime
-var onceSetupZone sync.Once
-
-// Look up the correct time zone (daylight savings or not) for the given unix time, in the current location.
-func lookupTimezone(sec int64) (zone string, offset int) {
- onceSetupZone.Do(setupZone)
- if len(zones) == 0 {
- return "UTC", 0
- }
-
- // Binary search for entry with largest time <= sec
- tz := zones
- for len(tz) > 1 {
- m := len(tz) / 2
- if sec < int64(tz[m].time) {
- tz = tz[0:m]
- } else {
- tz = tz[m:]
- }
- }
- z := tz[0].zone
- return z.name, z.utcoff
-}
-
-// lookupByName returns the time offset for the
-// time zone with the given abbreviation. It only considers
-// time zones that apply to the current system.
-// For example, for a system configured as being in New York,
-// it only recognizes "EST" and "EDT".
-// For a system in San Francisco, "PST" and "PDT".
-// For a system in Sydney, "EST" and "EDT", though they have
-// different meanings than they do in New York.
-func lookupByName(name string) (off int, found bool) {
- onceSetupZone.Do(setupZone)
- for _, z := range zones {
- if name == z.zone.name {
- return z.zone.utcoff, true
- }
- }
- return 0, false
-}
diff --git a/src/pkg/time/zoneinfo_unix.go b/src/pkg/time/zoneinfo_unix.go
deleted file mode 100644
index 2a83e0c16..000000000
--- a/src/pkg/time/zoneinfo_unix.go
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parse "zoneinfo" time zone file.
-// This is a fairly standard file format used on OS X, Linux, BSD, Sun, and others.
-// See tzfile(5), http://en.wikipedia.org/wiki/Zoneinfo,
-// and ftp://munnari.oz.au/pub/oldtz/
-
-package time
-
-import (
- "io/ioutil"
- "os"
-)
-
-const (
- headerSize = 4 + 16 + 4*7
-)
-
-// Simple I/O interface to binary blob of data.
-type data struct {
- p []byte
- error bool
-}
-
-
-func (d *data) read(n int) []byte {
- if len(d.p) < n {
- d.p = nil
- d.error = true
- return nil
- }
- p := d.p[0:n]
- d.p = d.p[n:]
- return p
-}
-
-func (d *data) big4() (n uint32, ok bool) {
- p := d.read(4)
- if len(p) < 4 {
- d.error = true
- return 0, false
- }
- return uint32(p[0])<<24 | uint32(p[1])<<16 | uint32(p[2])<<8 | uint32(p[3]), true
-}
-
-func (d *data) byte() (n byte, ok bool) {
- p := d.read(1)
- if len(p) < 1 {
- d.error = true
- return 0, false
- }
- return p[0], true
-}
-
-
-// Make a string by stopping at the first NUL
-func byteString(p []byte) string {
- for i := 0; i < len(p); i++ {
- if p[i] == 0 {
- return string(p[0:i])
- }
- }
- return string(p)
-}
-
-func parseinfo(bytes []byte) (zt []zonetime, ok bool) {
- d := data{bytes, false}
-
- // 4-byte magic "TZif"
- if magic := d.read(4); string(magic) != "TZif" {
- return nil, false
- }
-
- // 1-byte version, then 15 bytes of padding
- var p []byte
- if p = d.read(16); len(p) != 16 || p[0] != 0 && p[0] != '2' {
- return nil, false
- }
-
- // six big-endian 32-bit integers:
- // number of UTC/local indicators
- // number of standard/wall indicators
- // number of leap seconds
- // number of transition times
- // number of local time zones
- // number of characters of time zone abbrev strings
- const (
- NUTCLocal = iota
- NStdWall
- NLeap
- NTime
- NZone
- NChar
- )
- var n [6]int
- for i := 0; i < 6; i++ {
- nn, ok := d.big4()
- if !ok {
- return nil, false
- }
- n[i] = int(nn)
- }
-
- // Transition times.
- txtimes := data{d.read(n[NTime] * 4), false}
-
- // Time zone indices for transition times.
- txzones := d.read(n[NTime])
-
- // Zone info structures
- zonedata := data{d.read(n[NZone] * 6), false}
-
- // Time zone abbreviations.
- abbrev := d.read(n[NChar])
-
- // Leap-second time pairs
- d.read(n[NLeap] * 8)
-
- // Whether tx times associated with local time types
- // are specified as standard time or wall time.
- isstd := d.read(n[NStdWall])
-
- // Whether tx times associated with local time types
- // are specified as UTC or local time.
- isutc := d.read(n[NUTCLocal])
-
- if d.error { // ran out of data
- return nil, false
- }
-
- // If version == 2, the entire file repeats, this time using
- // 8-byte ints for txtimes and leap seconds.
- // We won't need those until 2106.
-
- // Now we can build up a useful data structure.
- // First the zone information.
- // utcoff[4] isdst[1] nameindex[1]
- z := make([]zone, n[NZone])
- for i := 0; i < len(z); i++ {
- var ok bool
- var n uint32
- if n, ok = zonedata.big4(); !ok {
- return nil, false
- }
- z[i].utcoff = int(n)
- var b byte
- if b, ok = zonedata.byte(); !ok {
- return nil, false
- }
- z[i].isdst = b != 0
- if b, ok = zonedata.byte(); !ok || int(b) >= len(abbrev) {
- return nil, false
- }
- z[i].name = byteString(abbrev[b:])
- }
-
- // Now the transition time info.
- zt = make([]zonetime, n[NTime])
- for i := 0; i < len(zt); i++ {
- var ok bool
- var n uint32
- if n, ok = txtimes.big4(); !ok {
- return nil, false
- }
- zt[i].time = int32(n)
- if int(txzones[i]) >= len(z) {
- return nil, false
- }
- zt[i].zone = &z[txzones[i]]
- if i < len(isstd) {
- zt[i].isstd = isstd[i] != 0
- }
- if i < len(isutc) {
- zt[i].isutc = isutc[i] != 0
- }
- }
- return zt, true
-}
-
-func readinfofile(name string) ([]zonetime, bool) {
- buf, err := ioutil.ReadFile(name)
- if err != nil {
- return nil, false
- }
- return parseinfo(buf)
-}
-
-func setupZone() {
- // consult $TZ to find the time zone to use.
- // no $TZ means use the system default /etc/localtime.
- // $TZ="" means use UTC.
- // $TZ="foo" means use /usr/share/zoneinfo/foo.
- // Many systems use /usr/share/zoneinfo, Solaris 2 has
- // /usr/share/lib/zoneinfo, IRIX 6 has /usr/lib/locale/TZ.
- zoneDirs := []string{"/usr/share/zoneinfo/",
- "/usr/share/lib/zoneinfo/",
- "/usr/lib/locale/TZ/"}
-
- tz, err := os.Getenverror("TZ")
- switch {
- case err == os.ENOENV:
- zones, _ = readinfofile("/etc/localtime")
- case len(tz) > 0:
- for _, zoneDir := range zoneDirs {
- var ok bool
- if zones, ok = readinfofile(zoneDir + tz); ok {
- break
- }
- }
- case len(tz) == 0:
- // do nothing: use UTC
- }
-}
diff --git a/src/pkg/time/zoneinfo_windows.go b/src/pkg/time/zoneinfo_windows.go
deleted file mode 100644
index 83afdfb02..000000000
--- a/src/pkg/time/zoneinfo_windows.go
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time
-
-import (
- "syscall"
- "sync"
- "os"
-)
-
-// BUG(brainman): The Windows implementation assumes that
-// this year's rules for daylight savings time apply to all previous
-// and future years as well.
-
-// TODO(brainman): use GetDynamicTimeZoneInformation, whenever possible (Vista and up),
-// to improve on situation described in the bug above.
-
-type zone struct {
- name string
- offset int
- year int64
- month, day, dayofweek int
- hour, minute, second int
- abssec int64
- prev *zone
-}
-
-// Populate zone struct with Windows supplied information. Returns true, if data is valid.
-func (z *zone) populate(bias, biasdelta int32, d *syscall.Systemtime, name []uint16) (dateisgood bool) {
- z.name = syscall.UTF16ToString(name)
- z.offset = int(bias)
- z.year = int64(d.Year)
- z.month = int(d.Month)
- z.day = int(d.Day)
- z.dayofweek = int(d.DayOfWeek)
- z.hour = int(d.Hour)
- z.minute = int(d.Minute)
- z.second = int(d.Second)
- dateisgood = d.Month != 0
- if dateisgood {
- z.offset += int(biasdelta)
- }
- z.offset = -z.offset * 60
- return
-}
-
-// Pre-calculate cutoff time in seconds since the Unix epoch, if data is supplied in "absolute" format.
-func (z *zone) preCalculateAbsSec() {
- if z.year != 0 {
- z.abssec = (&Time{z.year, int(z.month), int(z.day), int(z.hour), int(z.minute), int(z.second), 0, 0, ""}).Seconds()
- // Time given is in "local" time. Adjust it for "utc".
- z.abssec -= int64(z.prev.offset)
- }
-}
-
-// Convert zone cutoff time to sec in number of seconds since the Unix epoch, given particular year.
-func (z *zone) cutoffSeconds(year int64) int64 {
- // Windows specifies daylight savings information in "day in month" format:
- // z.month is month number (1-12)
- // z.dayofweek is appropriate weekday (Sunday=0 to Saturday=6)
- // z.day is week within the month (1 to 5, where 5 is last week of the month)
- // z.hour, z.minute and z.second are absolute time
- t := &Time{year, int(z.month), 1, int(z.hour), int(z.minute), int(z.second), 0, 0, ""}
- t = SecondsToUTC(t.Seconds())
- i := int(z.dayofweek) - t.Weekday
- if i < 0 {
- i += 7
- }
- t.Day += i
- if week := int(z.day) - 1; week < 4 {
- t.Day += week * 7
- } else {
- // "Last" instance of the day.
- t.Day += 4 * 7
- if t.Day > months(year)[t.Month] {
- t.Day -= 7
- }
- }
- // Result is in "local" time. Adjust it for "utc".
- return t.Seconds() - int64(z.prev.offset)
-}
-
-// Is t before the cutoff for switching to z?
-func (z *zone) isBeforeCutoff(t *Time) bool {
- var coff int64
- if z.year == 0 {
- // "day in month" format used
- coff = z.cutoffSeconds(t.Year)
- } else {
- // "absolute" format used
- coff = z.abssec
- }
- return t.Seconds() < coff
-}
-
-type zoneinfo struct {
- disabled bool // daylight saving time is not used locally
- offsetIfDisabled int
- januaryIsStd bool // is january 1 standard time?
- std, dst zone
-}
-
-// Pick zone (std or dst) t time belongs to.
-func (zi *zoneinfo) pickZone(t *Time) *zone {
- z := &zi.std
- if tz.januaryIsStd {
- if !zi.dst.isBeforeCutoff(t) && zi.std.isBeforeCutoff(t) {
- // after switch to daylight time and before the switch back to standard
- z = &zi.dst
- }
- } else {
- if zi.std.isBeforeCutoff(t) || !zi.dst.isBeforeCutoff(t) {
- // before switch to standard time or after the switch back to daylight
- z = &zi.dst
- }
- }
- return z
-}
-
-var tz zoneinfo
-var initError os.Error
-var onceSetupZone sync.Once
-
-func setupZone() {
- var i syscall.Timezoneinformation
- if _, e := syscall.GetTimeZoneInformation(&i); e != 0 {
- initError = os.NewSyscallError("GetTimeZoneInformation", e)
- return
- }
- if !tz.std.populate(i.Bias, i.StandardBias, &i.StandardDate, i.StandardName[0:]) {
- tz.disabled = true
- tz.offsetIfDisabled = tz.std.offset
- return
- }
- tz.std.prev = &tz.dst
- tz.dst.populate(i.Bias, i.DaylightBias, &i.DaylightDate, i.DaylightName[0:])
- tz.dst.prev = &tz.std
- tz.std.preCalculateAbsSec()
- tz.dst.preCalculateAbsSec()
- // Is january 1 standard time this year?
- t := UTC()
- tz.januaryIsStd = tz.dst.cutoffSeconds(t.Year) < tz.std.cutoffSeconds(t.Year)
-}
-
-// Look up the correct time zone (daylight savings or not) for the given unix time, in the current location.
-func lookupTimezone(sec int64) (zone string, offset int) {
- onceSetupZone.Do(setupZone)
- if initError != nil {
- return "", 0
- }
- if tz.disabled {
- return "", tz.offsetIfDisabled
- }
- t := SecondsToUTC(sec)
- z := &tz.std
- if tz.std.year == 0 {
- // "day in month" format used
- z = tz.pickZone(t)
- } else {
- // "absolute" format used
- if tz.std.year == t.Year {
- // we have rule for the year in question
- z = tz.pickZone(t)
- } else {
- // we do not have any information for that year,
- // will assume standard offset all year around
- }
- }
- return z.name, z.offset
-}
-
-// lookupByName returns the time offset for the
-// time zone with the given abbreviation. It only considers
-// time zones that apply to the current system.
-func lookupByName(name string) (off int, found bool) {
- onceSetupZone.Do(setupZone)
- if initError != nil {
- return 0, false
- }
- if tz.disabled {
- return tz.offsetIfDisabled, false
- }
- switch name {
- case tz.std.name:
- return tz.std.offset, true
- case tz.dst.name:
- return tz.dst.offset, true
- }
- return 0, false
-}