Преобразование пользовательской строки длительности в длительность момента для сравнения

#typescript #momentjs #primeng #duration

#typescript #momentjs #primeng #Продолжительность

Вопрос:

Для пользовательской функции сортировки в таблице мне нужна функция, которая может сравнивать две строки длительности. Они в пользовательском формате.

Вот функция, которую я использую для преобразования миллисекунд в строку. seconds Логическое значение есть, поэтому я могу игнорировать секундную часть, если это необходимо.

 export function convertMillisecondsToHours(
  milliseconds: number,
  seconds: boolean
): string {
  if (seconds)
    return `${moment
      .duration(milliseconds)
      .format('d [d] hh [h] mm [min] ss [s]')}`;
  else
    return `${moment.duration(milliseconds).format('d [d] hh [h] mm [min]')}`;
}
  

Результирующие строки выглядят так, например: 1 d 21 h 59 mins .

Теперь, в моей таблице (PrimeNG, но это не так важно) Мне нужна пользовательская функция сортировки, которая способна сортировать этот тип длительности от кратчайшего до самого длинного. Моя идея состоит в том, чтобы преобразовать ее в moment.js дата или продолжительность и разница / вычитание. Вот что я получил (что не удается в части преобразования):

  customSort(event: SortEvent) {
    console.log(`Sorting`)
    event.data.sort((data1, data2) => {
      let value1: string = data1[event.field];
      let value2: string = data2[event.field];

      // Convert to moment date/duration, compare (subtract/diff) and return value.
      const date1 = moment.duration(value1)
      const date2 = moment.duration(value2)
      return (event.order * date2.subtract(date1).asMilliseconds());
    });
  }
  

Преобразованные даты недействительны прямо сейчас. Как я могу преобразовать свою пользовательскую строку длительности обратно в дату или временную метку unix, которую я могу использовать в функции сравнения?

Ответ №1:

В конце концов, я написал свою собственную функцию.

 /**
 * Converts a duration string from the table to milliseconds.
 * @param durationString The duration string in format d [d] hh [h] mm [min] ss [s] or d [d] hh [h] mm [min]
 */
export function customDurationStringToMilliseconds(durationString: string): number {
  let duration = 0;

  // Add days.
  if (durationString.includes('d')) {
    duration  =
      parseInt(durationString.substr(0, durationString.indexOf('d')), 10) *
      86400;
    durationString = durationString.replace(
      durationString.substring(0, durationString.indexOf('d')   1),
      ''
    );
  }

  // Add hours.
  if (durationString.includes('h')) {
    duration  =
      parseInt(durationString.substr(0, durationString.indexOf('h')), 10) *
      3600;
    durationString = durationString.replace(
      durationString.substring(0, durationString.indexOf('h')   1),
      ''
    );
  }

  // Add minutes.
  if (durationString.includes('min') || durationString.includes('mins')) {
    duration  =
      parseInt(durationString.substr(0, durationString.indexOf('min')), 10) *
      60;
    if (durationString.includes('mins'))
      durationString = durationString.replace(
        durationString.substring(0, durationString.indexOf('mins')   4),
        ''
      );
    else
      durationString = durationString.replace(
        durationString.substring(0, durationString.indexOf('min')   3),
        ''
      );
  }

  // Add seconds.
  if (durationString.includes('s')) {
    duration  = parseInt(
      durationString.substr(0, durationString.indexOf('s')),
      10
    );
  }
  return duration;
}
  

Возможно, не самое элегантное решение, но оно работает. Сортировка:

 export function customSort(event: SortEvent) {
    event.data.sort((data1, data2) => {
          const value1: string = data1[event.field];
          const value2: string = data2[event.field];
          return (
            event.order *
            (customDurationStringToMilliseconds(value1) -
            customDurationStringToMilliseconds(value2))
        );
    });
}