date-fns 的 isSameOrBefore 实现

Ash*_*rwa 8 javascript momentjs date-fns

由于 moment 已被弃用,我决定隐藏整个项目中的 moment 并考虑使用 datefns 作为替代品。当我浏览代码文件时,我遇到了一行内容:

moment(date1).isSameOrBefore(date2, year);
Run Code Online (Sandbox Code Playgroud)

我开始寻找与该函数正在执行的操作类似的东西,但不幸的是,date-fns 没有任何东西可以执行基于精度的比较(即:年、月或日期比较)?谁能建议一些 date-fns 的解决方法?

Fra*_*ion 7

你可以使用differenceInYears

const date1 = new Date(2021, 6, 20);;
const date2 = new Date(2021, 7, 2);

function isSameOrBefore(date1, date2) {
  return dateFns.differenceInYears(date1, date2) <= 0;
}

console.log(isSameOrBefore(date1, date2));

console.log(isSameOrBefore(date1, new Date('2022-06-20')));

console.log(isSameOrBefore(date1, new Date('2019-06-20')));
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.28.5/date_fns.min.js"></script>
Run Code Online (Sandbox Code Playgroud)


Ter*_*nox 1

只要您针对相关的矩函数进行测试,您就应该能够创建直接替换。

我们可以查找相关的startOfXXX过程来比较unit指定的日期,如果缺少也会抛出错误:

function isSameOrBefore(date1, date2, unit = '') {
    if (unit) {
        const procName = `startOf${unit[0].toUpperCase()}${unit.slice(1)}`;
        if (!dateFns[procName]) { 
            throw new Error(`isSameOrBefore: Unsupported unit: ${unit}`);
        }
        date1 = dateFns[procName](date1);
        date2 = dateFns[procName](date2);
    }
    return dateFns.isBefore(date1, date2) || dateFns.isEqual(date1, date2);
}

// Test against various inputs
const dts = ['2010-10-20 01:00', '2010-10-20 00:00', '2010-10-20 00:59:00', '2010-10-01', '2010-09-01', '2009-09-01'];
let units = ['year', 'month', 'day', 'hour', 'minute'];
let dt1 = '2010-10-20 01:00'
let allTests = [];
for(let dt2 of dts) {
    for(let unit of units) {
        // Ensure we get the same answer as moment().isSameOrBefore
        const testPassed = isSameOrBefore(dt1, dt2, unit) === moment(dt1).isSameOrBefore(dt2, unit)
        allTests.push(testPassed);
        console.log(`isSameOrBefore(${dt1}, ${dt2}, ${unit}):`, isSameOrBefore(dt1, dt2, unit));
        console.log(`isSameOrBefore(${dt1}, ${dt2}, ${unit}): Test passed:`, testPassed ? "TRUE": "FALSE")
    }
}
console.log("All tests passed:", allTests.every(res => res) ? "TRUE": "FALSE")
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js" integrity="sha512-qTXRIMyZIFb8iQcfjXWCO8+M5Tbc38Qi5WzdPOYZHIlZpzBHG3L3by84BBBOiRGiEb7KKtAOAs5qYdUiZiQNNQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.30.1/date_fns.min.js" integrity="sha512-F+u8eWHrfY8Xw9BLzZ8rG/0wIvs0y+JyRJrXjp3VjtFPylAEEGwKbua5Ip/oiVhaTDaDs4eU2Xtsxjs/9ag2bQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
Run Code Online (Sandbox Code Playgroud)