Время округления, разница от конца дня до целых часов в моменты? - PullRequest
0 голосов
/ 28 декабря 2018

РЕДАКТИРОВАТЬ: Это не дубликат округлять вверх / округлять мгновенный момент до ближайшей минуты - потому что сначала я не хочу округлять до ближайшей минуты;во-вторых, я не хочу округлять безоговорочно , но только тогда, когда разница в .endOf('day') не равна целым часам, которые я ожидал бы получить;и в-третьих, я хочу округлить moment.duration, а не moment.

Скажем, у меня есть отметка даты / времени, "2017-02-17 21:00:00", и я хочу найтисколько часов осталось до конца дня.Мысленно, если я вспоминаю о девяти часах вечера, я считаю, что это в 3 часах от полуночи, и это ответ, который я хотел бы получить от моментов.Вот что я делаю (Javascript Web Console в Firefox):

var m1 = moment('2017-02-17 21:00:00');
<- undefined

var m2 = moment(m1).endOf('day');
<- undefined

m1
<- Object { _isAMomentObject: true, _i: "2017-02-17 21:00:00", _f: "YYYY-MM-DD HH:mm:ss", _isUTC: false, _pf: Object, _locale: Object, _a: Array[7], _d: Date 2017-02-17T20:00:00.000Z, _isValid: true, _z: null }

m2
<- Object { _isAMomentObject: true, _i: "2017-02-17 21:00:00", _f: "YYYY-MM-DD HH:mm:ss", _isUTC: false, _pf: Object, _locale: Object, _z: null, _a: Array[7], _d: Date 2017-02-17T22:59:59.999Z, _isValid: true }

var mdiff = moment(m2).diff(moment(m1))
<- undefined

mdiff
<- 10799999

var mddur = moment.duration(moment(m2).diff(moment(m1)))
<- undefined

mddur
<- Object { _isValid: true, _milliseconds: 10799999, _days: 0, _months: 0, _data: Object, _locale: Object }

Пока все хорошо, теперь, чтобы отформатировать продолжительность, я иду согласно Получите разницу во времени между двумя датами (также форматирование продолжительности · Выпуск № 1048 · момент / момент · GitHub );обратите внимание, что я хочу использовать ту же функцию, которую использовал бы, чтобы получить правильные значения длительности, превышающие 24 часа, чтобы рассчитать это - даже если этот конкретный пример имеет продолжительность менее 24 часов, поэтому я использую это:

Math.floor(mddur.asHours()) + moment.utc(mddur.asMilliseconds()).format(":mm:ss")
<- "2:59:59"

Итак, здесь я хочу получить ответ «3:00:00», а не «2:59:59» - хотя обратите внимание, я все еще хотел бы «2:59:58» как есть, и не округлено.

Полагаю, если наша длительность в мс равна 10799999, то есть 10799999/1000 = 10799,999000 секунд, поэтому если у нас есть длительность, у которой остаток в миллисекундах составляет 999 миллисекунд, только тогда я бы хотел округлить.

Каков рекомендуемый способ достижения этого с помощью moment.js?

1 Ответ

0 голосов
/ 28 декабря 2018

Хорошо, я закончил тем, что сделал функцию, которая делает то, что я хочу, вот она:

function padDigits(number, digits) { // SO:10073699
  return Array(Math.max(digits - String(number).length + 1, 0)).join(0) + number;
}

var durationToHoursStr = function(induration) {
  // copy the duration
  thisduration = moment.duration(induration);
  // to get seconds, we divide milliseconds with 1000;
  // check if the remainder of division of milliseconds with 1000 is 999:
  var remainder = thisduration.asMilliseconds() % 1000;
  //console.log("remainder", remainder);
  // only round up if the remainder is 999:
  if (remainder >= 999) {
    // in call moment.duration(Number), Number is interpreted as "length of time in milliseconds" (https://momentjs.com/docs/#/durations/)
    // so just add 1 ms, since anyways the previous remainder is 999, should be enough to flow over
    thisduration.add(moment.duration(1)); // should be in-place replacement - mutable
    //console.log("thisduration", thisduration);
  }
  return String(Math.floor(thisduration.asHours())) + ":" + padDigits(thisduration.minutes(), 2) + ":" + padDigits(thisduration.seconds(), 2);
};

var m1 = moment('2017-02-17 21:00:00');
var m2 = moment(m1).endOf('day');

// mdiff is int, total number of milliseconds, here 10799999
var mdiff = moment(m2).diff(moment(m1))

// mddur is moment.duration, also has the same amount of milliseconds, 
// mddur.asMilliseconds() = 10799999, mddur.asSeconds() = 10799.999, mddur.asHours() = 2.9999997222222223
var mddur = moment.duration(moment(m2).diff(moment(m1)));

var mddur_hoursString = durationToHoursStr(mddur);
console.log(mddur_hoursString); // prints "3:00:00"

var m3 = moment('2017-02-17 23:59:59');
var mddur3 = moment.duration(moment(m3).diff(moment(m1)));
var mddur3_hoursString = durationToHoursStr(mddur3);
console.log(mddur3_hoursString); // prints "2:59:59" - as it should, since we didn't really demand the difference to the end of day
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...