问题描述
我在我的项目中使用了“moment.js”(如年龄计算器),但我想用“date-fns”替换它。
使用 moment.js,我将输入值格式化为 DD / MM / YYYY(对于 TR),并通过减去当前日期来计算年龄,但现在我在使用 date-fns 时遇到了麻烦。我觉得 moment.js 变得更容易使用了。
Moment.js 年龄计算器代码:我在 10/03/1998 输入了输入。 (DD/MM/YYYY -> 土耳其)
const birthDay = moment(value,'DD/MM/YYYY');
console.log(birthDay); // (output: 10/03/1998)
const Now = moment();
console.log(Now); // (output: Thu Mar 04 2021 10:40:09 // TR Local Time)
const age = moment.duration(Now.diff(birthDay)).years();
console.log(age); // (output: 22)
我尝试用 date-fns 来做,但没有成功。我无法计算年龄。
const birthDay = format(new Date(value),'dd/MM/yyyy');
console.log(birthDay); // (output: 03/10/1998 - **issue 1**)
const Now = new Date();
console.log(Now); // (output: Thu Mar 04 2021 10:45:18 // TR Local Time)
const age = differenceInCalendarYears(Now,birthDay);
console.log(age); // (output: NaN - - **issue 2**)
如果您能帮助处理 date-fns,我将不胜感激。
我编辑了答案,现在是这样的:
const birthDay = new Date(value);
console.log(birthDay); // Oct 03 1998 (03/10/1998) it's MM/DD,I want DD/MM
const Now = new Date();
console.log(Now); // Mar 04 2021
const age = differenceInCalendarYears(Now,birthDay);
console.log(age); // it should be 22 but 23.
解决方法
我最近遇到了类似的情况,这就是我的实现方式
import { differenceInCalendarYears,parse } from "date-fns"
const calculateAge = (dob: string): number => {
const date = parse(dob,"dd/MM/yyyy",new Date())
const age = differenceInCalendarYears(new Date(),date)
return age
}
calculateAge("11/11/2019") // returns 2
PS:如果您只使用 JS,请考虑删除类型 (:string
& :number
)
您的年龄取决于您当年是否有您的周年纪念日。这就是为什么您应该不使用 differenceInCalendarYears
来计算年龄:它不考虑当前的月份和日期,只考虑年份。
使用 differenceInYears
代替,或者 intervalToDuration
如果您想获得包括月和日在内的年龄。
const { differenceInCalendarYears,differenceInYears,intervalToDuration,parse } = require("date-fns")
function calculateAge(dob) {
const date = parse(dob,new Date());
const age = differenceInYears(new Date(),date);
return age;
}
// INCORRECT
function calculateAge2(dob) {
const date = parse(dob,new Date());
const age = differenceInCalendarYears(new Date(),date);
return age;
}
console.log("dob = 01/04/2000"); // Running on 2021-08-05
console.log('- using differenceInYears: ',calculateAge("01/04/2000")); // 21
console.log('- using differenceInCalendarYears: ',calculateAge2("01/04/2000")); // 21
console.log("dob = 01/10/2000"); // Running on 2021-08-05
console.log('- using differenceInYears: ',calculateAge("01/10/2000")); // 20
console.log('- using differenceInCalendarYears: ',calculateAge2("01/10/2000")); // 21
function calculateFullAge(dob) {
const birthDate = parse(dob,new Date());
const { years,months,days } = intervalToDuration({ start: birthDate,end: new Date()});
return { years,days };
}
// Running on 2021-08-05
console.log('- using intervalToDuration: ',calculateFullAge("01/04/2000")); // {years: 21,months: 4,days: 4}
console.log('- using intervalToDuration: ',calculateFullAge("01/10/2000")); // {years: 20,months: 10,days: 4}
您可以在以下 runkit
中运行它 ,您的问题是使用以下方法解析日期字符串(时间戳):
const birthDay = new Date(value);
强烈建议不要使用内置解析器,参见Why does Date.parse give incorrect results?
由于您使用的是 Date.fns,use it for parsing too:
let dateFns = require("date-fns")
let d = '10/03/1998'; // 10 Mar 1998
let date = dateFns.parse(d,'dd/MM/yyyy',new Date());
let age = dateFns.differenceInCalendarYears(new Date(),date);
console.log(age); // 23 when run on 4 Mar 2021
以上可以在npm.runkit.com运行