【问题标题】:Round a timestamp to the nearest date将时间戳四舍五入到最近的日期
【发布时间】:2015-02-04 02:09:02
【问题描述】:

我需要按创建日期对我的网络应用中的一堆项目进行分组。

每个项目都有一个确切的时间戳,例如1417628530199。我正在使用Moment.js 及其“time from now”功能将这些原始时间戳转换为可读的日期,例如2 Days Ago。然后,我想将可读日期用作在同一日期创建的一组项目的标题。

问题在于原始时间戳过于具体 - 在同一日期创建但相隔一分钟的两个项目将各自具有唯一的时间戳。所以我得到了2 Days Ago 的标题,下面是第一项,然后是2 Days Ago 的另一个标题,下面是第二项,等等。

将原始时间戳四舍五入到最接近的日期的最佳方法是什么,这样在同一日期创建的任何项目都将具有完全相同的时间戳,从而可以组合在一起?

【问题讨论】:

标签: javascript date datetime momentjs


【解决方案1】:

嗯,使用js你可以做到:

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

更短的写法是d.setHours(0, 0, 0, 0);

【讨论】:

  • 我认为您更快的方法是不正确的,因为您使用当前时刻的时区偏移量,而不是适用于给定时间戳的时区偏移量。您应该将第二个调整更改为timestamp.getTimezoneOffset()
  • @MichaelPetito 时间戳是一个整数,所以猜你的意思是 new Date(timestamp).getTimezoneOffset() ?尽管如此,timezoneOffset 将与new Date() 相同
  • 时区偏移量可以变化,getTimezoneOffset 获取日期实例的偏移量。例如,我在美国东部时区,new Date().getTimezoneOffset() 对于今天的日期是 300,但由于夏令时的变化,new Date("6/1/2016")240。如果时间戳表示的日期与当前日期的时区偏移量不同,您的代码可能会产生意外结果。例如。 roundDate(new Date("6/1/2016").getTime()) 导致日期 Wed Jun 01 2016 01:00:00 GMT-0400 (Eastern Daylight Time) - 不是午夜 - 今天对我来说。
  • @MichaelPetito 我明白了,没有考虑到这一点。随意编辑答案
  • 感谢这两种方法,第二种可能性能更好,但第一种似乎更易读易懂。
【解决方案2】:

使用 Moment.js,您可以使用以下代码将所有内容四舍五入到一天的开始:

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

您可以在docs 中阅读有关startOf() 的更多信息。

【讨论】:

  • @Ken Fyrstenberg - 感谢您的编辑!出于某种原因,我正在考虑使用 Ruby 模式。我希望我可以对编辑进行投票以给你一些代表:-)
  • 别担心! +1 很好的解决方案:)
【解决方案3】:

这是一种在一行中只获取日期而没有依赖关系的简洁方法:

let d = new Date().setHours(0, 0, 0, 0);

【讨论】:

  • 除了 d 将是一个时间值(来自 ECMAScript 纪元的毫秒),而不是一个 Date 对象。要获得日期,您需要new Date(new Date().setHours(0, 0, 0, 0))。 ;-)
【解决方案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);

由于这似乎占用的空间很小,因此扩展原型以将其包含在 Date“类”中也很有用。

Date.prototype.round = function(){
    var dateObj = new Date(+this+43200000);
    return new Date(dateObj.getFullYear(), dateObj.getMonth(), dateObj.getDate());
};
console.log(new Date().round());

最小化:

Date.prototype.round = function(){var d = new Date(+this+43200000);return new Date(d.getFullYear(), d.getMonth(), d.getDate());};

【讨论】:

  • 这只是修剪日期,而不是四舍五入。
  • @koryakinp - 感谢您提醒我这一点。它在四舍五入的日期之前缺少 +.5,但我从未在这里更新它。干杯!
【解决方案5】:

试试这个:

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/

【讨论】:

  • 这非常接近我正在寻找的...有什么方法可以让fromNow()使用天数作为单位?例如,如果现在是下午 3:00,我创建了一个项目,即使我刚刚创建了它,Moment 也会将日期显示为 15 hours ago(因为它基于从上午 12:00 开始的距离)。我只想说Today
  • @daGuy 我已经更新了代码。这能回答你的问题吗?
【解决方案6】:
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);
};

这应该可以工作并且速度非常快。

【讨论】:

    【解决方案7】:
    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())

    【讨论】:

      猜你喜欢
      • 2012-03-29
      • 1970-01-01
      • 2022-01-02
      • 2021-12-11
      • 1970-01-01
      • 2021-12-15
      • 1970-01-01
      • 2021-12-16
      • 1970-01-01
      相关资源
      最近更新 更多