我基本上想要两个日期,即:
var startDate = new Date("01/01/2001 01:00:00");
var currentDate = new Date();
然后我希望通过从startDate
中减去currentDate
来获得持续时间,并以以下形式显示: a b year(s)c day(s)d hour(s) )e秒(s)。
到目前为止,我的问题是如果你采用捷径,即:
var duration = currentDate.getTime() - startDate.getTime();
var seconds = duration / 1000;
var minutes = duration / 1000 / 60;
等...
然后你会得到一个错误的持续时间,因为,例如,几个月并不总是30天,年份并不总是365天(闰年),等等。更不用说当我这样做的时候它大概是关闭的一年。
我已经浏览了网络并通过StackOverflow上的各种帖子,但我找不到一个JavaScript方法的工作示例,它准确地从另一个日期中减去一个日期并允许您获取详细信息(年,月,日,从结果日期开始的小时,分钟,秒。
有一个网站已经可以完全按照我的意愿执行此操作:http://www.timeanddate.com
答案 0 :(得分:2)
如果你想要一个“正确”的结果,因为几个月有不同的天数,没有明显的简单解决方案。
但与此同时,人类大脑在大日期范围内变得越来越邋..所以“1年11个月”几乎与“近两年”一样好。因此,在开始使用100%正确的解决方案之前,请先假设自己假装结果是否足够好,并且只需使用30天。
如果真的不是一个选择:摆脱小时和分钟;他们只会让人困惑。创建两个从午夜开始的日期(即HH:MM:SS是00:00:00)。
现在的问题是他们之间有多少天,几个月和几年?那要看。 6月1日和8月31日之间的时间差不多是两个月,但两个日期之间没有一个月。它是61 days, 0 months
。还是1 month, 30 days
?哪个是“正确的”?
数学正确的解决方案将为您提供长达61天的差异结果,用户会感到恼火。
人类解决方案在数学上并不正确,因此您最终必须编写假想人类时间感的启发式算法。
这就是为什么如此多的网站说“超过一个月”,如果某些日期相差超过30天并继续“半年”,“一年”(330至380天之间的任何事情)和“更多”他们使用邋human的人类大脑而不是试图提出一个“确切”的结果(a)也没有真正有用,并且b)没有人真正同意“确切”是什么应该是的意思)。
答案 1 :(得分:1)
我几天来一直在努力解决这个问题。最后做了一些我觉得有用的东西它现在看起来像垃圾,邋comments的评论和愚蠢的var名称,而Ill明天会做清理。但我想如果你需要它我会发布它。
编辑:我清理了代码并对其进行了精简。请在此处查看:https://gist.github.com/4705863
EDIT2:该死的,发现了一个错误。我在上面。 修正了错误,现在运行正常!
// Time difference function
function timeDiff(start, end) {
//today, now!
//Get the diff
var diff = end - start;
//Create numbers for dividing to get hour, minute and second diff
var units = [
1000 * 60 * 60 *24,
1000 * 60 * 60,
1000 * 60,
1000
];
var rv = []; // h, m, s array
//loop through d, h, m, s. we are not gonna use days, its just there to subtract it from the time
for (var i = 0; i < units.length; ++i) {
rv.push(Math.floor(diff / units[i]));
diff = diff % units[i];
}
//Get the year of this year
var thisFullYear = end.getFullYear();
//Check how many days there where in last month
var daysInLastMonth = new Date(thisFullYear, end.getMonth(), 0).getDate();
//Get this month
var thisMonth = end.getMonth();
//Subtract to get differense between years
thisFullYear = thisFullYear - start.getFullYear();
//Subtract to get differense between months
thisMonth = thisMonth - start.getMonth();
//If month is less than 0 it means that we are some moths before the start date in the year.
// So we subtract one year, and add the negative number (month) to 12. (12 + -1 = 11)
subAddDays = daysInLastMonth - start.getDate();
thisDay = end.getDate();
thisMonth = thisMonth - 1;
if(thisMonth < 0){
thisFullYear = thisFullYear - 1;
thisMonth = 12 + thisMonth;
//Get ends day of the month
}
//Subtract the start date from the number of days in the last month, add add the result to todays day of the month
subAddDays = daysInLastMonth - start.getDate();
subAddDays = thisDay + subAddDays;
if(subAddDays >= daysInLastMonth){
subAddDays = subAddDays - daysInLastMonth;
thisMonth++;
if (thisMonth > 11){
thisFullYear++;
thisMonth = 0;
}
}
return {
years: thisFullYear,
months: thisMonth,
days: subAddDays,
hours: rv[1],
minutes: rv[2],
seconds: rv[3]
};
}
//The start date/From date. Here i add one hour to offset it.
//var start = new Date(1814, 3, 20, 1);
//The end date. today, now!
//var end = new Date();
//Get the difference
//var d = timeDiff(start, end);
// Log that bitch
//console.log('years: '+ d.years + '. months: '+ d.months + '. days: ' + d.days + '. hours:' +d.hours+ '. minutes:' + d.minutes + '. seconds: ' + d.seconds);
答案 2 :(得分:0)
http://www.w3schools.com/jsref/jsref_obj_date.asp
myDate.UTC() // get the number of milliseconds since the Unix epoch
所以
delta_ms = laterDate.UTC() - earlierDate.UTC();
delta_days = Math.round(delta_ms / (1000 * 60 * 60 * 24));
如果你想要几个月和几年,你需要指定你是否想要日历差异(例如5月1日到6月1日是1个月,但是2月28日到3月30日是......?),或者是“标准”年份比如365天和30天等等。
即使看起来应该如此,这也不是直截了当的。例如,在金融领域,至少有5种方法可以计算两个日期之间的差距,使用标准月份与否,以及是否使用标准日期。在某个日期之后生成日期很容易(2月1日之后的1个日历月是3月1日),但后退不是,因为映射不是1:1。
另外,请注意,这是一个绝对值,不需要调整闰年,闰秒,夏令时,时区和所有其他时间格式的短暂时间。
答案 3 :(得分:0)
您也可以考虑这些案例。
考虑2个日期2nd Mar 2008
和5th Jun 2013
。
Mar
2008 ________###########################
2009 ###################################
2010 ###################################
2011 ###################################
2012 #################################### (leap)
2013 ###############--------------------
Jun
您可以减去两者之间的年份(即2009年,2010年,2011年,2012年)。现在2012年是闰年,但无关紧要,因为它将计入年而不是月。
Years = 4
现在,你还剩下这个
2
Mar 08 ____################################
Apr 08 ####################################
May 08 #####################################
Jun 08 ####################################
Jul 08 #####################################
Aug 08 #####################################
Sep 08 ####################################
Oct 08 #####################################
Nov 08 ####################################
Dec 08 #####################################
Jan 12 #####################################
Feb 12 ###################################
Mar 12 #####################################
Apr 12 ####################################
May 12 #####################################
Jun 12 #########----------------------------
5
算上整整几个月。它们包含多少天并不重要。它们被计入月而非天。
Months = 14
2
Mar 08 ____################################
Jun 12 #########----------------------------
5
现在计算Mar2008和Jun2012的剩余天数(不包括结束日期)。这里的计数是29(3月)+ 4(6月)= 33。
Days = 33
但33天似乎很奇怪,因为它可以转换为1个月+几天。如果发生这种情况,问题出现在哪个月可以选择 - 3月(31天),6月(30天)或仅减少30天以增加一个月。我认为在考虑巨大差异时,这几乎不重要。如果我们考虑三月,那么差异将是
4 Years 15 Months 2 Days
或只是5 Years 3 Months 2 Days
同样的方法可以持续一段时间。
<强> EDITED 强>
Let `date1` be greater than `date2`
Let max(month) gives the total days in the month
years = date1.year - date2.year - 1;
months = date1.month - date2.month - 1;
days = (max(date2.month) - date1.day) + (date2.day - 1);
if(days >= 30) //Here you can take totals days in date1 or date2
{
month++;
days-=30;
}
while(month >= 12) //Here month can reach a value of 24 because it can be incremented above too
{
years++;
month-=12;
}
print("Difference is " + years + " years " + month + " months " + days + " days");
答案 4 :(得分:0)
将来为自己留下答案
只需使用时刻及其持续时间插件
并使用
moment.duration(moment('then').diff(moment('now'))).format('d [Days] hh:mm:ss')
它有效
答案 5 :(得分:-1)
var years = currentDate.getYear() - startDate.getYear();
var months = currentDate.getMonth() - startDate.getMonth();
...