's'
This commit is contained in:
123
app/lib/dates.ts
123
app/lib/dates.ts
@@ -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`,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user