e26206b93c
CI / verify (pull_request) Has been cancelled
总部后端,开发计划-任务列表-来源工单支持链接 总部端-开发计划-任务列表-编辑任务-增加“开发中”状态 账单日期修正
103 lines
3.6 KiB
TypeScript
103 lines
3.6 KiB
TypeScript
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:00(UTC 9/1 00:00)取 8 月', () => {
|
||
expect(previousShanghaiMonth(new Date('2026-09-01T00:00:00.000Z'))).toEqual({
|
||
year: 2026,
|
||
month: 8,
|
||
});
|
||
});
|
||
|
||
it('北京 9 月 1 日 00:30(UTC 8/31 16:30)取 8 月,不因 UTC 仍是 8 月而错到 7 月', () => {
|
||
expect(previousShanghaiMonth(new Date('2026-08-31T16:30:00.000Z'))).toEqual({
|
||
year: 2026,
|
||
month: 8,
|
||
});
|
||
});
|
||
});
|