Files
dukang/packages/domain/src/shanghai-date.test.ts
T
jacy e26206b93c
CI / verify (pull_request) Has been cancelled
v4.0.3版本
总部后端,开发计划-任务列表-来源工单支持链接
总部端-开发计划-任务列表-编辑任务-增加“开发中”状态
账单日期修正
2026-08-31 14:22:49 +08:00

103 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from 'vitest';
import {
addShanghaiDays,
previousShanghaiMonth,
shanghaiLaggedIssueWindow,
shanghaiMonthLastInstant,
shanghaiMonthRange,
shanghaiPeriodYmds,
shanghaiT1DayWindow,
shanghaiYmd,
startOfShanghaiDay,
} from './shanghai-date';
describe('shanghaiYmd / startOfShanghaiDay', () => {
it('UTC 16:00 已是北京次日 00:00,账单日取北京日历日', () => {
const utc = new Date('2026-08-30T16:00:00.000Z');
expect(shanghaiYmd(utc)).toBe('2026-08-31');
expect(startOfShanghaiDay(utc).toISOString()).toBe('2026-08-30T16:00:00.000Z');
});
it('UTC 15:59 仍是北京当日', () => {
const utc = new Date('2026-08-30T15:59:59.000Z');
expect(shanghaiYmd(utc)).toBe('2026-08-30');
expect(startOfShanghaiDay(utc).toISOString()).toBe('2026-08-29T16:00:00.000Z');
});
it('不依赖服务器本地时区:输入 ISO 即得到北京自然日 00:00', () => {
const noonUtc = new Date('2026-08-30T04:00:00.000Z'); // 北京 12:00
expect(shanghaiYmd(noonUtc)).toBe('2026-08-30');
expect(startOfShanghaiDay(noonUtc).toISOString()).toBe('2026-08-29T16:00:00.000Z');
});
});
describe('shanghaiT1DayWindow', () => {
it('北京 8 月 30 日 08:00 出账:出账日 30 日,窗口为 29 日全天', () => {
const { start, end, billDate } = shanghaiT1DayWindow(new Date('2026-08-30T00:00:00.000Z'));
expect(shanghaiYmd(billDate)).toBe('2026-08-30');
expect(shanghaiYmd(start)).toBe('2026-08-29');
expect(end.toISOString()).toBe(billDate.toISOString());
});
it('北京 8 月 31 日 00:05:出账日仍是 31 日,不是 UTC 的 30 日', () => {
const { billDate } = shanghaiT1DayWindow(new Date('2026-08-30T16:05:00.000Z'));
expect(shanghaiYmd(billDate)).toBe('2026-08-31');
});
});
describe('shanghaiLaggedIssueWindow', () => {
it('酒厂 T+3:出账日是今天,纳入 3 天前完成的订单', () => {
const { start, end, billDate } = shanghaiLaggedIssueWindow(
new Date('2026-08-31T00:00:00.000Z'),
3,
);
expect(shanghaiYmd(billDate)).toBe('2026-08-31');
expect(shanghaiYmd(start)).toBe('2026-08-28');
expect(shanghaiYmd(end)).toBe('2026-08-29');
});
});
describe('addShanghaiDays', () => {
it('跨月跨年按北京日历加减', () => {
expect(shanghaiYmd(addShanghaiDays(new Date('2026-08-31T16:00:00.000Z'), 1))).toBe(
'2026-09-02',
);
expect(shanghaiYmd(addShanghaiDays(new Date('2026-01-01T00:00:00.000Z'), -1))).toBe(
'2025-12-31',
);
});
});
describe('shanghaiMonthRange', () => {
it('8 月账期为北京 8/1 00:00 至 9/1 00:00(不含)', () => {
const { start, endExclusive } = shanghaiMonthRange(2026, 8);
expect(start.toISOString()).toBe('2026-07-31T16:00:00.000Z');
expect(endExclusive.toISOString()).toBe('2026-08-31T16:00:00.000Z');
expect(shanghaiYmd(shanghaiMonthLastInstant(2026, 8))).toBe('2026-08-31');
});
it('UTC 月末 23:59:59 不会把账期止日滚成下月', () => {
const periodStart = new Date('2026-08-01T00:00:00.000Z');
expect(shanghaiPeriodYmds(periodStart)).toEqual({
periodStart: '2026-08-01',
periodEnd: '2026-08-31',
});
});
});
describe('previousShanghaiMonth', () => {
it('北京 9 月 1 日 08:00UTC 9/1 00:00)取 8 月', () => {
expect(previousShanghaiMonth(new Date('2026-09-01T00:00:00.000Z'))).toEqual({
year: 2026,
month: 8,
});
});
it('北京 9 月 1 日 00:30UTC 8/31 16:30)取 8 月,不因 UTC 仍是 8 月而错到 7 月', () => {
expect(previousShanghaiMonth(new Date('2026-08-31T16:30:00.000Z'))).toEqual({
year: 2026,
month: 8,
});
});
});