import type { TimeInterval } from "../models/common"; import { addDays, addMonths, addYears, formatDate, startOfDay, startOfMonth, startOfWeek, startOfYear } from "./date"; export default function parseInterval(s: string, date: Date): TimeInterval { const [verb, args] = s.split(":") switch (verb) { case "": case "all_time": return null; case "next": { const [amount, unit] = unitNumber(args); switch (unit) { case "d": case "days": return {display: "days", min: startOfDay(date), max: startOfDay(addDays(date, amount))} case "w": case "weeks": return {display: "days", min: startOfDay(date), max: startOfDay(addDays(date, amount * 7))} case "m": case "months": return {display: "days", min: startOfDay(date), max: startOfDay(addMonths(date, amount))} case "y": case "years": return {display: "none", min: startOfDay(date), max: startOfDay(addYears(date, amount))} } } case "last": { const [amount, unit] = unitNumber(args); switch (unit) { case "d": case "days": return {display: "days", min: startOfDay(addDays(date, -amount)), max: startOfDay(addDays(date, 1))} case "w": case "weeks": return {display: "weeks", min: startOfDay(addDays(date, -amount * 7)), max: startOfDay(addDays(date, 1))} case "m": case "months": return {display: "days", min: startOfDay(addMonths(date, -amount)), max: startOfDay(addDays(date, 1))} case "y": case "years": return {display: "none", min: startOfDay(addYears(date, -amount)), max: startOfDay(addDays(date, 1))} } } case "today": return {display: "none", min: startOfDay(date), max: startOfDay(addDays(date, 1))} case "next_week": return {display: "weeks", min: startOfWeek(addDays(date, 7)), max: startOfWeek(addDays(date, 14))} case "this_week": return {display: "weeks", min: startOfWeek(date), max: startOfWeek(addDays(date, 7))} case "last_week": return {display: "weeks", min: startOfWeek(addDays(date, -7)), max: startOfWeek(date)} case "next_month": return {display: "month", min: startOfMonth(addMonths(date, 1)), max: startOfMonth(addMonths(date, 2))} case "this_month": return {display: "month", min: startOfMonth(date), max: startOfMonth(addMonths(date, 1))} case "last_month": return {display: "month", min: startOfMonth(addMonths(date, -1)), max: startOfMonth(date)} case "next_year": return {display: "year", min: startOfYear(addYears(date, 1)), max: startOfYear(addYears(date, 2))} case "this_year": return {display: "year", min: startOfYear(date), max: startOfYear(addYears(date, 1))} case "last_year": return {display: "year", min: startOfYear(addYears(date, -1)), max: startOfYear(date)} } } export function intervalLabel(s: string): string { const [verb, args] = s.split(":") switch (verb) { case "": return "All time"; case "next": case "last": { const [amount, unit] = unitNumber(args); switch (unit) { case "d": case "days": return `${capitalize(verb)} ${amount} ${amount !== 1 ? "days" : "day"}` case "w": case "weeks": return `${capitalize(verb)} ${amount} ${amount !== 1 ? "weeks" : "week"}` case "m": case "months": return `${capitalize(verb)} ${amount} ${amount !== 1 ? "months" : "month"}` case "y": case "years": return `${capitalize(verb)} ${amount} ${amount !== 1 ? "years" : "year"}` } } case "today": return verb; case "all_time": case "next_week": case "this_week": case "last_week": case "next_month": case "this_month": case "last_month": case "next_year": case "this_year": case "last_year": return capitalize(verb.replace("_", " ")); } } export function datesOf(interval: TimeInterval): TimeInterval { if (interval == null) { return void(0) } return {min: formatDate(interval.min), max: formatDate(interval.max)} } function capitalize(s: string) { return `${s.charAt(0).toLocaleUpperCase()}${s.slice(1)}` } function unitNumber(s: string): [number, string] { for (let i = 0; i < s.length; ++i) { const ch = s.charAt(i); if (ch < '0' || ch > '9') { return [parseInt(s.slice(0, i)), s.slice(i)] } } return [parseInt(s), ""]; }