// Parses string datetime in TimeFormat using loc location.
// Converts MySQL zero to time.Time zero.
553042
func ParseTime(str string, loc *time.Location) (t time.Time, err error) {
	str = strings.TrimSpace(str)
	format := TimeFormat[:19]
	switch len(str) {
	case 10:
		if str == "0000-00-00" {
			return
		}
		format = format[:10]
	case 19:
		if str == "0000-00-00 00:00:00" {
			return
		}
	}
	// Don't expect 0000-00-00 00:00:00.0+
	t, err = time.ParseInLocation(format, str, loc)
	return
}
957642
func ParseDatetimeFromNum(num int64) (Time, error) {
	return ParseTimeFromNum(num, mysql.TypeDatetime, DefaultFsp)
}
406669
func localDateTimeString(dt DateTime) string {
	year, month, day, hour, minute, second := dt.DateTime()
	sign := ""
	if year < 0 {
		year = -year
		sign = "-"
	}
	return fmt.Sprintf("%s%04d-%02d-%02dT%02d:%02d:%02d", sign, year, int(month), day, hour, minute, second)
}
1364037
func (p TimeParser) Parse(field string) (result interface{}, err error) {
	return time.Parse(p.Layout, field)
}
1246263
func (t *Translator) FormatDateTime(format int, datetime time.Time) (string, error) {
	pattern := ""
	switch format {
	case DateFormatFull:
		pattern = t.rules.DateTime.Formats.Date.Full
	case DateFormatLong:
		pattern = t.rules.DateTime.Formats.Date.Long
	case DateFormatMedium:
		pattern = t.rules.DateTime.Formats.Date.Medium
	case DateFormatShort:
		pattern = t.rules.DateTime.Formats.Date.Short
	case TimeFormatFull:
		pattern = t.rules.DateTime.Formats.Time.Full
	case TimeFormatLong:
		pattern = t.rules.DateTime.Formats.Time.Long
	case TimeFormatMedium:
		pattern = t.rules.DateTime.Formats.Time.Medium
	case TimeFormatShort:
		pattern = t.rules.DateTime.Formats.Time.Short
	case DateTimeFormatFull:
		datePattern := strings.Trim(t.rules.DateTime.Formats.Date.Full, " ,")
		timePattern := strings.Trim(t.rules.DateTime.Formats.Time.Full, " ,")
		pattern = getDateTimePattern(t.rules.DateTime.Formats.DateTime.Full, datePattern, timePattern)
	case DateTimeFormatLong:
		datePattern := strings.Trim(t.rules.DateTime.Formats.Date.Long, " ,")
		timePattern := strings.Trim(t.rules.DateTime.Formats.Time.Long, " ,")
		pattern = getDateTimePattern(t.rules.DateTime.Formats.DateTime.Long, datePattern, timePattern)
	case DateTimeFormatMedium:
		datePattern := strings.Trim(t.rules.DateTime.Formats.Date.Medium, " ,")
		timePattern := strings.Trim(t.rules.DateTime.Formats.Time.Medium, " ,")
		pattern = getDateTimePattern(t.rules.DateTime.Formats.DateTime.Medium, datePattern, timePattern)
	case DateTimeFormatShort:
		datePattern := strings.Trim(t.rules.DateTime.Formats.Date.Short, " ,")
		timePattern := strings.Trim(t.rules.DateTime.Formats.Time.Short, " ,")
		pattern = getDateTimePattern(t.rules.DateTime.Formats.DateTime.Short, datePattern, timePattern)
	default:
		return "", translatorError{message: "unknown datetime format" + pattern[0:1]}
	}

	parsed, err := t.parseDateTimeFormat(pattern)
	if err != nil {
		return "", err
	}

	return t.formatDateTime(datetime, parsed)
}
1224142
func FormatTime(name string, t time.Time) string {
	t = t.UTC()

	switch name {
	case RFC822TimeFormatName:
		return t.Format(RFC822TimeFormat)
	case ISO8601TimeFormatName:
		return t.Format(ISO8601TimeFormat)
	case UnixTimeFormatName:
		return strconv.FormatInt(t.Unix(), 10)
	default:
		panic("unknown timestamp format name, " + name)
	}
}
362880
func NewDateTimeFieldDescriptor(nullable NullableColumn) FieldDescriptor {
	return newFixedLengthFieldDescriptor(
		mysql_proto.FieldType_DATETIME,
		nullable,
		8,
		func(b []byte) interface{} {
			val := LittleEndian.Uint64(b)
			d := val / 1000000
			t := val % 1000000
			return time.Date(
				int(d/10000),              // year
				time.Month((d%10000)/100), // month
				int(d%100),                // day
				int(t/10000),              // hour
				int((t%10000)/100),        // minute
				int(t%100),                // second
				0,                         // nanosecond
				time.UTC)
		})
}
1068693
func ParseFromTime(t time.Time, nlTime string) []time.Time {
	r := strings.NewReplacer(
		".", "",
		",", "",
		"(", "",
		")", "",
		"'", "",
	)
	nlTime = r.Replace(nlTime)
	nlTime = strings.ToLower(nlTime)
	r = strings.NewReplacer(
		"at ", "",
		"time", "",
		"oclock", "",
		"am", "AM",
		"pm", "PM",
		" am", "AM",
		" pm", "PM",

		// 1st, 2nd, 3rd, 4th, 5th, etc.
		"1st", "1",
		"2nd", "2",
		"3rd", "3",
		"th", "",
		"21st", "21",
		"22nd", "22",
		"23rd", "23",
		"31st", "31",
	)
	nlTime = r.Replace(nlTime)
	nlTime = strings.Title(nlTime)
	if nlTime == "Now" {
		return []time.Time{time.Now()}
	}
	st := strings.Fields(nlTime)
	transform := struct {
		Transform  int
		Type       timeTransform
		Multiplier int
	}{
		Multiplier: 1,
	}
	stFull := ""
	var closeTime bool
	var idxRel int
	var loc *time.Location
	for i := range st {
		// Normalize days
		switch st[i] {
		case "Monday":
			st[i] = "Mon"
			transform.Type = transformDay
		case "Tuesday", "Tues":
			st[i] = "Tue"
			transform.Type = transformDay
		case "Wednesday":
			st[i] = "Wed"
			transform.Type = transformDay
		case "Thursday", "Thur", "Thurs":
			st[i] = "Thu"
			transform.Type = transformDay
		case "Friday":
			st[i] = "Fri"
			transform.Type = transformDay
		case "Saturday":
			st[i] = "Sat"
			transform.Type = transformDay
		case "Sunday":
			st[i] = "Sun"
			transform.Type = transformDay

		// Normalize months
		case "January":
			st[i] = "Jan"
			transform.Type = transformMonth
		case "February":
			st[i] = "Feb"
			transform.Type = transformMonth
		case "March":
			st[i] = "Mar"
			transform.Type = transformMonth
		case "April":
			st[i] = "Apr"
			transform.Type = transformMonth
		case "May":
			// No translation needed for May
			transform.Type = transformMonth
		case "June":
			st[i] = "Jun"
			transform.Type = transformMonth
		case "July":
			st[i] = "Jul"
			transform.Type = transformMonth
		case "August":
			st[i] = "Aug"
			transform.Type = transformMonth
		case "September", "Sept":
			st[i] = "Sep"
			transform.Type = transformMonth
		case "October":
			st[i] = "Oct"
			transform.Type = transformMonth
		case "November":
			st[i] = "Nov"
			transform.Type = transformMonth
		case "December":
			st[i] = "Dec"
			transform.Type = transformMonth

		// If non-deterministic timezone information is provided,
		// e.g. ET or Eastern rather than EST, then load the location.
		// Daylight Savings will be determined on parsing
		case "Pacific", "PT":
			st[i] = ""
			loc = loadLocation("America/Los_Angeles")
		case "Mountain", "MT":
			st[i] = ""
			loc = loadLocation("America/Denver")
		case "Central", "CT":
			st[i] = ""
			loc = loadLocation("America/Chicago")
		case "Eastern", "ET":
			st[i] = ""
			loc = loadLocation("America/New_York")
		// TODO Add the remaining timezones

		// Handle relative times. This currently does not handle
		// complex cases like "in 3 months and 2 days"
		case "Yesterday":
			st[i] = ""
			transform.Type = transformDay
			transform.Transform = 1
			transform.Multiplier = -1
		case "Tomorrow":
			st[i] = ""
			transform.Transform = 1
			transform.Type = transformDay
		case "Today":
			st[i] = ""
			closeTime = true
			transform.Type = transformHour
		case "Ago", "Last":
			st[i] = ""
			transform.Transform = 1
			transform.Multiplier *= -1
		// e.g. "In an hour"
		case "Next", "From", "Now", "In":
			st[i] = ""
			transform.Transform = 1
		case "Later":
			st[i] = ""
			transform.Transform = 6
		case "Hour", "Hours":
			st[i] = ""
			idxRel = i
			closeTime = true
			transform.Type = transformHour
		case "Few", "Couple":
			st[i] = ""
			transform.Transform = 2
		case "Min", "Mins", "Minute", "Minutes":
			st[i] = ""
			idxRel = i
			closeTime = true
			transform.Type = transformMinute
		case "Day", "Days":
			st[i] = ""
			idxRel = i
			transform.Type = transformDay
		case "Week", "Weeks":
			st[i] = ""
			idxRel = i
			transform.Type = transformDay
			transform.Multiplier = 7
		case "Month", "Months":
			st[i] = ""
			idxRel = i
			transform.Type = transformMonth
		case "Year", "Years":
			st[i] = ""
			idxRel = i
			transform.Type = transformYear

		// Remove unnecessary but common expressions like "at", "time",
		// "oclock".
		case "At", "Time", "Oclock", "This", "The":
			st[i] = ""
		case "Noon":
			st[i] = "12PM"
		case "Supper", "Dinner":
			st[i] = "6PM"
		}

		if len(st[i]) > 0 {
			stFull += st[i] + " "
		}
	}
	normalized := strings.TrimRight(stFull, " ")

	var timeEmpty bool
	ts := []time.Time{}
	tme, err := parseTime(normalized)
	if err != nil {
		// Set the hour to 9am
		timeEmpty = true
		tme = time.Now().Round(time.Hour)
		val := 9 - tme.Hour()
		tme = tme.Add(time.Duration(val) * time.Hour)
	}
	if closeTime {
		tme = time.Now().Round(time.Minute)
	}
	ts = append(ts, tme)

	// TODO make more efficient. Handle in switch?
	tloc := timeLocation{loc: loc}
	ctx := &TimeContext{ampm: ampmNoTime, tz: tloc}
	if strings.Contains(normalized, "AM") {
		ctx.ampm = amTime
	}
	if strings.Contains(normalized, "UTC") {
		ctx.tz.utc = true
	}
	for _, ti := range ts {
		ctx = updateContext(ctx, ti, false)
	}

	// Ensure dates are reasonable even in the absence of information.
	// e.g. 2AM should parse to the current year, not 0000
	ctx = completeContext(ctx, t)

	// Loop through a second time to apply the discovered context to each
	// time. Note that this doesn't support context switching,
	// e.g. "5PM CST or PST" or "5PM EST or 6PM PST", which is rare in
	// practice. Future versions may be adapted to support it.
	if ctx.ampm == ampmNoTime {
		halfLen := len(ts)
		// Double size of times for AM/PM
		ts = append(ts, ts...)
		for i := range ts {
			var hour int
			t := ts[i]
			if i < halfLen {
				hour = t.Hour()
			} else {
				hour = t.Hour() + 12
			}
			ts[i] = time.Date(ctx.year,
				ctx.month,
				ctx.day,
				hour,
				t.Minute(),
				t.Second(),
				t.Nanosecond(),
				ctx.tz.loc)
		}
	} else {
		for i := range ts {
			t := ts[i]
			ts[i] = time.Date(ctx.year,
				ctx.month,
				ctx.day,
				t.Hour(),
				t.Minute(),
				t.Second(),
				t.Nanosecond(),
				ctx.tz.loc)
		}
	}

	// If there's no relative transform, we're done.
	if transform.Type == transformInvalid {
		if timeEmpty {
			return []time.Time{}
		}
		if idxRel == 0 {
			return ts
		}
	}

	// Check our idxRel term for the word that preceeds it. If that's a
	// number, e.g. 2 days, then that number is our Transform. Note that
	// this doesn't handle fractional modifiers, like 2.5 days.
	if idxRel > 0 {
		val, err := strconv.Atoi(st[idxRel-1])
		if err == nil {
			transform.Transform = val
		}
	}

	// Apply the transform
	log.Debugf("timeparse: normalized %q. %+v\n", normalized, transform)
	for i := range ts {
		switch transform.Type {
		case transformYear:
			ts[i] = ts[i].AddDate(transform.Transform*transform.Multiplier, 0, 0)
		case transformMonth:
			ts[i] = ts[i].AddDate(0, transform.Multiplier*transform.Transform, 0)
		case transformDay:
			ts[i] = ts[i].AddDate(0, 0, transform.Multiplier*transform.Transform)
		case transformHour:
			ts[i] = ts[i].Add(time.Duration(transform.Transform*transform.Multiplier) * time.Hour)
		case transformMinute:
			ts[i] = ts[i].Add(time.Duration(transform.Transform*transform.Multiplier) * time.Minute)
		}
	}
	log.Debug("timeparse: parsed times", ts)
	return ts
}
260658
func ParseTime(formatName, value string) (time.Time, error) {
	switch formatName {
	case RFC822TimeFormatName:
		return time.Parse(RFC822TimeFormat, value)
	case ISO8601TimeFormatName:
		return time.Parse(ISO8601TimeFormat, value)
	case UnixTimeFormatName:
		v, err := strconv.ParseFloat(value, 64)
		if err != nil {
			return time.Time{}, err
		}
		return time.Unix(int64(v), 0), nil
	default:
		panic("unknown timestamp format name, " + formatName)
	}
}
288904
func parseFullTime(buff []byte, cursor *int, l int) (fullTime, error) {
	var loc = new(time.Location)
	var ft fullTime

	pt, err := parsePartialTime(buff, cursor, l)
	if err != nil {
		return ft, err
	}

	loc, err = parseTimeOffset(buff, cursor, l)
	if err != nil {
		return ft, err
	}

	ft = fullTime{
		pt:  pt,
		loc: loc,
	}

	return ft, nil
}
227834
func DateFormat(format string, timestamp interface{}) (t string) { // timestamp
	switch format {
	case "Y-m-d H:i:s", "":
		format = "2006-01-02 15:04:05"
	case "Y-m-d H:i":
		format = "2006-01-02 15:04"
	case "y-m-d H:i":
		format = "06-01-02 15:04"
	case "m-d H:i":
		format = "01-02 15:04"
	case "Y-m-d":
		format = "2006-01-02"
	case "y-m-d":
		format = "06-01-02"
	case "m-d":
		format = "01-02"
	default:
		format = ConvDateFormat(format)
	}
	sd := Int64(timestamp)
	t = time.Unix(sd, 0).Format(format)
	return
}
695632
func parseTime(c *Cell) (string, error) {
	f, err := strconv.ParseFloat(c.Value, 64)
	if err != nil {
		return c.Value, err
	}
	val := TimeFromExcelTime(f, c.date1904)
	format := c.GetNumberFormat()
	// Replace Excel placeholders with Go time placeholders.
	// For example, replace yyyy with 2006. These are in a specific order,
	// due to the fact that m is used in month, minute, and am/pm. It would
	// be easier to fix that with regular expressions, but if it's possible
	// to keep this simple it would be easier to maintain.
	replacements := []struct{ xltime, gotime string }{
		{"yyyy", "2006"},
		{"yy", "06"},
		{"dd", "02"},
		{"d", "2"},
		{"mmm", "Jan"},
		{"mmss", "0405"},
		{"ss", "05"},
		{"hh", "15"},
		{"h", "3"},
		{"mm:", "04:"},
		{":mm", ":04"},
		{"mm", "01"},
		{"am/pm", "pm"},
		{"m/", "1/"},
		{".0", ".9999"},
	}
	for _, repl := range replacements {
		format = strings.Replace(format, repl.xltime, repl.gotime, 1)
	}
	// If the hour is optional, strip it out, along with the
	// possible dangling colon that would remain.
	if val.Hour() < 1 {
		format = strings.Replace(format, "]:", "]", 1)
		format = strings.Replace(format, "[3]", "", 1)
		format = strings.Replace(format, "[15]", "", 1)
	} else {
		format = strings.Replace(format, "[3]", "3", 1)
		format = strings.Replace(format, "[15]", "15", 1)
	}
	return val.Format(format), nil
}
1141734
func formatTime(v interface{}, dateFormat string) string {
	if typed, isTyped := v.(time.Time); isTyped {
		return typed.Format(dateFormat)
	}
	if typed, isTyped := v.(int64); isTyped {
		return time.Unix(0, typed).Format(dateFormat)
	}
	if typed, isTyped := v.(float64); isTyped {
		return time.Unix(0, int64(typed)).Format(dateFormat)
	}
	return ""
}
1207055
func (pt *ParseTime) US(value string) (time.Time, error) {
	t, _, err := parseUS(value, pt.location)
	return t, err
}
468082
func (t MysqlTime) GoTime(loc *gotime.Location) (gotime.Time, error) {
	// gotime.Time can't represent month 0 or day 0, date contains 0 would be converted to a nearest date,
	// For example, 2006-12-00 00:00:00 would become 2015-11-30 23:59:59.
	tm := gotime.Date(t.Year(), gotime.Month(t.Month()), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Microsecond()*1000, loc)
	year, month, day := tm.Date()
	hour, minute, second := tm.Clock()
	microsec := tm.Nanosecond() / 1000
	// This function will check the result, and return an error if it's not the same with the origin input.
	if year != t.Year() || int(month) != t.Month() || day != t.Day() ||
		hour != t.Hour() || minute != t.Minute() || second != t.Second() ||
		microsec != t.Microsecond() {
		return tm, errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(t))
	}
	return tm, nil
}
715010
func ParseTimeFromInt64(sc *stmtctx.StatementContext, num int64) (Time, error) {
	return parseDateTimeFromNum(sc, num)
}
183418
func ParseTime(s string) (time.Time, error) {
	t, err := time.Parse(logutil.SlowLogTimeFormat, s)
	if err != nil {
		// This is for compatibility.
		t, err = time.Parse(logutil.OldSlowLogTimeFormat, s)
		if err != nil {
			err = errors.Errorf("string \"%v\" doesn't has a prefix that matches format \"%v\", err: %v", s, logutil.SlowLogTimeFormat, err)
		}
	}
	return t, err
}