// parseDuration parses a duration string, like time.ParseDuration
// but is empty string friendly, returns a zero time duration
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)
}
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)
}
1255081
func ToDurationE(i interface{}) (d time.Duration, err error) {
	i = indirect(i)

	switch s := i.(type) {
	case time.Duration:
		return s, nil
	case int, int64, int32, int16, int8, uint, uint64, uint32, uint16, uint8:
		d = time.Duration(ToInt64(s))
		return
	case float32, float64:
		d = time.Duration(ToFloat64(s))
		return
	case string:
		if strings.ContainsAny(s, "nsuµmh") {
			d, err = time.ParseDuration(s)
		} else {
			d, err = time.ParseDuration(s + "ns")
		}
		return
	default:
		err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i)
		return
	}
}
1268189
func Duration(val interface{}) time.Duration {
	switch t := val.(type) {
	case int:
		return time.Duration(int64(t))
	case int8:
		return time.Duration(int64(t))
	case int16:
		return time.Duration(int64(t))
	case int32:
		return time.Duration(int64(t))
	case int64:
		return time.Duration(t)
	case uint:
		return time.Duration(int64(t))
	case uint8:
		return time.Duration(int64(t))
	case uint16:
		return time.Duration(int64(t))
	case uint32:
		return time.Duration(int64(t))
	case uint64:
		return time.Duration(int64(t))
	default:
		return strToDuration(String(val))
	}
	panic("Reached")
}
831014
func Duration(input interface{}) (output time.Duration, err error) {
	switch castValue := input.(type) {
	case string:
		output, err = time.ParseDuration(castValue)
		if err != nil {
			outputInt, errCast := Int(castValue)
			if errCast != nil {
				err = NewCastError("Could not convert to time.Duration")
				return
			}
			output = time.Duration(int(outputInt))
		}
		return
	case time.Duration:
		output = castValue
		return
	default:
		outputInt, errCast := Int(castValue)
		if errCast == nil {
			output = time.Duration(int(outputInt))
			return
		}
		err = NewCastError("Could not convert to time.Duration")
	}
	return
}
1352094
func (b *builtinAddDurationAndStringSig) evalDuration(row chunk.Row) (types.Duration, bool, error) {
	arg0, isNull, err := b.args[0].EvalDuration(b.ctx, row)
	if isNull || err != nil {
		return types.ZeroDuration, isNull, err
	}
	s, isNull, err := b.args[1].EvalString(b.ctx, row)
	if isNull || err != nil {
		return types.ZeroDuration, isNull, err
	}
	if !isDuration(s) {
		return types.ZeroDuration, true, nil
	}
	arg1, err := types.ParseDuration(b.ctx.GetSessionVars().StmtCtx, s, types.GetFsp(s))
	if err != nil {
		return types.ZeroDuration, true, err
	}
	result, err := arg0.Add(arg1)
	if err != nil {
		return types.ZeroDuration, true, err
	}
	return result, false, nil
}
179058
func (ec *Envcfg) GetDuration(key string) time.Duration {
	d, _ := time.ParseDuration(ec.GetKey(key))
	return d
}
1226125
func stringToReadableDurationFunc() mapstructure.DecodeHookFunc {
	return func(
		f reflect.Type,
		t reflect.Type,
		data interface{}) (interface{}, error) {
		var v api.ReadableDuration
		if t != reflect.TypeOf(v) {
			return data, nil
		}

		switch {
		case f.Kind() == reflect.String:
			if dur, err := time.ParseDuration(data.(string)); err != nil {
				return nil, err
			} else {
				v = api.ReadableDuration(dur)
			}
			return v, nil
		default:
			return data, nil
		}
	}
}
627288
func (e *EncodeSession) FrameDuration() time.Duration {
	return time.Duration(e.options.FrameDuration) * time.Millisecond
}
483516
func (b *builtinCaseWhenDurationSig) evalDuration(row chunk.Row) (ret types.Duration, isNull bool, err error) {
	var condition int64
	args, l := b.getArgs(), len(b.getArgs())
	for i := 0; i < l-1; i += 2 {
		condition, isNull, err = args[i].EvalInt(b.ctx, row)
		if err != nil {
			return ret, true, err
		}
		if isNull || condition == 0 {
			continue
		}
		ret, isNull, err = args[i+1].EvalDuration(b.ctx, row)
		return ret, isNull, err
	}
	// when clause(condition, result) -> args[i], args[i+1]; (i >= 0 && i+1 < l-1)
	// else clause -> args[l-1]
	// If case clause has else clause, l%2 == 1.
	if l%2 == 1 {
		ret, isNull, err = args[l-1].EvalDuration(b.ctx, row)
		return ret, isNull, err
	}
	return ret, true, nil
}
638024
func (b *builtinTimeLiteralSig) evalDuration(row chunk.Row) (types.Duration, bool, error) {
	return b.duration, false, nil
}
1152153
func parseDuration(lease string) time.Duration {
	dur, err := time.ParseDuration(lease)
	if err != nil {
		dur, err = time.ParseDuration(lease + "s")
	}
	if err != nil || dur < 0 {
		log.Fatal("invalid lease duration", zap.String("lease", lease))
	}
	return dur
}
680048
func (c *ConfigLookup) GetDuration(key string) time.Duration {
	value, ok := c.Lookup(key)
	if !ok {
		return 0
	}
	return cast.ToDuration(value)
}
1033879
func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration {
	p := new(time.Duration)
	f.DurationVar(p, name, value, usage)
	return p
}
360925
func ParseDuration(s string) (time.Duration, error) {
	rx := regexp.MustCompile(`(?i)^\s*(-?\d+)(d|w|y)\s*$`)
	rs := rx.FindStringSubmatch(s)

	if len(rs) > 0 {
		zeroDuration, _ := time.ParseDuration("0s")
		quantity := rs[1]
		units := strings.ToLower(rs[2])
		i, err := strconv.Atoi(quantity)
		if err != nil {
			return zeroDuration, err
		}
		if units == "d" {
			s = fmt.Sprintf("%vs", i*DaySeconds)
		} else if units == "w" {
			s = fmt.Sprintf("%vs", i*WeekSeconds)
		} else if units == "y" {
			s = fmt.Sprintf("%vs", i*YearSeconds)
		} else {
			return zeroDuration, errors.New("timeutil.ParseDuration Parse Error")
		}
	}
	return time.ParseDuration(s)
}
345501
func ParseDurationString(input string, args ...interface{}) (*Durafmt, error) {
	if input == "0" || input == "-0" {
		return nil, errors.New("durafmt: missing unit in duration " + input)
	}
	duration, err := time.ParseDuration(input)
	if err != nil {
		return nil, err
	}
	return &Durafmt{duration, input, getDurationUnits(args)}, nil
}
377912
func (p *parserMixin) Duration() (target *time.Duration) {
	target = new(time.Duration)
	p.DurationVar(target)
	return
}