C# 计算两个日期之间的月差
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1525990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
calculating the difference in months between two dates
提问by Dinah
In C#/.NET TimeSpan
has TotalDays
, TotalMinutes
, etc. but I can't figure out a formula for total months difference. Variable days per month and leap years keep throwing me off. How can I get TotalMonths?
在 C#/.NET 中TimeSpan
有TotalDays
,TotalMinutes
等,但我无法找出总月数差异的公式。每月的可变天数和闰年让我感到厌烦。我怎样才能得到TotalMonths?
EditSorry for not being more clear: I know I can't actually get this from TimeSpan
but I thought using TotalDays
and TotalMinutes
would be a good example to express what I was looking for ... except I'm trying to get Total Months.
编辑抱歉没有说得更清楚:我知道我实际上无法从中得到这个,TimeSpan
但我认为使用TotalDays
并且TotalMinutes
将是一个很好的例子来表达我正在寻找的东西......除了我试图获得总月数。
Example: Dec 25, 2009 - Oct 6, 2009 = 2 TotalMonths. Oct 6th to Nov 5th equals 0 months. On Nov 6th, 1 month. On Dec 6th, 2 months
示例:2009 年 12 月 25 日 - 2009 年 10 月 6 日 = 2 个总月数。10 月 6 日到 11 月 5 日等于 0 个月。11 月 6 日,1 个月。12 月 6 日,两个月
采纳答案by Adam Robinson
You won't be able to get that from a TimeSpan
, because a "month" is a variable unit of measure. You'll have to calculate it yourself, and you'll have to figure out how exactly you want it to work.
您将无法从 a 获得它TimeSpan
,因为“月”是可变的度量单位。您必须自己计算它,并且必须弄清楚您希望它如何工作。
For example, should dates like July 5, 2009
and August 4, 2009
yield one month or zero months difference? If you say it should yield one, then what about July 31, 2009
and August 1, 2009
? Is thata month? Is it simply the difference of the Month
values for the dates, or is it more related to an actual span of time? The logic for determining all of these rules is non-trivial, so you'll have to determine your own and implement the appropriate algorithm.
例如,日期应该July 5, 2009
和August 4, 2009
产生一个月还是零个月的差异?如果你说它应该产生一个,那么July 31, 2009
andAugust 1, 2009
呢?是那一个月?它仅仅是Month
日期值的差异,还是与实际时间跨度更相关?确定所有这些规则的逻辑非常重要,因此您必须确定自己的规则并实施适当的算法。
If all you want is simply a difference in the months--completely disregarding the date values--then you can use this:
如果你想要的只是月份的差异——完全不考虑日期值——那么你可以使用这个:
public static int MonthDifference(this DateTime lValue, DateTime rValue)
{
return (lValue.Month - rValue.Month) + 12 * (lValue.Year - rValue.Year);
}
Note that this returns a relative difference, meaning that if rValue
is greater than lValue
, then the return value will be negative. If you want an absolute difference, you can use this:
请注意,这将返回一个相对差异,这意味着如果rValue
大于lValue
,则返回值将为负。如果你想要一个绝对的区别,你可以使用这个:
public static int MonthDifference(this DateTime lValue, DateTime rValue)
{
return Math.Abs((lValue.Month - rValue.Month) + 12 * (lValue.Year - rValue.Year));
}
回答by Henk Holterman
You will have to define what you mean by TotalMonths to start with.
A simple definition puts a month at 30.4 days (365.25 / 12).
您必须首先定义 TotalMonths 的含义。
一个简单的定义是一个月有 30.4 天 (365.25 / 12)。
Beyond that, any definition including fractions seems useless, and the more common integer value (whole months between dates) also depends on non-standard business rules.
除此之外,包括分数在内的任何定义似乎都没用,更常见的整数值(日期之间的整月)也取决于非标准业务规则。
回答by Rik
If you want the exact number, you can't from just the Timespan, since you need to know which months you're dealing, and whether you're dealing with a leap year, like you said.
如果你想要确切的数字,你不能只从时间跨度,因为你需要知道你正在处理的月份,以及你是否正在处理闰年,就像你说的。
Either go for an approximate number, or do some fidgetting with the original DateTimes
要么找一个大概的数字,要么用原来的 DateTimes 做一些烦躁的事情
回答by Maximilian Mayerl
I would do it like this:
我会这样做:
static int TotelMonthDifference(this DateTime dtThis, DateTime dtOther)
{
int intReturn = 0;
dtThis = dtThis.Date.AddDays(-(dtThis.Day-1));
dtOther = dtOther.Date.AddDays(-(dtOther.Day-1));
while (dtOther.Date > dtThis.Date)
{
intReturn++;
dtThis = dtThis.AddMonths(1);
}
return intReturn;
}
回答by JDunkerley
You need to work it out yourself off the datetimes. How you deal with the stub days at the end will depend on what you want to use it for.
你需要自己解决日期时间。您最终如何处理存根天数将取决于您想将其用于什么目的。
One method would be to count month and then correct for days at the end. Something like:
一种方法是计算月份,然后在最后修正天数。就像是:
DateTime start = new DateTime(2003, 12, 25);
DateTime end = new DateTime(2009, 10, 6);
int compMonth = (end.Month + end.Year * 12) - (start.Month + start.Year * 12);
double daysInEndMonth = (end - end.AddMonths(1)).Days;
double months = compMonth + (start.Day - end.Day) / daysInEndMonth;
回答by Jesse O'Brien
http://www.astro.uu.nl/~strous/AA/en/reken/juliaansedag.html
http://www.astro.uu.nl/~strous/AA/en/reken/juliaansedag.html
If you can get the time converted from a Gregorian Date into Julian day number, you can just create an operator to do comparisons of the zulian day number, which can be type double to get months, days, seconds, etc. Check out the above link for an algorithm for converting from Gregorian to Julian.
如果您可以将时间从公历日期转换为儒略日数,则可以创建一个运算符来比较zulian 日数,可以键入 double 以获取月、日、秒等。查看上面的内容从格里高利转换为儒略的算法链接。
回答by Rubens Farias
Maybe you don't want to know about month fractions; What about this code?
也许你不想知道月份的分数;这段代码怎么样?
public static class DateTimeExtensions
{
public static int TotalMonths(this DateTime start, DateTime end)
{
return (start.Year * 12 + start.Month) - (end.Year * 12 + end.Month);
}
}
// Console.WriteLine(
// DateTime.Now.TotalMonths(
// DateTime.Now.AddMonths(-1))); // prints "1"
回答by Marc Gravell
The problem with months is that it isn't really a simple measure - they aren't constant size. You would need to define your rules for what you want to include, and work from there. For example 1 Jan to 1 Feb - you could argue 2 months are involved there, or you could say that is one month. Then what about "1 Jan 20:00" to "1 Feb 00:00" - that isn't quite an entire full month. Is that 0? 1? what about the other way around (1 Jan 00:00 to 1 Feb 20:00)... 1? 2?
月份的问题在于它并不是一个简单的度量——它们不是恒定的大小。您需要为要包含的内容定义规则,然后从那里开始工作。例如 1 月 1 日至 2 月 1 日 - 您可以说那里涉及 2 个月,或者您可以说那是 1 个月。那么“1 月 1 日 20:00”到“2 月 1 日 00:00”呢?这还不是一整个月。那是0吗?1?反过来呢(1 月 1 日 00:00 至 2 月 1 日 20:00)... 1?2?
First define the rules, then you'll have to code it yourself, I'm afraid...
先定义规则,然后你就得自己编码了,恐怕……
回答by Snowbear
If you want to have a result 1
between 28th Feb
and 1st March
:
如果您想1
在28th Feb
和之间获得结果1st March
:
DateTime date1, date2;
int monthSpan = (date2.Year - date1.Year) * 12 + date2.Month - date1.Month
回答by Matt
There is no built in way to do this accurately in idiomatic-c#. There are some workarounds, such as this CodeProject examplethat people have coded though.
在惯用 C# 中没有内置的方法可以准确地做到这一点。有一些解决方法,例如人们编写的这个 CodeProject 示例。