// See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_datediff
9784
func builtinDateDiff(args []types.Datum, ctx context.Context) (d types.Datum, err error) {
	sc := ctx.GetSessionVars().StmtCtx
	t1, err := convertDatumToTime(sc, args[0])
	if err != nil {
		return d, errors.Trace(err)
	}

	t2, err := convertDatumToTime(sc, args[1])
	if err != nil {
		return d, errors.Trace(err)
	}

	if t1.Time.Month() == 0 || t1.Time.Day() == 0 || t2.Time.Month() == 0 || t2.Time.Day() == 0 {
		return d, nil
	}

	r := types.DateDiff(t1.Time, t2.Time)
	d.SetInt64(int64(r))
	return d, nil
}
1132257
func (b *builtinFromDaysSig) evalTime(row chunk.Row) (types.Time, bool, error) {
	n, isNull, err := b.args[0].EvalInt(b.ctx, row)
	if isNull || err != nil {
		return types.Time{}, true, err
	}

	return types.TimeFromDays(n), false, nil
}
786033
func CalculateDiff(options *Options) (*Result, error) {
	baseVersionQuery := models.GetDashboardVersionQuery{
		DashboardId: options.Base.DashboardId,
		Version:     options.Base.Version,
		OrgId:       options.OrgId,
	}

	if err := bus.Dispatch(&baseVersionQuery); err != nil {
		return nil, err
	}

	newVersionQuery := models.GetDashboardVersionQuery{
		DashboardId: options.New.DashboardId,
		Version:     options.New.Version,
		OrgId:       options.OrgId,
	}

	if err := bus.Dispatch(&newVersionQuery); err != nil {
		return nil, err
	}

	baseData := baseVersionQuery.Result.Data
	newData := newVersionQuery.Result.Data

	left, jsonDiff, err := getDiff(baseData, newData)
	if err != nil {
		return nil, err
	}

	result := &Result{}

	switch options.DiffType {
	case DiffDelta:

		deltaOutput, err := deltaFormatter.NewDeltaFormatter().Format(jsonDiff)
		if err != nil {
			return nil, err
		}
		result.Delta = []byte(deltaOutput)

	case DiffJSON:
		jsonOutput, err := NewJSONFormatter(left).Format(jsonDiff)
		if err != nil {
			return nil, err
		}
		result.Delta = []byte(jsonOutput)

	case DiffBasic:
		basicOutput, err := NewBasicFormatter(left).Format(jsonDiff)
		if err != nil {
			return nil, err
		}
		result.Delta = basicOutput

	default:
		return nil, ErrUnsupportedDiffType
	}

	return result, nil
}
755075
func Date(db XODB, v0 pgtypes.Abstime, v1 time.Time, v2 time.Time) (time.Time, error) {
	var err error

	// sql query
	const sqlstr = `SELECT pg_catalog.date($1, $2, $3)`

	// run query
	var ret time.Time
	XOLog(sqlstr, v0, v1, v2)
	err = db.QueryRow(sqlstr, v0, v1, v2).Scan(&ret)
	if err != nil {
		return time.Time{}, err
	}

	return ret, nil
}
306584
func builtinFromDays(args []types.Datum, ctx context.Context) (d types.Datum, err error) {
	days, err := args[0].ToInt64(ctx.GetSessionVars().StmtCtx)
	d.SetMysqlTime(types.TimeFromDays(days))
	return d, nil
}
370061
func Diff(a, b interface{}) (desc []string) {
	Pdiff((*sbuf)(&desc), a, b)
	return desc
}
710711
func TimeToDate(t time.Time) *google_type.Date {
	return NewDate(int32(t.Month()), int32(t.Day()), int32(t.Year()))
}
1366213
func (t *Time) StrToDate(date, format string) bool {
	ctx := make(map[string]int)
	var tm mysqlTime
	if !strToDate(&tm, date, format, ctx) {
		t.Time = ZeroTime
		t.Type = mysql.TypeDatetime
		t.Fsp = 0
		return false
	}
	if err := mysqlTimeFix(&tm, ctx); err != nil {
		return false
	}

	t.Time = tm
	t.Type = mysql.TypeDatetime
	if t.check() != nil {
		return false
	}
	return true
}
1230315
func Ldiff(l Logfer, a, b interface{}) {
	Pdiff(&logprintfer{l}, a, b)
}
784785
func (d date) Date(year, month, day int, loc *time.Location) time.Time {
	return time.Date(year, time.Month(month), day, 12, 0, 0, 0, loc)
}
479780
func (d *Datum) GetMysqlDuration() Duration {
	return Duration{Duration: time.Duration(d.i), Fsp: int(d.decimal)}
}
1029222
func calcWeek(t *MysqlTime, wb weekBehaviour) (year int, week int) {
	var days int
	daynr := calcDaynr(int(t.year), int(t.month), int(t.day))
	firstDaynr := calcDaynr(int(t.year), 1, 1)
	mondayFirst := wb.test(weekBehaviourMondayFirst)
	weekYear := wb.test(weekBehaviourYear)
	firstWeekday := wb.test(weekBehaviourFirstWeekday)

	weekday := calcWeekday(firstDaynr, !mondayFirst)

	year = int(t.year)

	if t.month == 1 && int(t.day) <= 7-weekday {
		if !weekYear &&
			((firstWeekday && weekday != 0) || (!firstWeekday && weekday >= 4)) {
			week = 0
			return
		}
		weekYear = true
		year--
		days = calcDaysInYear(year)
		firstDaynr -= days
		weekday = (weekday + 53*7 - days) % 7
	}

	if (firstWeekday && weekday != 0) ||
		(!firstWeekday && weekday >= 4) {
		days = daynr - (firstDaynr + 7 - weekday)
	} else {
		days = daynr - (firstDaynr - weekday)
	}

	if weekYear && days >= 52*7 {
		weekday = (weekday + calcDaysInYear(year)) % 7
		if (!firstWeekday && weekday < 4) ||
			(firstWeekday && weekday == 0) {
			year++
			week = 1
			return
		}
	}
	week = days/7 + 1
	return
}
618324
func (dt DateTime) Date() (year int, month time.Month, day int) {
	return dt.t.Date()
}
92627
func calcTimeDiff(t1, t2 MysqlTime, sign int) (seconds, microseconds int, neg bool) {
	days := calcDaynr(t1.Year(), t1.Month(), t1.Day())
	days2 := calcDaynr(t2.Year(), t2.Month(), t2.Day())
	days -= sign * days2

	tmp := (int64(days)*secondsIn24Hour+
		int64(t1.Hour())*3600+int64(t1.Minute())*60+
		int64(t1.Second())-
		int64(sign)*(int64(t2.Hour())*3600+int64(t2.Minute())*60+
			int64(t2.Second())))*
		1e6 +
		int64(t1.Microsecond()) - int64(sign)*int64(t2.Microsecond())

	if tmp < 0 {
		tmp = -tmp
		neg = true
	}
	seconds = int(tmp / 1e6)
	microseconds = int(tmp % 1e6)
	return
}
1260163
func (t MysqlTime) YearDay() int {
	if t.month == 0 || t.day == 0 {
		return 0
	}
	return calcDaynr(int(t.year), int(t.month), int(t.day)) -
		calcDaynr(int(t.year), 1, 1) + 1
}
1062965
func (d Date) Date() (year int, month time.Month, day int) {
	return d.t.Date()
}
946406
func (b *builtinUTCDateSig) evalTime(row chunk.Row) (types.Time, bool, error) {
	var nowTs = &b.ctx.GetSessionVars().StmtCtx.NowTs
	if nowTs.Equal(time.Time{}) {
		*nowTs = time.Now()
	}
	year, month, day := nowTs.UTC().Date()
	result := types.Time{
		Time: types.FromGoTime(time.Date(year, month, day, 0, 0, 0, 0, time.UTC)),
		Type: mysql.TypeDate,
		Fsp:  types.UnspecifiedFsp}
	return result, false, nil
}