li / web /src /lib /time.ts
xiaolongmr
Add shop quota management and China time display
a1ff683
Raw
History Blame Contribute Delete
2.51 kB
const CHINA_TIME_ZONE = "Asia/Shanghai";
const PLAIN_DATE_TIME_RE = /^(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2})(?::(\d{2}))?)?$/;
function pad(value: string | undefined) {
return value || "00";
}
function formatPlainChinaDateTime(value: string, withSeconds = false) {
const match = value.trim().match(PLAIN_DATE_TIME_RE);
if (!match) {
return null;
}
const [, year, month, day, hour, minute, second] = match;
if (!hour || !minute) {
return `${year}/${month}/${day}`;
}
return withSeconds
? `${year}/${month}/${day} ${hour}:${minute}:${pad(second)}`
: `${year}/${month}/${day} ${hour}:${minute}`;
}
export function formatChinaDateTime(value?: string | number | null, options?: { seconds?: boolean }) {
if (value === null || value === undefined || value === "") {
return "—";
}
const raw = String(value).trim();
const plain = formatPlainChinaDateTime(raw, Boolean(options?.seconds));
if (plain) {
return plain;
}
const date = new Date(raw);
if (Number.isNaN(date.getTime())) {
return raw;
}
return new Intl.DateTimeFormat("zh-CN", {
timeZone: CHINA_TIME_ZONE,
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: options?.seconds ? "2-digit" : undefined,
hour12: false,
}).format(date);
}
export function formatChinaShortDateTime(value?: string | number | null) {
if (value === null || value === undefined || value === "") {
return "";
}
const raw = String(value).trim();
const plain = formatPlainChinaDateTime(raw);
if (plain) {
return plain.slice(5);
}
const date = new Date(raw);
if (Number.isNaN(date.getTime())) {
return raw;
}
return new Intl.DateTimeFormat("zh-CN", {
timeZone: CHINA_TIME_ZONE,
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
hour12: false,
}).format(date);
}
export function formatChinaTime(value?: string | number | null) {
if (value === null || value === undefined || value === "") {
return "";
}
const raw = String(value).trim();
const match = raw.match(PLAIN_DATE_TIME_RE);
if (match?.[4] && match?.[5]) {
return `${match[4]}:${match[5]}:${pad(match[6])}`;
}
const date = new Date(raw);
if (Number.isNaN(date.getTime())) {
return raw;
}
return new Intl.DateTimeFormat("zh-CN", {
timeZone: CHINA_TIME_ZONE,
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false,
}).format(date);
}