【问题标题】:Sorting is not correct when using parse date-fns使用 parse date-fns 时排序不正确
【发布时间】:2022-11-15 05:14:51
【问题描述】:

我有 4 个具有以下数据的日期,但是当我对它们进行排序时,数据出现错误。

日期:


2h, 2m, 13s
5d, 3h, 49m, 42s
2h, 0m, 13s
12h, 32m, 13s

我正在尝试使用此公式使用 Date-fns parse 将它们转换为日期

     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

【问题讨论】:

  • 什么是“解析”
  • 日期 Fns.parse 函数
  • 为什么你期望你已经指出的输出?它们按最早日期到最新日期排序(您的实际输出顺序不正确)。看起来您的意思是按持续时间的长度而不是按日期排序。
  • 是的,我想按持续时间而不是按日期对它们进行排序。
  • 然后您需要将它们全部转换为等效单位(秒?)并进行比较

标签: javascript jquery parsing date-fns


【解决方案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);

或者,您可以执行以下操作,从您的字符串值创建一个duration object,然后使用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>

【讨论】:

    猜你喜欢
    • 2021-06-22
    • 2020-12-18
    • 2021-11-08
    • 2021-12-12
    • 2021-03-05
    • 2021-09-27
    • 2021-03-18
    • 2021-05-07
    • 2020-05-08
    相关资源
    最近更新 更多