TypeScript中实现两个波斯历日期相减计算时长的问题求助
解决波斯历日期与API日期相减的问题
我明白你遇到的困扰了——想拿当前波斯历日期和API返回的日期计算时间差,但因为把波斯历转成字符串后没法生成有效的时间戳,导致减法运算直接失败。咱们先拆解问题根源,再一步步搞定:
问题出在哪?
你原来的代码里,new Date().toLocaleDateString('fa-IR').replace(...)得到的是波斯历日期的字符串(比如"1403/05/12"),哪怕替换成阿拉伯数字后还是字符串类型。调用valueOf()对字符串来说,返回的只是字符串本身,不是时间戳;而new Date(arr).valueOf()是把API返回的日期转成了数字类型的时间戳,字符串减数字自然会得到NaN或者错误结果。
要解决这个问题,核心是把波斯历日期转换成JavaScript能识别的公历Date对象,这样才能拿到正确的时间戳进行计算。下面给你两种可行方案:
方案一:用原生Intl API处理(无需第三方库)
原生的Intl.DateTimeFormat可以帮我们解析波斯历的日期部分,再转成公历Date对象。注意要指定正确的时区(伊朗标准时间Asia/Tehran),避免日期偏移:
let arr; this.formsService.get_date_duration().subscribe(res => { arr = res; // 1. 获取当前波斯历的年、月、日(阿拉伯数字) const persianFormatter = new Intl.DateTimeFormat('fa-IR-u-ca-persian', { year: 'numeric', month: '2-digit', day: '2-digit', timeZone: 'Asia/Tehran' }); const dateParts = persianFormatter.formatToParts(new Date()); const persianYear = parseInt(dateParts.find(p => p.type === 'year').value); const persianMonth = parseInt(dateParts.find(p => p.type === 'month').value) - 1; // 月份从0开始计数 const persianDay = parseInt(dateParts.find(p => p.type === 'day').value); // 2. 将波斯历日期转换为公历Date对象(用反向格式化技巧) const gregorianFormatter = new Intl.DateTimeFormat('en-US', { year: 'numeric', month: '2-digit', day: '2-digit', timeZone: 'Asia/Tehran' }); const tempDate = new Date(Date.UTC(persianYear, persianMonth, persianDay)); const gregorianDateStr = gregorianFormatter.format(tempDate); const eventStartTime = new Date(gregorianDateStr).setHours(0, 0, 0, 0); // 设置为当天0点的时间戳 // 3. 处理API返回的日期,转成时间戳 const eventEndTime = new Date(arr).setHours(0, 0, 0, 0); // 4. 计算时长(单位:毫秒),按需转成天数/小时等 const duration = eventStartTime - eventEndTime; const daysDiff = Math.abs(duration) / (1000 * 60 * 60 * 24); console.log("时长(毫秒):", duration); console.log("天数差:", daysDiff.toFixed(1)); });
方案二:用专门的波斯历库(更可靠)
原生API处理波斯历多少有点绕,想省心的话可以用jalaali-js这个轻量级库,它专门用来处理波斯历(Jalaali)和公历的转换:
第一步:安装库
npm install jalaali-js
第二步:在代码中使用
import * as jalaali from 'jalaali-js'; let arr; this.formsService.get_date_duration().subscribe(res => { arr = res; // 1. 获取当前时间对应的波斯历日期 const now = new Date(); const currentPersian = jalaali.toJalaali(now.getFullYear(), now.getMonth() + 1, now.getDate()); // currentPersian 结构:{ jy: 1403, jm: 5, jd: 12 } // 2. 把波斯历日期转成公历日期 const currentGregorian = jalaali.toGregorian(currentPersian.jy, currentPersian.jm, currentPersian.jd); // currentGregorian 结构:{ gy: 2024, gm: 8, gd: 3 } // 3. 生成当天0点的时间戳 const eventStartTime = new Date(currentGregorian.gy, currentGregorian.gm - 1, currentGregorian.gd).setHours(0, 0, 0, 0); // 4. 处理API返回的日期(如果API返回波斯历字符串,也可以用jalaali解析) const eventEndTime = new Date(arr).setHours(0, 0, 0, 0); // 5. 计算时长 const duration = eventStartTime - eventEndTime; console.log("时长(毫秒):", duration); console.log("天数差:", Math.round(Math.abs(duration) / (1000 * 60 * 60 * 24))); });
如果API返回的本身就是波斯历字符串(比如"1403/05/10"),可以直接解析后转公历:
// 解析API返回的波斯历日期 const [jy, jm, jd] = arr.split('/').map(Number); const endGregorian = jalaali.toGregorian(jy, jm, jd); const eventEndTime = new Date(endGregorian.gy, endGregorian.gm - 1, endGregorian.gd).setHours(0, 0, 0, 0);
内容的提问来源于stack exchange,提问作者hanie
相关产品推荐
相关产品推荐

