提问人:user3594118 提问时间:11/15/2022 最后编辑:user3594118 更新时间:11/15/2022 访问量:125
使用解析 date-fns 时排序不正确
Sorting is not correct when using parse date-fns
问:
我有 4 个日期,其中包含以下数据,但是当我对它们进行排序时,数据是错误的。
日期:
2h, 2m, 13s
5d, 3h, 49m, 42s
2h, 0m, 13s
12h, 32m, 13s
我正在尝试使用此公式使用 Date-fns 解析将它们转换为日期
convertStringToDate(value) {
if (value.match('M')) {
return dateFns.parse(value, "M'M', dd'd', HH'h', mm'm', ss's'", new Date())
}
else if (value.match('d')) {
return dateFns.parse(value, "dd'd', HH'h', mm'm', ss's'", new Date())
}
else if (value.match('h')) {
return dateFns.parse(value, "HH'h', mm'm', ss's'", new Date())
}
else if (value.match('m')) {
return dateFns.parse(value, "mm'm', ss's'", new Date())
}
else if (value.match('s')) {
return dateFns.parse(value, "ss's'", new Date())
}
}
然后对其进行排序
$.fn.dataTableExt.oSort["customDuration-desc"] = (a, b) => {
a = this.convertStringToDate(a);
b = this.convertStringToDate(b);
return new Date(a) - new Date(b);
};
结果是错误的。 其显示为
5d, 3h, 49m, 42s
2h, 2m, 13s
2h, 0m, 13s
12h, 32m, 13s
而不是
5d, 3h, 49m, 42s
12h, 32m, 13s
2h, 2m, 13s
2h, 0m, 13s
答:
1赞
pilchard
11/15/2022
#1
您可以简单地解析持续时间字符串并将每个单位转换为秒,此处使用按单位缩写索引的对象来保存转换方法。(我已经删除了月份,因为没有标准的月份长度(以秒为单位)
function durationToSeconds(value) {
const unitMap = {
d: (d) => +d * 24 * 60 * 60,
h: (h) => +h * 60 * 60,
m: (m) => +m * 60,
s: (s) => +s,
}
return value
.split(',')
.reduce((a, u) => {
const { v, k } = u.match(/(?<v>\d+)(?<k>\w)/).groups
return a + unitMap[k]?.(v) ?? 0;
}, 0);
}
const input = [
"2h, 2m, 13s",
"5d, 3h, 49m, 42s",
"2h, 0m, 13s",
"12h, 32m, 13s"
];
const result = input.sort((a, b) => {
a = durationToSeconds(a);
b = durationToSeconds(b);
return b - a;
});
console.log(result);
或者,您可以执行如下操作,该操作从字符串值创建一个持续时间对象,然后使用 date-fns.add()
将每个持续时间添加到预先指定的日期(此处保存在闭包中)。注意:在计算中引入日期会带来更多的复杂性,具体取决于您如何处理它们,时区/本地与 UTC/夏令时。
<script type='module'>
import { add } from 'https://esm.run/date-fns';
function addDuration(date) {
const unitMap = {
d: 'days',
h: 'hours',
m: 'minutes',
s: 'seconds',
}
return (value) => {
const duration = Object.assign(
{
years: 0,
months: 0,
weeks: 0,
days: 0,
hours: 0,
minutes: 0,
seconds: 0
},
Object.fromEntries(value.split(',').map(u => {
const { v, k } = u.match(/(?<v>\d+)(?<k>\w)/).groups
return [unitMap[k], v];
}))
);
return add(date, duration)
}
}
const addDurationToDate = addDuration(new Date());
const result = [
"2h, 2m, 13s",
"5d, 3h, 49m, 42s",
"2h, 0m, 13s",
"12h, 32m, 13s"
].sort((a, b) => {
a = addDurationToDate(a);
b = addDurationToDate(b);
return b - a;
});
console.log(result);
</script>
评论