Отметьте отметку времени до ближайшей даты
Мне нужно сгруппировать кучу элементов в моем веб-приложении по дате.
Каждый элемент имеет точную метку времени, например. 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())