Отметьте отметку времени до ближайшей даты

Мне нужно сгруппировать кучу элементов в моем веб-приложении по дате.

Каждый элемент имеет точную метку времени, например. 1417628530199. Я использую Moment.js и его время от времени ", чтобы преобразовать эти необработанные метки времени в удобные для чтения даты, например 2 Days Ago. Затем я хочу использовать читаемую дату в качестве заголовка для группы элементов, созданных в ту же дату.

Проблема заключается в том, что исходные временные метки слишком специфичны - у двух элементов, созданных в одну и ту же дату, но каждая минута каждая, будет иметь уникальную временную метку. Поэтому я получаю заголовок для 2 Days Ago с первым элементом под ним, затем другим заголовком для 2 Days Ago со вторым под ним и т.д.

Каков наилучший способ округления необработанных временных меток до ближайшей даты, чтобы все элементы, созданные в одну и ту же дату, имели одну и ту же метку времени и, следовательно, могли быть сгруппированы вместе?

Ответ 1

Попробуйте следующее:

Date.prototype.formatDate = function() {
   var yyyy = this.getFullYear().toString();
   var mm = (this.getMonth()+1).toString();
   var dd  = this.getDate().toString();
   return yyyy + (mm[1]?mm:"0"+mm[0]) + (dd[1]?dd:"0"+dd[0]);
  };

var utcSeconds = 1417903843000,
    d = new Date(0);

d.setUTCSeconds(Math.round( utcSeconds / 1000.0));

var myTime = (function(){
        var theTime = moment(d.formatDate(), 'YYYYMMDD').startOf('day').fromNow();
        if(theTime.match('hours ago')){
            return 'Today';
        }
        return theTime;
    })();

alert( myTime );

http://jsfiddle.net/cdn5rvck/4/

Ответ 2

Ну, используя js, вы можете сделать:

var d = new Date(1417628530199);
d.setHours(0);
d.setMinutes(0);
d.setSeconds(0);
d.setMilliseconds(0);

Edit:

После проверки нескольких методов, этот, кажется, быстрее:

function roundDate(timeStamp){
    timeStamp -= timeStamp % (24 * 60 * 60 * 1000);//subtract amount of time since midnight
    timeStamp += new Date().getTimezoneOffset() * 60 * 1000;//add on the timezone offset
    return new Date(timeStamp);
}

Вы можете проверить разницу в скорости здесь: http://jsfiddle.net/juvian/3aqmhn2h/

Ответ 3

Используя Moment.js, вы можете использовать следующий код для округления всех до начала дня:

moment().startOf('day').toString();
// -> Prints out "Fri Dec 05 2014 00:00:00 GMT-0800"

Подробнее о startOf() можно узнать в docs.

Ответ 4

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

var offset = new Date(Date.now() +43200000);
var rounded = new Date(offset .getFullYear(),offset .getMonth(),offset .getDate());
console.log(new Date());
console.log(rounded);

Ответ 5

function roundDownDate(date) {
  if (typeof date !== "object" || !date.getUTCMilliseconds) {
      throw Error("Arg must be a Date object.");
  }
  var offsetMs = date.getTimezoneOffset() * 60 * 1000,
      oneDayMs = 24 * 60 * 60 * 1000;
  return new Date(Math.floor((date.getTime() - offsetMs) / oneDayMs) * oneDayMs + offsetMs);
};

Это должно работать и довольно быстро.

Ответ 6

function getDateOfTimeStamp(time) {
  var originTime = 0;
  var offsetOriginTime = originTime + new Date().getTimezoneOffset() * 60 * 1000;
  var timeSinceOrigin = time - offsetOriginTime;
  var timeModulo = timeSinceOrigin % (24 * 60 * 60 * 1000);
  var normalizedTime = time - timeModulo;

  console.log(new Date(normalizedTime) ,new Date(time));
  return normalizedTime;
}

Это сработало для моего проекта. Чистая математика, никаких манипуляций с строкой не требуется, никакой внешней библиотеки не требуется, поэтому она очень быстро.

Вы можете попробовать, скопировав указанную выше функцию в javascript-консоль, а затем выполните normalizeTimeToDate(Date.now())