add date util
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import { Time } from "timi-web";
|
||||
|
||||
/** 日期筛选器支持的预设范围。 */
|
||||
export type DateFilterPreset =
|
||||
| "all"
|
||||
| "today"
|
||||
| "yesterday"
|
||||
| "lastWeek"
|
||||
| "thisMonth"
|
||||
| "lastMonth"
|
||||
| "last7"
|
||||
| "last30";
|
||||
|
||||
/** 日期时间范围,文本格式为 YYYY-MM-DD HH:mm。 */
|
||||
export type DateTimeRange = [string, string];
|
||||
|
||||
/**
|
||||
* 根据预设筛选类型生成日期时间范围。
|
||||
*
|
||||
* `last7` 和 `last30` 为包含今天在内的最近 7 天和 30 天。
|
||||
*/
|
||||
export function buildPresetDateRange(type: DateFilterPreset, now = new Date()): DateTimeRange {
|
||||
if (type === "all") {
|
||||
return ["", ""];
|
||||
}
|
||||
|
||||
if (type === "lastWeek") {
|
||||
const current = getDateStart(now);
|
||||
const day = current.getDay() || 7;
|
||||
const thisWeekMonday = addDays(current, 1 - day);
|
||||
const lastWeekMonday = addDays(thisWeekMonday, -7);
|
||||
const lastWeekSunday = addDays(thisWeekMonday, -1);
|
||||
return buildDayRange(lastWeekMonday, lastWeekSunday);
|
||||
}
|
||||
|
||||
if (type === "thisMonth") {
|
||||
const current = new Date(now);
|
||||
const begin = new Date(current.getFullYear(), current.getMonth(), 1);
|
||||
return buildDayRange(begin, current);
|
||||
}
|
||||
|
||||
if (type === "lastMonth") {
|
||||
const current = new Date(now);
|
||||
const begin = new Date(current.getFullYear(), current.getMonth() - 1, 1);
|
||||
const end = new Date(current.getFullYear(), current.getMonth(), 0);
|
||||
return buildDayRange(begin, end);
|
||||
}
|
||||
|
||||
if (type === "last7" || type === "last30") {
|
||||
const end = new Date(now);
|
||||
end.setHours(23, 59, 0, 0);
|
||||
const begin = new Date(end);
|
||||
begin.setDate(begin.getDate() - (type === "last7" ? 6 : 29));
|
||||
begin.setHours(0, 0, 0, 0);
|
||||
return [Time.formatDateTime(begin), Time.formatDateTime(end)];
|
||||
}
|
||||
|
||||
const date = getDateStart(now);
|
||||
date.setDate(date.getDate() - (type === "today" ? 0 : 1));
|
||||
return buildDayRange(date, date);
|
||||
}
|
||||
|
||||
/** 将路由或组件输入转换为合法的日期筛选类型。 */
|
||||
export function parseDateFilterType<T extends string>(
|
||||
value: unknown,
|
||||
options: readonly { value: T }[],
|
||||
fallback: T
|
||||
): T {
|
||||
const text = Array.isArray(value) ? String(value[0] || "") : String(value || "");
|
||||
return options.some(item => item.value === text) ? text as T : fallback;
|
||||
}
|
||||
|
||||
/** 将日期时间文本解析为本地时间。空开始时间和空结束时间分别回退到 Unix 起点和当前时间。 */
|
||||
export function parseDateTime(value: string, isEnd: boolean): Date {
|
||||
if (!value) {
|
||||
return isEnd ? new Date() : new Date(0);
|
||||
}
|
||||
|
||||
const [dateText, timeText = isEnd ? "23:59" : "00:00"] = value.split(" ");
|
||||
const [year, month, day] = dateText.split("-").map(Number);
|
||||
const [hour, minute] = timeText.split(":").map(Number);
|
||||
return new Date(year, month - 1, day, hour || 0, minute || 0, isEnd ? 59 : 0, 0);
|
||||
}
|
||||
|
||||
function buildDayRange(begin: Date, end: Date): DateTimeRange {
|
||||
return [`${Time.formatDate(begin)} 00:00`, `${Time.formatDate(end)} 23:59`];
|
||||
}
|
||||
|
||||
function getDateStart(date: Date): Date {
|
||||
const value = new Date(date);
|
||||
value.setHours(0, 0, 0, 0);
|
||||
return value;
|
||||
}
|
||||
|
||||
function addDays(date: Date, days: number): Date {
|
||||
const value = new Date(date);
|
||||
value.setDate(value.getDate() + days);
|
||||
return value;
|
||||
}
|
||||
Reference in New Issue
Block a user