Files
CRM_Montzar/apps/api/test/dates.test.ts
T

105 lines
3.7 KiB
TypeScript

import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import {
addJalaliMonths,
endOfJalaliMonth,
jalaliMonthName,
toGregorian,
toJalali,
} from '../src/common/jalali';
import {
addDays,
dayDiff,
eachDay,
isDayKey,
isTimeOfDay,
jalaliDayOfMonth,
persianWeekday,
tehranDateTime,
tehranDayKey,
tehranHour,
weekStartKey,
} from '../src/routines/routine-dates';
import {
formatTehranJalaliNumeric,
isDueInDays,
} from '../src/finance/cheque-reminder.util';
describe('تبدیل تاریخ شمسی', () => {
const pairs: Array<[[number, number, number], [number, number, number]]> = [
[[2026, 10, 8], [1405, 7, 16]],
[[2025, 3, 21], [1404, 1, 1]],
[[2024, 3, 20], [1403, 1, 1]],
[[2025, 3, 20], [1403, 12, 30]],
[[2000, 1, 1], [1378, 10, 11]],
];
for (const [[gy, gm, gd], [jy, jm, jd]] of pairs) {
it(`${gy}-${gm}-${gd} ⇄ ${jy}/${jm}/${jd}`, () => {
assert.deepEqual(toJalali(gy, gm, gd), { jy, jm, jd });
assert.deepEqual(toGregorian(jy, jm, jd), { gy, gm, gd });
});
}
it('رفت‌وبرگشت برای هر روز دو سال', () => {
const d = new Date(Date.UTC(2024, 0, 1));
for (let i = 0; i < 731; i += 1) {
const gy = d.getUTCFullYear();
const gm = d.getUTCMonth() + 1;
const gd = d.getUTCDate();
const j = toJalali(gy, gm, gd);
assert.deepEqual(toGregorian(j.jy, j.jm, j.jd), { gy, gm, gd });
d.setUTCDate(gd + 1);
}
});
it('ماه‌ها', () => {
assert.deepEqual(addJalaliMonths(1405, 12, 1), { jy: 1406, jm: 1 });
assert.deepEqual(addJalaliMonths(1405, 1, -1), { jy: 1404, jm: 12 });
assert.equal(jalaliMonthName(7), 'مهر');
assert.equal(jalaliMonthName(13), '');
const end = endOfJalaliMonth(1405, 6);
const j = toJalali(end.getFullYear(), end.getMonth() + 1, end.getDate());
assert.deepEqual(j, { jy: 1405, jm: 6, jd: 31 });
});
});
describe('روزهای روتین (وقت تهران)', () => {
it('کلید روز با منطقهٔ زمانی تهران', () => {
// ۰۰:۳۰ بامداد تهران = ۲۱:۰۰ UTC روز قبل
assert.equal(tehranDayKey(new Date('2026-10-07T21:00:00Z')), '2026-10-08');
assert.equal(tehranDayKey(new Date('2026-10-07T20:29:00Z')), '2026-10-07');
assert.equal(tehranHour(new Date('2026-10-07T21:00:00Z')), 0);
});
it('اعتبارسنجی', () => {
assert.ok(isDayKey('2026-10-08'));
assert.ok(!isDayKey('1405/07/16'));
assert.ok(isTimeOfDay('23:59'));
assert.ok(!isTimeOfDay('24:00'));
});
it('محاسبات روز و هفته', () => {
assert.equal(addDays('2026-12-31', 1), '2027-01-01');
assert.equal(dayDiff('2026-10-01', '2026-10-08'), 7);
assert.equal(persianWeekday('2026-10-08'), 5); // پنجشنبه
assert.equal(persianWeekday('2026-10-03'), 0); // شنبه
assert.equal(weekStartKey('2026-10-08'), '2026-10-03');
assert.equal(jalaliDayOfMonth('2026-10-08'), 16);
assert.deepEqual(eachDay('2026-10-01', '2026-10-03'), ['2026-10-01', '2026-10-02', '2026-10-03']);
assert.equal(tehranDateTime('2026-10-08', '09:00').toISOString(), '2026-10-08T05:30:00.000Z');
});
});
describe('یادآور چک', () => {
it('تاریخ شمسی به وقت تهران', () => {
assert.equal(formatTehranJalaliNumeric(new Date('2026-10-08T10:00:00Z')), '۱۴۰۵/۰۷/۱۶');
assert.equal(formatTehranJalaliNumeric(new Date('2026-10-07T21:00:00Z')), '۱۴۰۵/۰۷/۱۶');
});
it('سررسید سه روز بعد', () => {
const now = new Date('2026-10-08T06:00:00Z');
assert.ok(isDueInDays(new Date('2026-10-11T12:00:00Z'), 3, now));
assert.ok(!isDueInDays(new Date('2026-10-12T12:00:00Z'), 3, now));
});
});