我正在编写一个设备租赁应用程序,根据租赁期限(以天为单位),客户需要支付租用设备的费用.所以,基本上,(每日费用*天数)=总费用.
对于客户端的即时反馈,我正在尝试使用Javascript来计算两个日历日期的差异.我一直在四处寻找,但我发现的并不是我想要的.我见过的大多数解决方案都是以下形式:
function dateDiff1(startDate, endDate) {
return ((endDate.getTime() - startDate.getTime()) / 1000*60*60*24);
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,设备可以在这两个日期的任何时间检查并退回,无需额外费用.以上代码计算两个日期之间24小时的时间段,当时我真的对日历天数感兴趣.
例如,如果有人在7月6日早上6点检查了设备并在7月7日晚上10点将其退回,则上述代码将计算超过一个24小时的时间段,并且将返回2.所需的结果为1,因为仅已经过了一个日历日期(即第6到第7日).
我发现的最接近的解决方案是这个功能:
function dateDiff2(startDate, endDate) {
return endDate.getDate() - startDate.getDate();
}
Run Code Online (Sandbox Code Playgroud)
只要这两个日期在同一个月内,这就完全符合我的要求.但是,由于getDate()仅返回月中的日期(即1-31),因此当日期跨越多个月时(例如,7月31日至8月1日为1天,但上述计算为1 - 31,或者-29).
在后端,在PHP中,我正在使用gregoriantojd(),这似乎工作得很好(参见这篇文章的一个例子).我只是在Javascript中找不到等效的解决方案.
有人有主意吗?
Ed *_*oor 47
如果您想要整整一天的学生相机租赁示例......
function daysBetween(first, second) {
// Copy date parts of the timestamps, discarding the time parts.
var one = new Date(first.getFullYear(), first.getMonth(), first.getDate());
var two = new Date(second.getFullYear(), second.getMonth(), second.getDate());
// Do the math.
var millisecondsPerDay = 1000 * 60 * 60 * 24;
var millisBetween = two.getTime() - one.getTime();
var days = millisBetween / millisecondsPerDay;
// Round down.
return Math.floor(days);
}
Run Code Online (Sandbox Code Playgroud)
小智 19
我刚刚遇到这个问题并在找到这个问题后解决了,所以我回来发布了这个问题.无论时间如何,这都将获得总天数.DST不会弄乱它:
date1 = Date.UTC(date1.getFullYear(), date1.getMonth(), date1.getDate());
date2 = Date.UTC(date2.getFullYear(), date2.getMonth(), date2.getDate());
var ms = Math.abs(date1-date2);
return Math.floor(ms/1000/60/60/24); //floor should be unnecessary, but just in case
Run Code Online (Sandbox Code Playgroud)
诀窍是转换为甚至不知道原始日期时间的UTC日期.
mga*_*911 10
我要做的是将两个日期的时间设置为同一时间.例如,将endDate的时间设置为凌晨12:00,将startDate的时间设置为凌晨12:00.然后得到它们之间的区别.
另一方面,由于我也在租赁设备软件行业,看起来你不计算小时数就会损失租金收入.根据你的例子,如果有人在7月6日早上6点拿起设备,并在7月7日晚上10点归还.他们有两整天的时间来使用这些设备,并且可能还会产生多余的电表费用......
小智 10
给定的解决方案中存在错误!
这适用于忽略时间的日期差异,并且您需要整数结果,即整数天.
在上面的许多例子中,我们看到Math.floor其他实例我也见过Math.ceil的其他地方.这样做是为了将结果四舍五入为整数天.问题是夏令时会在秋天使用Math.ceil给出错误的结果 - 你的结果将是一天太大或者在春天如果你使用Math.floor你会在一天之内关闭太少.只需使用Math.round,因为1小时任何一种方式都不会使结果产生偏差.
function dateDiff(dateEarlier, dateLater) {
var one_day=1000*60*60*24
return ( Math.round((dateLater.getTime()-dateEarlier.getTime())/one_day) );
}
Run Code Online (Sandbox Code Playgroud)
我还建议看看令人难以置信的moment.js库.它具有多种diff功能,您可以使用它来解决上述示例,如下所示:
function is_same_date(startDate, endDate) {
var startMoment = moment(startDate).clone().startOf('day'),
endMoment = moment(endDate).clone().startOf('day');
return startMoment.diff(endMoment, 'days') == 0;
}
Run Code Online (Sandbox Code Playgroud)
以下是使用moment.jsdiff的一些示例:
> d1 = new Date(2012,04,04,0,0)
Fri May 04 2012 00:00:00 GMT-0400 (EDT)
> d2 = new Date(2012,04,03,23,0)
Thu May 03 2012 23:00:00 GMT-0400 (EDT)
> d3 = new Date(2012,04,05,23,0)
Sat May 05 2012 23:00:00 GMT-0400 (EDT)
> moment(d2).diff(d1, 'days')
0
> moment(d1).diff(d2, 'days')
0
> moment(d1).diff(d3, 'days') // uh oh. this is why we use `startOf`
-2
> moment(d2).diff(d3, 'days')
-2
> moment(d3).startOf('day') // this modified d3, sets the time to 00:00:00.0000
> d3
Sat May 05 2012 00:00:00 GMT-0400 (EDT)
Run Code Online (Sandbox Code Playgroud)
如果时区是一个问题,您还可以使用moment.utc()转换为标准化时区.
由于Julian日实际上是自某个日期以来的天数(在某些情况下也是天数的一小部分),因此它实际上与UNIX时间戳相同,呈现的方式不同.你可以得到自1970年以来的整天数,如下:
Date.prototype.getWholeDays = function () {
return Math.floor(new Date() / 1000*60*60*24);
};
function dateDiff(startDate, endDate) {
return endDate.getWholeDays() - startDate.getWholeDays();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
70222 次 |
| 最近记录: |