refactor: normalize date handling to Tehran timezone
- Updated date handling in BlogSeoFields and ScheduleSection to use Tehran timezone utilities for consistency. - Introduced `toTehranClockTime`, `tehranWallClockToUnix`, and `todayIso` functions for accurate date representation. - Modified various components to utilize these new utilities, ensuring that date strings are correctly formatted and timestamps are accurately converted. - Enhanced API documentation to clarify the handling of date fields, emphasizing the importance of server-local midnight. - Added tests to verify that date overrides and holidays maintain the correct day without shifting due to timezone discrepancies.
This commit is contained in:
@@ -16,6 +16,10 @@ import {
|
||||
formatDate,
|
||||
formatDateTime,
|
||||
toGregorianDate,
|
||||
toTehranClockTime,
|
||||
tehranWallClockToUnix,
|
||||
unixToIso,
|
||||
todayIso,
|
||||
maskMobile,
|
||||
cn,
|
||||
toEnglishDigits,
|
||||
@@ -107,6 +111,42 @@ describe('toGregorianDate', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('unixToIso / todayIso / toTehranClockTime', () => {
|
||||
// نیمهشبِ ۲۹ ژوئیهٔ ۲۰۲۶ به وقت تهران = ۲۸ ژوئیه ۲۰:۳۰ UTC. تبدیل با
|
||||
// toISOString همینجا یک روز عقب میرفت — رگرسیونِ «تاریخ خاص یک روز قبل».
|
||||
const tehranMidnight = Math.floor(Date.UTC(2026, 6, 28, 20, 30, 0) / 1000);
|
||||
|
||||
it('timestamp نیمهشبِ تهران همان روز را میدهد، نه روز قبل', () => {
|
||||
expect(unixToIso(tehranMidnight)).toBe('2026-07-29');
|
||||
});
|
||||
|
||||
it('لحظهٔ آخر شب به وقت تهران هنوز همان روز است', () => {
|
||||
const lateNight = Math.floor(Date.UTC(2026, 6, 29, 20, 0, 0) / 1000); // ۲۳:۳۰ تهران
|
||||
expect(unixToIso(lateNight)).toBe('2026-07-29');
|
||||
});
|
||||
|
||||
it('مقدار خالی رشتهٔ تهی میدهد', () => {
|
||||
expect(unixToIso(null)).toBe('');
|
||||
expect(unixToIso(undefined)).toBe('');
|
||||
});
|
||||
|
||||
it('todayIso همان تاریخ تهرانِ لحظهٔ جاری است', () => {
|
||||
expect(todayIso()).toBe(toGregorianDate(new Date()));
|
||||
expect(todayIso()).toMatch(/^\d{4}-\d{2}-\d{2}$/);
|
||||
});
|
||||
|
||||
it('ساعت دیواری تهران با رقم لاتین و ۲۴ساعته برمیگردد', () => {
|
||||
expect(toTehranClockTime(new Date(tehranMidnight * 1000))).toBe('00:00');
|
||||
expect(toTehranClockTime(new Date(Date.UTC(2026, 6, 29, 10, 0, 0)))).toBe('13:30');
|
||||
});
|
||||
|
||||
it('رفتوبرگشتِ tehranWallClockToUnix ↔ unixToIso روز را جابهجا نمیکند', () => {
|
||||
const ts = tehranWallClockToUnix('2026-07-29', '00:00');
|
||||
expect(ts).toBe(tehranMidnight);
|
||||
expect(unixToIso(ts)).toBe('2026-07-29');
|
||||
});
|
||||
});
|
||||
|
||||
describe('maskMobile', () => {
|
||||
it('شماره ۱۱ رقمی را ماسک میکند', () => {
|
||||
expect(maskMobile('09123456789')).toBe('0912***789');
|
||||
|
||||
Reference in New Issue
Block a user