func parseTimeFilterExpression()

in query/common/time_filter.go [241:338]


func parseTimeFilterExpression(expression string, now time.Time) (start, end time.Time, unit string, err error) {
	start, end = now, now
	unit = "m"
	if expression == "now" {
		unit = "s"
		return
	}

	if expression == "today" {
		expression = "this day"
	} else if expression == "yesterday" {
		expression = "last day"
	}

	var amount int
	segments := strings.Split(expression, " ")
	if segments[0] == "this" {
		if len(segments) != 2 {
			err = utils.StackError(nil, "Unknown time filter expression: %s", expression)
			return
		}
		unit = timeUnitMap[segments[1]]
		if unit == "" {
			err = utils.StackError(nil, "Unknown time filter unit: %s", segments[1])
		}
		start, end, err = applyTimeOffset(now, 0, unit)
		return
	} else if segments[0] == "last" {
		if len(segments) != 2 {
			err = utils.StackError(nil, "Unknown time filter expression: %s", expression)
			return
		}
		unit = timeUnitMap[segments[1]]
		if unit == "" {
			err = utils.StackError(nil, "Unknown time filter unit: %s", segments[1])
		}
		start, end, err = applyTimeOffset(now, -1, unit)
		return
	} else if segments[len(segments)-1] == "ago" {
		if len(segments) != 3 {
			err = utils.StackError(nil, "Unknown time filter expression: %s", expression)
			return
		}
		amount, err = strconv.Atoi(segments[0])
		if err != nil {
			err = utils.StackError(err, "failed to parse %s as a number", segments[0])
			return
		}
		unit = timeUnitMap[segments[1][:len(segments[1])-1]]
		if unit == "" {
			err = utils.StackError(nil, "Unknown time filter unit: %s", segments[1])
		}
		start, end, err = applyTimeOffset(now, -amount, unit)
		return
	} else if len(segments) == 1 {
		amount, err = strconv.Atoi(expression[:len(expression)-1])
		if err == nil {
			unit = expression[len(expression)-1:]
			start, end, err = applyTimeOffset(now, amount, unit)
			if err == nil {
				return
			}
		}
	}

	dateExpr := segments[0]
	var timeExpr string
	if len(segments) == 2 {
		timeExpr = segments[1]
	} else if len(segments) > 2 {
		err = utils.StackError(nil, "Unknown time filter expression: %s", expression)
		return
	} else if len(segments) == 1 {
		var seconds int64
		seconds, err = strconv.ParseInt(segments[0], 10, 64)
		if seconds > 99999999999 {
			//we will assume data over 99999999999 will be timestamp in ms, and convert it to be in seconds
			seconds = seconds / 1000
		}
		// Numbers above 9999999 are treated as timestamps, otherwise the corresponding Time object (of year 10000 and beyond)
		// will fail JSON marshaling, and criples debugz.
		if err == nil && seconds > 9999999 {
			t := time.Unix(seconds, 0).In(now.Location())
			rounded := t.Round(time.Minute)
			if rounded.Equal(t) {
				start = rounded
				end = rounded
				unit = "m"
			} else {
				start, end = t, t
				unit = "s"
			}
			return
		}
	}
	start, end, unit, err = parseAbsoluteTime(dateExpr, timeExpr, now.Location())
	return
}