This commit is contained in:
eric
2026-03-18 02:01:48 -05:00
parent 742c293e14
commit bf10b5d7e4
11 changed files with 415 additions and 138 deletions

View File

@@ -6,6 +6,7 @@ const TZ = "Asia/Shanghai";
/**
* 获取中国时区下的日期数字(月、日、星期)
* 无论服务器/客户端在何地,均返回中国公历
*/
function getChinaDateParts(): { year: number; month: number; day: number; weekday: number } {
const now = new Date();
@@ -28,6 +29,27 @@ function getChinaDateParts(): { year: number; month: number; day: number; weekda
};
}
/**
* 获取当前中国公历时间字符串,用于上传
* 格式:YYYY-MM-DD HH:mm:ss(中国时区)
*/
export function getNowChinaStr(): string {
const formatter = new Intl.DateTimeFormat("en-CA", {
timeZone: TZ,
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false,
});
const parts = formatter.formatToParts(new Date());
const pad = (s: string) => s.padStart(2, "0");
const get = (type: string) => parts.find((p) => p.type === type)?.value ?? "0";
return `${get("year")}-${pad(get("month"))}-${pad(get("day"))} ${pad(get("hour"))}:${pad(get("minute"))}:${pad(get("second"))}`;
}
/**
* 格式化为中文日期:M月D日 周X
*/
@@ -36,48 +58,75 @@ function formatDateCN(month: number, day: number, weekday: number): string {
}
/**
* 获取下一个周六、周日的日期(中国日历)
* session-1 对应周六,session-2 对应周日
* 获取下一个周六、周日的日期(中国公历)
* 使用 +08:00 显式构造,避免服务器/客户端时区影响
*/
export function getNextWeekendDates(): { saturday: string; sunday: string } {
const { year, month, day, weekday } = getChinaDateParts();
const pad = (n: number) => String(n).padStart(2, "0");
const todayStr = `${year}-${pad(month)}-${pad(day)}T12:00:00+08:00`;
const today = new Date(todayStr);
let satM = month;
let satD = day;
let satW = 6;
let sunM = month;
let sunD = day;
let sunW = 0;
if (weekday === 0) {
// 今天周日:下周六 +6 天,下周日 +7 天
const d = new Date(year, month - 1, day);
d.setDate(d.getDate() + 6);
satM = d.getMonth() + 1;
satD = d.getDate();
d.setDate(d.getDate() + 1);
sunM = d.getMonth() + 1;
sunD = d.getDate();
} else if (weekday === 6) {
// 今天周六:明天周日
const d = new Date(year, month - 1, day);
d.setDate(d.getDate() + 1);
sunM = d.getMonth() + 1;
sunD = d.getDate();
} else {
// 周一至周五
const daysToSat = 6 - weekday;
const d = new Date(year, month - 1, day);
d.setDate(d.getDate() + daysToSat);
satM = d.getMonth() + 1;
satD = d.getDate();
d.setDate(d.getDate() + 1);
sunM = d.getMonth() + 1;
sunD = d.getDate();
}
const daysToSat = weekday === 0 ? 6 : weekday === 6 ? 0 : 6 - weekday;
const saturday = new Date(today);
saturday.setUTCDate(saturday.getUTCDate() + daysToSat);
const sunday = new Date(saturday);
sunday.setUTCDate(sunday.getUTCDate() + 1);
return {
saturday: formatDateCN(satM, satD, 6),
sunday: formatDateCN(sunM, sunD, 0),
saturday: formatDateCN(saturday.getUTCMonth() + 1, saturday.getUTCDate(), 6),
sunday: formatDateCN(sunday.getUTCMonth() + 1, sunday.getUTCDate(), 0),
};
}
/**
* 获取中国公历本周一 00:00 至周日 23:59:59 的 UTC 时间范围
* 用于 PocketBase created 过滤。PocketBase 要求 Y-m-d H:i:s.uZ 格式(空格非 T)
*/
export function getThisWeekRangeISO(): { start: string; end: string } {
const { year, month, day, weekday } = getChinaDateParts();
const pad = (n: number) => String(n).padStart(2, "0");
const todayStr = `${year}-${pad(month)}-${pad(day)}T12:00:00+08:00`;
const today = new Date(todayStr);
const daysToMonday = weekday === 0 ? 6 : weekday - 1;
const monday = new Date(today);
monday.setUTCDate(monday.getUTCDate() - daysToMonday);
const sunday = new Date(monday);
sunday.setUTCDate(sunday.getUTCDate() + 6);
const mondayStr = `${monday.getUTCFullYear()}-${pad(monday.getUTCMonth() + 1)}-${pad(monday.getUTCDate())}T00:00:00+08:00`;
const sundayStr = `${sunday.getUTCFullYear()}-${pad(sunday.getUTCMonth() + 1)}-${pad(sunday.getUTCDate())}T23:59:59.999+08:00`;
const startDate = new Date(mondayStr);
const endDate = new Date(sundayStr);
const fmt = (d: Date, ms: string) => {
const y = d.getUTCFullYear();
const m = pad(d.getUTCMonth() + 1);
const day = pad(d.getUTCDate());
const h = pad(d.getUTCHours());
const min = pad(d.getUTCMinutes());
const s = pad(d.getUTCSeconds());
return `${y}-${m}-${day} ${h}:${min}:${s}.${ms}Z`;
};
return {
start: fmt(startDate, "000"),
end: fmt(endDate, "999"),
};
}
/**
* 获取中国公历本周一、周日的日期字符串(YYYY-MM-DD),用于 submitted_at_cn 过滤
*/
export function getThisWeekRangeChinaStr(): { start: string; end: string } {
const { year, month, day, weekday } = getChinaDateParts();
const pad = (n: number) => String(n).padStart(2, "0");
const todayStr = `${year}-${pad(month)}-${pad(day)}T12:00:00+08:00`;
const today = new Date(todayStr);
const daysToMonday = weekday === 0 ? 6 : weekday - 1;
const monday = new Date(today);
monday.setUTCDate(monday.getUTCDate() - daysToMonday);
const sunday = new Date(monday);
sunday.setUTCDate(sunday.getUTCDate() + 6);
return {
start: `${monday.getUTCFullYear()}-${pad(monday.getUTCMonth() + 1)}-${pad(monday.getUTCDate())} 00:00:00`,
end: `${sunday.getUTCFullYear()}-${pad(sunday.getUTCMonth() + 1)}-${pad(sunday.getUTCDate())} 23:59:59`,
};
}