// ParseDateFromNum is a helper function wrapping ParseTimeFromNum with date type.
182371
func ParseDateFromNum(num int64) (Time, error) {
	// date has no fractional seconds precision
	return ParseTimeFromNum(num, mysql.TypeDate, MinFsp)
}
867587
func DateFromTime(t time.Time) Date {
	year, month, day := t.Date()
	return DateFor(year, month, day)
}
1028388
func ParseDatetime(sc *stmtctx.StatementContext, str string) (Time, error) {
	return ParseTime(sc, str, mysql.TypeDatetime, GetFsp(str))
}
410404
func ParseTime(rfc3339Time string) int {
	t, _ := time.Parse(
		time.RFC3339,
		rfc3339Time)

	return TimeToEpoch(t)
}
731846
func ParseNumber(f interface{}) (uint32, error) {
	// Useful for tests
	if n, ok := f.(uint32); ok {
		return n, nil
	}

	s, ok := f.(string)
	if !ok {
		return 0, newParseError("expected a number, got a non-atom")
	}

	nbr, err := strconv.ParseUint(s, 10, 32)
	if err != nil {
		return 0, &parseError{err}
	}

	return uint32(nbr), nil
}
1269288
func (fullFormat *parsedNumberFormat) parseTime(value string, date1904 bool) (string, error) {
	f, err := strconv.ParseFloat(value, 64)
	if err != nil {
		return value, err
	}
	val := TimeFromExcelTime(f, date1904)
	format := fullFormat.numFmt
	// 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.
	// Full-length month and days (e.g. March, Tuesday) have letters in them that would be replaced
	// by other characters below (such as the 'h' in March, or the 'd' in Tuesday) below.
	// First we convert them to arbitrary characters unused in Excel Date formats, and then at the end,
	// turn them to what they should actually be.
	// Based off: http://www.ozgrid.com/Excel/CustomFormats.htm
	replacements := []struct{ xltime, gotime string }{
		{"yyyy", "2006"},
		{"yy", "06"},
		{"mmmm", "%%%%"},
		{"dddd", "&&&&"},
		{"dd", "02"},
		{"d", "2"},
		{"mmm", "Jan"},
		{"mmss", "0405"},
		{"ss", "05"},
		{"mm:", "04:"},
		{":mm", ":04"},
		{"mm", "01"},
		{"am/pm", "pm"},
		{"m/", "1/"},
		{"%%%%", "January"},
		{"&&&&", "Monday"},
	}
	// It is the presence of the "am/pm" indicator that determins
	// if this is a 12 hour or 24 hours time format, not the
	// number of 'h' characters.
	if is12HourTime(format) {
		format = strings.Replace(format, "hh", "03", 1)
		format = strings.Replace(format, "h", "3", 1)
	} else {
		format = strings.Replace(format, "hh", "15", 1)
		format = strings.Replace(format, "h", "15", 1)
	}
	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, "[03]", "", 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
}
837855
func ParseDuration(s string) (d time.Duration, err error) {
	r := strings.NewReader(s)

	switch {
	case strings.HasSuffix(s, "d"):
		var v float64
		_, err = fmt.Fscanf(r, "%fd", &v)
		d = time.Duration(v * float64(24*time.Hour))
	case strings.HasSuffix(s, "w"):
		var v float64
		_, err = fmt.Fscanf(r, "%fw", &v)
		d = time.Duration(v * float64(24*time.Hour*7))
	case strings.HasSuffix(s, "mo"):
		var v float64
		_, err = fmt.Fscanf(r, "%fmo", &v)
		d = time.Duration(v * float64(30*24*time.Hour))
	case strings.HasSuffix(s, "M"):
		var v float64
		_, err = fmt.Fscanf(r, "%fM", &v)
		d = time.Duration(v * float64(30*24*time.Hour))
	default:
		d, err = time.ParseDuration(s)
	}

	return
}
1113569
func NullDateTimeFrom(ptr *DateTime) NullDateTime {
	if ptr == nil {
		return NullDateTime{}
	}
	return NullDateTime{
		DateTime: *ptr,
		Valid:    true,
	}
}
368182
func ParseDuration(str string, fsp int) (Duration, error) {
	var (
		day    int
		hour   int
		minute int
		second int
		frac   int

		err       error
		sign      = 0
		dayExists = false
	)

	fsp, err = checkFsp(fsp)
	if err != nil {
		return ZeroDuration, errors.Trace(err)
	}

	if len(str) == 0 {
		return ZeroDuration, nil
	} else if str[0] == '-' {
		str = str[1:]
		sign = -1
	}

	// Time format may has day.
	if n := strings.IndexByte(str, ' '); n >= 0 {
		if day, err = strconv.Atoi(str[:n]); err == nil {
			dayExists = true
		}
		str = str[n+1:]
	}

	var overflow bool
	if n := strings.IndexByte(str, '.'); n >= 0 {
		// It has fractional precesion parts.
		fracStr := str[n+1:]
		frac, overflow, err = parseFrac(fracStr, fsp)
		if err != nil {
			return ZeroDuration, errors.Trace(err)
		}
		str = str[0:n]
	}

	// It tries to split str with delimiter, time delimiter must be :
	seps := strings.Split(str, ":")

	switch len(seps) {
	case 1:
		if dayExists {
			hour, err = strconv.Atoi(seps[0])
		} else {
			// No delimiter.
			if len(str) == 6 {
				// HHMMSS
				_, err = fmt.Sscanf(str, "%2d%2d%2d", &hour, &minute, &second)
			} else if len(str) == 4 {
				// MMSS
				_, err = fmt.Sscanf(str, "%2d%2d", &minute, &second)
			} else if len(str) == 2 {
				// SS
				_, err = fmt.Sscanf(str, "%2d", &second)
			} else {
				// Maybe only contains date.
				_, err = ParseDate(str)
				if err == nil {
					return ZeroDuration, nil
				}
				return ZeroDuration, errors.Trace(ErrInvalidTimeFormat)
			}
		}
	case 2:
		// HH:MM
		_, err = fmt.Sscanf(str, "%2d:%2d", &hour, &minute)
	case 3:
		// Time format maybe HH:MM:SS or HHH:MM:SS.
		// See https://dev.mysql.com/doc/refman/5.7/en/time.html
		if !dayExists && len(seps[0]) == 3 {
			_, err = fmt.Sscanf(str, "%3d:%2d:%2d", &hour, &minute, &second)
		} else {
			_, err = fmt.Sscanf(str, "%2d:%2d:%2d", &hour, &minute, &second)
		}
	default:
		return ZeroDuration, errors.Trace(ErrInvalidTimeFormat)
	}

	if err != nil {
		return ZeroDuration, errors.Trace(err)
	}

	if overflow {
		second++
		frac = 0
	}
	d := gotime.Duration(day*24*3600+hour*3600+minute*60+second)*gotime.Second + gotime.Duration(frac)*gotime.Microsecond
	if sign == -1 {
		d = -d
	}

	if d > MaxTime {
		d = MaxTime
		err = ErrInvalidTimeFormat
	} else if d < MinTime {
		d = MinTime
		err = ErrInvalidTimeFormat
	}
	return Duration{Duration: d, Fsp: fsp}, errors.Trace(err)
}
216473
func (p *Parser) parseTimestamp() (time.Time, error) {
	var ts time.Time

	if p.buff[p.cursor] == NILVALUE {
		p.cursor++
		return ts, nil
	}

	fd, err := parseFullDate(p.buff, &p.cursor, p.l)
	if err != nil {
		return ts, err
	}

	if p.buff[p.cursor] != 'T' {
		return ts, ErrInvalidTimeFormat
	}

	p.cursor++

	ft, err := parseFullTime(p.buff, &p.cursor, p.l)
	if err != nil {
		return ts, syslogparser.ErrTimestampUnknownFormat
	}

	nSec, err := toNSec(ft.pt.secFrac)
	if err != nil {
		return ts, err
	}

	ts = time.Date(
		fd.year,
		time.Month(fd.month),
		fd.day,
		ft.pt.hour,
		ft.pt.minute,
		ft.pt.seconds,
		nSec,
		ft.loc,
	)

	return ts, nil
}
809951
func ParseTimestamp(str string) (Time, error) {
	return ParseTime(str, mysql.TypeTimestamp, DefaultFsp)
}
512642
func parseTimestamp(timeFunc func() time.Time, recordFields map[string]interface{},
	timestampColumn, timestampFormat string,
) (metricTime time.Time, err error) {
	metricTime = timeFunc()

	if timestampColumn != "" {
		if recordFields[timestampColumn] == nil {
			err = fmt.Errorf("timestamp column: %v could not be found", timestampColumn)
			return
		}

		tStr := fmt.Sprintf("%v", recordFields[timestampColumn])

		switch timestampFormat {
		case "":
			err = fmt.Errorf("timestamp format must be specified")
			return
		default:
			metricTime, err = internal.ParseTimestamp(tStr, timestampFormat)
			if err != nil {
				return
			}
		}
	}
	return
}
963706
func parseDuration(s string) (time.Duration, error) {
	if s == "" {
		return time.Duration(0), nil
	}

	// try to parse it as duration
	return time.ParseDuration(s)
}
490665
func (n Number) parseFormat(pattern string, includeDecimalDigits bool) *numberFormat {
	format := new(numberFormat)
	patterns := strings.Split(pattern, ";")

	matches := prefixSuffixRegex.FindAllStringSubmatch(patterns[0], -1)
	if len(matches) > 0 {
		if len(matches[0]) > 1 {
			format.positivePrefix = matches[0][1]
		}
		if len(matches[0]) > 2 {
			format.positiveSuffix = matches[0][2]
		}
	}

	// default values for negative prefix & suffix
	format.negativePrefix = string(n.Symbols.Negative) + string(format.positivePrefix)
	format.negativeSuffix = format.positiveSuffix

	// see if they are in the pattern
	if len(patterns) > 1 {
		matches = prefixSuffixRegex.FindAllStringSubmatch(patterns[1], -1)

		if len(matches) > 0 {
			if len(matches[0]) > 1 {
				format.negativePrefix = matches[0][1]
			}
			if len(matches[0]) > 2 {
				format.negativeSuffix = matches[0][2]
			}
		}
	}

	pat := patterns[0]

	if strings.Index(pat, "%") != -1 {
		format.multiplier = 100
	} else if strings.Index(pat, "‰") != -1 {
		format.multiplier = 1000
	} else {
		format.multiplier = 1
	}

	pos := strings.Index(pat, ".")

	if pos != -1 {
		pos2 := strings.LastIndex(pat, "0")
		if pos2 > pos {
			format.minDecimalDigits = pos2 - pos
		}

		pos3 := strings.LastIndex(pat, "#")
		if pos3 >= pos2 {
			format.maxDecimalDigits = pos3 - pos
		} else {
			format.maxDecimalDigits = format.minDecimalDigits
		}

		pat = pat[0:pos]
	}

	p := strings.Replace(pat, ",", "", -1)
	pos = strings.Index(p, "0")
	if pos != -1 {
		format.minIntegerDigits = strings.LastIndex(p, "0") - pos + 1
	}

	p = strings.Replace(pat, "#", "0", -1)
	pos = strings.LastIndex(pat, ",")
	if pos != -1 {
		format.groupSizeFinal = strings.LastIndex(p, "0") - pos
		pos2 := strings.LastIndex(p[0:pos], ",")
		if pos2 != -1 {
			format.groupSizeMain = pos - pos2 - 1
		} else {
			format.groupSizeMain = format.groupSizeFinal
		}
	}

	if !includeDecimalDigits {
		format.maxDecimalDigits = 0
		format.minDecimalDigits = 0
	}

	return format
}
703346
func ParseDate(ddmmyy string) (Date, error) {
	if ddmmyy == "" {
		return Date{}, nil
	}
	if len(ddmmyy) != 6 {
		return Date{}, fmt.Errorf("parse date: exptected ddmmyy format, got '%s'", ddmmyy)
	}
	dd, err := strconv.Atoi(ddmmyy[0:2])
	if err != nil {
		return Date{}, errors.New(ddmmyy)
	}
	mm, err := strconv.Atoi(ddmmyy[2:4])
	if err != nil {
		return Date{}, errors.New(ddmmyy)
	}
	yy, err := strconv.Atoi(ddmmyy[4:6])
	if err != nil {
		return Date{}, errors.New(ddmmyy)
	}
	return Date{true, dd, mm, yy}, nil
}
1075038
func parseTwoNumeric(input string) (int, string) {
	if len(input) > 1 && input[0] == '0' {
		return 0, input[1:]
	}
	matched := twoDigitRegex.FindAllString(input, -1)
	if len(matched) == 0 {
		return 0, input
	}

	str := matched[0]
	v, err := strconv.ParseInt(str, 10, 64)
	if err != nil {
		return 0, input
	}
	return int(v), input[len(str):]
}
424763
func (c *Cell) getNumberFormat() *parsedNumberFormat {
	if c.parsedNumFmt == nil || c.parsedNumFmt.numFmt != c.NumFmt {
		c.parsedNumFmt = parseFullNumberFormatString(c.NumFmt)
	}
	return c.parsedNumFmt
}