JavaScript 中两个日期之间的月份差异
如何计算 JavaScript 中两个 Date() 对象的差异,同时只返回差异的月数?
任何帮助都会很棒:)
How would I work out the difference for two Date() objects in JavaScript, while only return the number of months in the difference?
Any help would be great :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(29)
以月份为单位考虑每个日期,然后减去以找出差异。
这将为您提供两个日期之间的月份差异,忽略天数。
Consider each date in terms of months, then subtract to find the difference.
This will get you the difference of months between the two dates, ignoring the days.
计算两个日期之间的差异,包括月份(天)的一部分。
Calculate the difference between two dates include fraction of month (days).
有两种方法,数学方法和数学方法。很快,但会受到日历中变幻莫测的影响,或者迭代和迭代。缓慢,但可以处理所有奇怪的情况(或者至少将它们委托给经过良好测试的库处理)。
如果您迭代日历,则将开始日期增加一个月并增加一个月。看看我们是否超过了结束日期。这将异常处理委托给内置的 Date() 类,但如果您对大量日期执行此操作,速度可能会很慢。詹姆斯的回答就采用了这种方法。尽管我不喜欢这个想法,但我认为这是“最安全”的方法,如果您只进行一次计算,那么性能差异实际上可以忽略不计。我们倾向于尝试过度优化只执行一次的任务。
现在,如果您要在数据集上计算此函数,您可能不想在每一行上运行该函数(或者上帝保佑,每条记录运行多次)。在这种情况下,您可以使用这里几乎任何其他答案,除了接受的答案,这是错误的(
new Date()
和new Date 之间的差异()
是 -1)?这是我尝试的一种数学快速方法,它解释了不同的月份长度和闰年。如果您要将其应用到数据集(一遍又一遍地进行此计算),您实际上应该只使用这样的函数。如果您只需要执行一次,请使用上面 James 的迭代方法,因为您将处理所有(许多)异常委托给 Date() 对象。
There are two approaches, mathematical & quick, but subject to vagaries in the calendar, or iterative & slow, but handles all the oddities (or at least delegates handling them to a well-tested library).
If you iterate through the calendar, incrementing the start date by one month & seeing if we pass the end date. This delegates anomaly-handling to the built-in Date() classes, but could be slow IF you're doing this for a large number of dates. James' answer takes this approach. As much as I dislike the idea, I think this is the "safest" approach, and if you're only doing one calculation, the performance difference really is negligible. We tend to try to over-optimize tasks which will only be performed once.
Now, if you're calculating this function on a dataset, you probably don't want to run that function on each row (or god forbid, multiple times per record). In that case, you can use almost any of the other answers here except the accepted answer, which is just wrong (difference between
new Date()
andnew Date()
is -1)?Here's my stab at a mathematical-and-quick approach, which accounts for differing month lengths and leap years. You really should only use a function like this if you'll be applying this to a dataset (doing this calculation over & over). If you just need to do it once, use James' iterative approach above, as you're delegating handling all the (many) exceptions to the Date() object.
日期和日期的月数时间并不重要
在这种情况下,我不关心完整月份、部分月份、一个月有多长等。我只需要知道月份数。 一个相关的现实案例是每个月都有一份报告到期,我需要知道应该有多少份报告。
示例:
这是一个详细的代码示例,用于显示数字的去向。
让我们采用 2 个时间戳,应为 4 个月
可能与您提取的时区/时间略有不同。日、分、秒并不重要,可以包含在时间戳中,但我们在实际计算中会忽略它。
步骤 1:将时间戳转换为 JavaScript 日期
步骤 2:获取整数值月/年
这给了我们
第3步:添加
(12 * (endYear - startYear)) + 1 到结束月份。
2 + (12 * (2020 - 2019)) + 1 = 15
步骤 4:减去月份
15 - 11 = 4
;我们得到了 4 个月的结果。29 个月示例 示例
2019 年 11 月至 2022 年 3 月为 29 个月。如果将它们放入 Excel 电子表格中,您将看到 29 行。
3 + (12 * (2022-2019)) + 1
40 - 11 = 29
Number Of Months When Day & Time Doesn't Matter
In this case, I'm not concerned with full months, part months, how long a month is, etc. I just need to know the number of months. A relevant real world case would be where a report is due every month, and I need to know how many reports there should be.
Example:
This is an elaborated code example to show where the numbers are going.
Let's take 2 timestamps that should result in 4 months
May be slightly different with your timezone / time pulled. The day, minutes, and seconds don't matter and can be included in the timestamp, but we will disregard it with our actual calculation.
Step 1: convert the timestamp to a JavaScript date
Step 2: get integer values for the months / years
This gives us
Step 3: Add
(12 * (endYear - startYear)) + 1
to the ending month.2 + (12 * (2020 - 2019)) + 1 = 15
Step 4: Subtract the months
15 - 11 = 4
; we get our 4 month result.29 Month Example Example
November 2019 through March 2022 is 29 months. If you put these into an excel spreadsheet, you will see 29 rows.
3 + (12 * (2022-2019)) + 1
40 - 11 = 29
这里就可以了其他循环较少的方法:
Here you go other approach with less looping:
这应该可以正常工作:
This should work fine:
以下代码还考虑了部分月份的天数,返回两个日期之间的完整月份。
Following code returns full months between two dates by taking nr of days of partial months into account as well.
}
}
以下逻辑将获取几个月的差异
below logic will fetch difference in months
这是我能找到的最简单的解决方案。这将直接返回月份数。虽然,它总是给出绝对值。
对于非绝对值,可以使用以下解决方案:
This is the simplest solution I could find. This will directly return the number of months. Although, it always gives an absolute value.
For non-absolute values, you can use the following solution:
看看我用的是什么:
See what I use:
任何值都会与其绝对值一起返回。
Any value is returned along with its absolute value.
以下代码片段帮助我找到两个日期之间的月份
The following code snippet helped me to find months between two dates
#这是我编写的一段很好的代码,用于获取天数和月数
从给定日期开始
[1]:jsfiddle 链接
#Here is a nice piece of code i wrote for getting number of days and months
from given dates
[1]: jsfiddle link
一种方法是编写一个使用 JODA 库
http 的简单 Java Web 服务 (REST/JSON) ://joda-time.sourceforge.net/faq.html#datediff
计算两个日期之间的差异并从 JavaScript 调用该服务。
这假设您的后端是 Java 语言。
One approach would be to write a simple Java Web Service (REST/JSON) that uses JODA library
http://joda-time.sourceforge.net/faq.html#datediff
to calculate difference between two dates and call that service from javascript.
This assumes your back end is in Java.
“差异月数”的定义有很多解释。 :-)
您可以从 JavaScript 日期对象获取年、月和日。根据您要查找的信息,您可以使用这些信息来计算两个时间点之间相差多少个月。
例如,即兴:
(请注意,JavaScript 中的月份值以 0 = 一月开头。)
在上面包含小数月份要复杂得多,因为典型的二月中的三天占该月的比例 (~10.714%) 比八月的三天要大 ( ~9.677%),当然,甚至二月也是一个移动目标,具体取决于它是否是闰年。
还有一些可用于 JavaScript 的日期和时间库,可能会使此类事情变得更容易。
注意:上面原来有一个
+1
,这里:那是因为我本来是这么说的:
我删除它有两个原因:
事实证明,不计算部分月份并不是很多(大多数?)人想要得到答案的结果,所以我认为我应该将它们分开。
即使按照这个定义,它也并不总是有效。 :-D(抱歉。)
The definition of "the number of months in the difference" is subject to a lot of interpretation. :-)
You can get the year, month, and day of month from a JavaScript date object. Depending on what information you're looking for, you can use those to figure out how many months are between two points in time.
For instance, off-the-cuff:
(Note that month values in JavaScript start with 0 = January.)
Including fractional months in the above is much more complicated, because three days in a typical February is a larger fraction of that month (~10.714%) than three days in August (~9.677%), and of course even February is a moving target depending on whether it's a leap year.
There are also some date and time libraries available for JavaScript that probably make this sort of thing easier.
Note: There used to be a
+ 1
in the above, here:That's because originally I said:
I've removed it for two reasons:
Not counting partial months turns out not to be what many (most?) people coming to the answer want, so I thought I should separate them out.
It didn't always work even by that definition. :-D (Sorry.)
如果您不考虑该月的哪一天,这是迄今为止更简单的解决方案
请注意,月份索引是从 0 开始的。这意味着
一月 = 0
和十二月 = 11
。If you do not consider the day of the month, this is by far the simpler solution
Be aware that month index is 0-based. This means that
January = 0
andDecember = 11
.这是一个准确提供 2 个日期之间的月数的函数。
默认行为仅计算整月,例如 3 个月加 1 天将导致 3 个月的差异。您可以通过将
roundUpFractionalMonths
参数设置为true
来防止这种情况发生,因此 3 个月加 1 天的差异将返回为 4 个月。上面接受的答案(TJ Crowder 的答案)不准确,有时会返回错误的值。
例如,
monthDiff(new Date('Jul 01, 2015'), new Date(' Aug 05, 2015'))
返回0
这显然是错误的。正确的差异是 1 个整月或 2 个月的四舍五入。这是我写的函数:
Here's a function that accurately provides the number of months between 2 dates.
The default behavior only counts whole months, e.g. 3 months and 1 day will result in a difference of 3 months. You can prevent this by setting the
roundUpFractionalMonths
param astrue
, so a 3 month and 1 day difference will be returned as 4 months.The accepted answer above (T.J. Crowder's answer) isn't accurate, it returns wrong values sometimes.
For example,
monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015'))
returns0
which is obviously wrong. The correct difference is either 1 whole month or 2 months rounded-up.Here's the function I wrote:
有时您可能只想获取两个日期之间的月份数量,完全忽略日期部分。例如,如果您有两个日期 - 2013/06/21 和 2013/10/18 - 并且您只关心 2013/06 和 2013/10 部分,则以下是场景和可能的解决方案:
1.如果您想要仅两个日期之间的月份数,不包括 Month1 和 Month2
2.如果您想包括任一月份
3.如果您想包括两个月份
Sometimes you may want to get just the quantity of the months between two dates totally ignoring the day part. So for instance, if you had two dates- 2013/06/21 and 2013/10/18- and you only cared about the 2013/06 and 2013/10 parts, here are the scenarios and possible solutions:
1.If you want just the number of the months between the two dates excluding both month1 and month2
2.If you want to include either of the months
3.If you want to include both of the months
如果您需要计算完整月份,无论月份是 28、29、30 还是 31 天。下面应该可以工作。
这是答案的扩展版本 https://stackoverflow.com/a/4312956/1987208 但修复了以下情况:它计算从1月31日到2月1日(1天)的案例1个月。
这将涵盖以下内容;
If you need to count full months, regardless of the month being 28, 29, 30 or 31 days. Below should work.
This is an extended version of the answer https://stackoverflow.com/a/4312956/1987208 but fixes the case where it calculates 1 month for the case from 31st of January to 1st of February (1day).
This will cover the following;
JavaScript 中两个日期之间的月份差异:
start_date 和 end_date 之间的总月份:
Difference in Months between two dates in JavaScript:
total months between start_date and end_date :
您还可以考虑此解决方案,此
函数
以整数或数字形式返回月份差异将开始日期作为第一个或最后一个
param
,是容错的。这意味着该函数仍将返回相同的值。You could also consider this solution, this
function
returns the month difference in integer or numberPassing the start date as the first or last
param
, is fault tolerant. Meaning, the function would still return the same value.我知道这真的很晚了,但无论如何还是发布它以防对其他人有帮助。这是我想出的一个函数,它似乎可以很好地计算两个日期之间的月份差异。诚然,它比 Mr.Crowder 的更加粗俗,但通过单步执行日期对象提供了更准确的结果。它是在 AS3 中,但您应该能够放弃强类型,并且您将拥有 JS。请随意让外面的人看起来更漂亮!
I know this is really late, but posting it anyway just in case it helps others. Here is a function I came up with that seems to do a good job of counting differences in months between two dates. It is admittedly a great deal raunchier than Mr.Crowder's, but provides more accurate results by stepping through the date object. It is in AS3 but you should just be able to drop the strong typing and you'll have JS. Feel free to make it nicer looking anyone out there!
为了扩展@TJ的答案,如果您正在寻找简单的月份,而不是完整的日历月份,您可以只检查 d2 的日期是否大于或等于 d1 的日期。也就是说,如果 d2 的月份晚于 d1 的月份,则多了 1 个月。所以你应该能够这样做:
这并不能完全解释时间问题(例如 3 月 3 日下午 4:00 和 4 月 3 日下午 3:00),但它更准确,并且只需几行代码。
To expand on @T.J.'s answer, if you're looking for simple months, rather than full calendar months, you could just check if d2's date is greater than or equal to than d1's. That is, if d2 is later in its month than d1 is in its month, then there is 1 more month. So you should be able to just do this:
This doesn't totally account for time issues (e.g. 3 March at 4:00pm and 3 April at 3:00pm), but it's more accurate and for just a couple lines of code.