关于javascript:计算从今天开始的天数

Calculate how many days passed from today's date

这是我的问题:

我正在尝试计算从今天的日期过去多少天并将其显示在标签中。问题是当用户改变时间时,我得到的结果是分数。

请协助

这是我在JS中的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 //=============================================== //
   // How many days passed from the current day     //
   // ============================================ //

   function BanDateChanged(sender, args) {
       var banDate = $find("<%= rdtpBan.ClientID %>");
       var TodayDate = new Date();
       var today = new Date();
       var todayFormat = new Date(today.getMonth() + 1 +"/" + today.getDate() +"/" + today.getFullYear());
       var banSelectedDate = banDate.get_selectedDate();
       var countedBannedDays = document.getElementById("<%= lblBanCountDays.ClientID %>");
       var one_day = 1000 * 60 * 60 * 24;
       var countedDays = (Math.ceil(todayFormat - banSelectedDate) / one_day);
       if (countedDays == 0) {
           countedBannedDays.innerHTML ="";
       } else {
           countedBannedDays.innerHTML = countedDays +" Days ago";
       }
   }


由于时间信息不匹配,您可以获得小数结果,因此您所寻找的是"整天",以获得良好的圆形结果。你可以通过几种方式做到这一点。一种是您可以使用setHours()等功能清除使用日期中的时间信息。第二种方法是从banSelectedDate创建一个新的Date对象,但不使用它的时间信息,如下所示:

1
var cDate = new Date(banSelectedDate.getFullYear(), banSelectedDate.getMonth(), banSelectedDate.getDate());

然后使用cDate进行计算。


Javascript日期实际上只是一个时间值,自1970-01-01T00:00:00Z以来是毫秒。要获得两个日期之间的毫秒数,只需从另一个中减去一个:

1
2
3
4
var date0 = new Date(2015, 0, 1); // 1 Jan 2015
var date1 = new Date(2015, 1, 1); // 1 Feb 2015

var numberOfDays = Math.ceil((date1 - date0) / 8.64e7); // 31

不要使用Date构造函数来解析字符串。如果您知道这些值,请直接传递它们(记住几个月是零索引)。

要了解自月初开始已经过了多少天,只需使用日期编号:

1
2
var now = new Date();
var daysSinceStartOfMonth = now.getDate() - 1;

所以在1号它将返回0,在2号它将返回1,依此类推。如果你想按照自己的方式去做(有效但工作量远远超过它需要),那么:

1
2
3
4
5
6
7
8
9
10
11
// Create a date object for the current instant
var now = new Date();

// Make an exact copy
var startOfMonth = new Date(+now);

// Set the copy's date to the start of the month
startOfMonth.setDate(1);

// Get the difference in time value and calculate whole days
var daysSinceStartOfMonth = Math.ceil((now - startOfMonth) / 8.64e7); // 17 on 18 June

Math.ceil的唯一需求是日期跨越夏令时边界。希望有所帮助。


一般情况

传统上通过一次又一次地重新发明相同的解决方案来解决这个和许多类似的任务,在开发期间导致问题,就像你在这里遇到的那样,并为未来留下可维护性的噩梦。

幸运的是,有一个小型库可用于这样的情况:Moment.js。

数天

要显示自给定日期以来已过去的天数:

1
var days = moment().diff("2015-06-02","days");

它为您处理舍入,它处理夏令时的边界,它处理时区,它为您处理日期格式解析等。 - 实际上没有必要重新发明轮子并多次编写相同的代码。
见:DEMO。

但它比那更好:

更智能的输出

您可以使用此代替:

1
var ago = moment.duration(moment().diff("2015-06-05")).humanize() +" ago";

并且您将自动获得如下值:

  • "15 days ago"
  • "13 hours ago"
  • "5 years ago"

准备放入countedBannedDays.innerHTML,为用户提供更多信息。见:DEMO。

你的榜样

在您的示例中,只要banSelectedDate的值包含有效日期,那么您的代码 - 删除DOM处理代码,因为它将保持不变:

1
2
3
4
5
6
7
    var banDate = $find("<%= rdtpBan.ClientID %>");
    var TodayDate = new Date();
    var today = new Date();
    var todayFormat = new Date(today.getMonth() + 1 +"/" + today.getDate() +"/" + today.getFullYear());
    var banSelectedDate = banDate.get_selectedDate();
    var one_day = 1000 * 60 * 60 * 24;
    var countedDays = (Math.ceil(todayFormat - banSelectedDate) / one_day);

可以简化为:

1
2
3
    var banDate = $find("<%= rdtpBan.ClientID %>");
    var banSelectedDate = banDate.get_selectedDate();
    var countedDays = moment().diff(banSelectedDate,"days");

与相关的日计数逻辑只是:

var countedDays = moment().diff(banSelectedDate,"days");

显而易见的是,您不必处理奇怪的边缘情况,避免暴露内部数据表示导致泄漏抽象,并且实际上没有太多空间可以犯任何错误。

其他选择

还有其他图书馆:

  • XDate
  • DateJS

在这个答案中查看更多信息。

有了可用于处理此类常见任务的良好库,我们不必编写具有许多潜在问题的复杂代码,例如您在此处遇到的问题。代码重用不仅可以避免潜在的问题,还可以使您自己的代码更易于维护。