// 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.

// The time package provides functionality for measuring and
// displaying time.
package time

import (
	"os";
	"time"
)

// Seconds reports the number of seconds since the Unix epoch,
// January 1, 1970 00:00:00 UTC.
func Seconds() int64 {
	sec, nsec, err := os.Time();
	if err != nil {
		panic("time: os.Time: ", err.String());
	}
	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("time: os.Time: ", err.String());
	}
	return sec*1e9 + nsec
}

// 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;	// 2008 is 2008
	Month, Day int;	// Sep-17 is 9, 17
	Hour, Minute, Second int;	// 10:43:12 is 10, 43, 12
	Weekday int;		// Sunday, Monday, ...
	ZoneOffset int;	// seconds west of UTC
	Zone string;
}

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;
	} else {
		// Cut off 400 year cycles.
		n := day/daysPer400Years;
		year += 400*n;
		day -= daysPer400Years*n;
	}

	// Cut off 100-year cycles
	n := day/daysPer100Years;
	year += 100*n;
	day -= daysPer100Years*n;

	// Cut off 4-year cycles
	n = day/daysPer4Years;
	year += 4*n;
	day -= daysPer4Years*n;

	// Cut off non-leap years.
	n = day/365;
	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 := time.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
}

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"
}

func copy(dst []byte, s string) {
	for i := 0; i < len(s); i++ {
		dst[i] = s[i]
	}
}

func decimal(dst []byte, n int) {
	if n < 0 {
		n = 0
	}
	for i := len(dst)-1; i >= 0; i-- {
		dst[i] = byte(n%10 + '0');
		n /= 10
	}
}

func addString(buf []byte, bp int, s string) int {
	n := len(s);
	copy(buf[bp:bp+n], s);
	return bp+n
}

// Just enough of strftime to implement the date formats below.
// Not exported.
func format(t *Time, fmt string) string {
	buf := make([]byte, 128);
	bp := 0;

	for i := 0; i < len(fmt); i++ {
		if fmt[i] == '%' {
			i++;
			switch fmt[i] {
			case 'A':	// %A full weekday name
				bp = addString(buf, bp, longDayNames[t.Weekday]);
			case 'a':	// %a abbreviated weekday name
				bp = addString(buf, bp, shortDayNames[t.Weekday]);
			case 'b':	// %b abbreviated month name
				bp = addString(buf, bp, shortMonthNames[t.Month-1]);
			case 'd':	// %d day of month (01-31)
				decimal(buf[bp:bp+2], t.Day);
				bp += 2;
			case 'e':	// %e day of month ( 1-31)
				if t.Day >= 10 {
					decimal(buf[bp:bp+2], t.Day)
				} else {
					buf[bp] = ' ';
					buf[bp+1] = byte(t.Day + '0')
				}
				bp += 2;
			case 'H':	// %H hour 00-23
				decimal(buf[bp:bp+2], t.Hour);
				bp += 2;
			case 'M':	// %M minute 00-59
				decimal(buf[bp:bp+2], t.Minute);
				bp += 2;
			case 'S':	// %S second 00-59
				decimal(buf[bp:bp+2], t.Second);
				bp += 2;
			case 'Y':	// %Y year 2008
				decimal(buf[bp:bp+4], int(t.Year));
				bp += 4;
			case 'y':	// %y year 08
				decimal(buf[bp:bp+2], int(t.Year%100));
				bp += 2;
			case 'Z':
				bp = addString(buf, bp, t.Zone);
			default:
				buf[bp] = '%';
				buf[bp+1] = fmt[i];
				bp += 2
			}
		} else {
			buf[bp] = fmt[i];
			bp++;
		}
	}
	return string(buf[0:bp])
}

// Asctime formats the parsed time value in the style of
// ANSI C asctime: Sun Nov  6 08:49:37 1994
func (t *Time) Asctime() string {
	return format(t, "%a %b %e %H:%M:%S %Y")
}

// RFC850 formats the parsed time value in the style of
// RFC 850: Sunday, 06-Nov-94 08:49:37 UTC
func (t *Time) RFC850() string {
	return format(t, "%A, %d-%b-%y %H:%M:%S %Z")
}

// RFC1123 formats the parsed time value in the style of
// RFC 1123: Sun, 06 Nov 1994 08:49:37 UTC
func (t *Time) RFC1123() string {
	return format(t, "%a, %d %b %Y %H:%M:%S %Z")
}

// String formats the parsed time value in the style of
// date(1) - Sun Nov  6 08:49:37 UTC 1994
func (t *Time) String() string {
	return format(t, "%a %b %e %H:%M:%S %Z %Y")
}
