我想要两天之间(可能是分数)日历月的数量,例如2013年1月2日 - 2014年2月15日应为12.5个月左右。
我很惊讶没有发现谷歌已经回复了这个问题。
编辑:我最后编写了一些代码 - 如果有人需要相同的话,这是我的答案(我当天的好事):/// <summary>
/// Number of total calendar months between two dates. If day of month is different,
/// gives fractional approximation using average days per month.
/// </summary>
public static double MonthsBetween(DateTime start, DateTime finish)
{
//handle if dates switched - calculation same but there's a negative result:
double multiplier;
if(finish < start)
{
var temp = start;
start = finish;
finish = temp;
multiplier = -1;
}
else
{
multiplier = 1;
}
//1) 20 Mar 2012 - 13 Jan 2014 --> 2*12 months
//2) 15 Jan 2011 - 30 Jul 2012 --> 1*12 months
//3) 20 Jan 2010 - 25 Jan 2010 --> 0*12 months
double totalMonths = (finish.Year - start.Year)*12;
//1) 20 Mar 2012 - 13 Jan 2014 --> 2*12 + 1 - 3 = 22 months
//2) 15 Jan 2011 - 30 Jul 2012 --> 1*12 + 7 - 1 = 18 months
//3) 20 Jan 2010 - 25 Jan 2010 --> 0*12 + 0 months = 0 months
totalMonths += finish.Month - start.Month;
///Now we have "1st of the month to 1st of the month" difference. Days can only be approximated,
///since each month has a different number of days. Statistically (http://en.wikipedia.org/wiki/Month#Julian_and_Gregorian_calendars):
const double averageDaysInMonth = 30.436875;
///Remove the days we've included in the starting month (not in actual period):
totalMonths -= start.Day / averageDaysInMonth;
///Add the days in the finish month (weren't yet included, since had "1st to 1st"):
totalMonths += finish.Day / averageDaysInMonth;
//1) 20 Mar 2012 - 13 Jan 2014 --> 2*12 + 1 - 3 - 20/30 + 13/30 = 22 - 7/30 = 21.76 months
//2) 15 Jan 2011 - 30 Jul 2012 --> 1*12 + 7 - 1 - 15/30 + 30/30 = 18 + 15/30 = 18.5 months
//3) 20 Jan 2010 - 25 Jan 2010 --> 0*12 + 0 - 20/30 + 25/30 = 0 + 5/30 = 0.17 months
return totalMonths * multiplier;
}
同样,我在多年后需要类似的东西后才意识到。这也是代码,如果有人帮助的话:
/// <summary>
/// Number of total calendar years between two dates. Gives fractional
/// approximation if months/days differ.
/// </summary>
public static double YearsBetween(DateTime start, DateTime finish)
{
//handle if dates switched - calculation same but there's a negative result:
double multiplier;
if (finish < start)
{
var temp = start;
start = finish;
finish = temp;
multiplier = -1;
}
else
{
multiplier = 1;
}
//1) 20 Mar 2012 - 13 Jan 2014 --> 2 years
//2) 15 Jan 2011 - 30 Jul 2012 --> 1 year
//3) 20 Jan 2010 - 25 Jan 2010 --> 0 years
double totalYears = finish.Year - start.Year;
///Now we have "1st of the year to 1st of the year" difference. Days/months can only be approximated,
///since each year has a different number of days. Statistically (http://en.wikipedia.org/wiki/Year):
const double averageDaysPerYear = 365.2425;
///Remove the days we've included in the starting year (not in actual period):
totalYears -= start.DayOfYear / averageDaysPerYear;
///Add the days in the finish year (weren't yet included, since had "Jan 1 to Jan 1"):
totalYears += finish.DayOfYear / averageDaysPerYear;
//1) 20 Mar 2012 - 13 Jan 2014 --> 2 - ~(2*30+20)/365 + 13/365 = 1.82 years
//2) 15 Jan 2011 - 30 Jul 2012 --> 1 - 15/365 + ~(6*30+30)/365 = 1.53 years
//3) 20 Jan 2010 - 25 Jan 2010 --> 0 - 20/365 + 25/365 = 0.01 years
return totalYears * multiplier;
}
答案 0 :(得分:1)
可能是使用假设的最佳选择;
var startTime = Convert.ToDateTime("02/01/2013");
var endTime = Convert.ToDateTime("15/02/2014");
var span = endTime.Subtract(startTime);
Console.WriteLine("Time Difference (months): " + Math.Round((decimal)span.Days/30,1));
提供13.6
答案 1 :(得分:1)
使用以下内容:
TimeSpan timeSpan = laterDate.Subtract(earlierDate);
var monthsCount = timeSpan.TotalDays / MonthDaysCount;
答案 2 :(得分:0)
如果你真的想要分数月,那么一种方法是花费天数并除以一个月内的(近似)平均天数。
e.g。
(new DateTime(2013, 1, 2) - new DateTime(2014, 2, 15)).TotalDays / (365.25 / 12)
结果为-13.4373716632444。这可以四舍五入到您需要的精度,例如13.5(我相信你问题中的12.5应该是13.5)。
这里的近似值是一个月中的平均天数365.25 / 12.这应该适用于所有但非常大的日期范围。
修改强>
然而,重要的是要注意这是一个近似值 - 日历月是不一致的度量(天数变化),因此一个月的一半不一定等于另一个月的一半。
鉴于此,a)每个日历月收费并制定政策,如果服务提供15天或更长时间,或b)按天收费,您将收取指定月份的费用。如果你真的想要降到'半月'水平,那么你需要决定标准的'半月'何时过去,例如15天,但在决定何时应该收取下一个“半月”的时候会变得复杂。
答案 3 :(得分:0)
如果您愿意使用30天的月份,请尝试以下操作:
DateTime date1 = new DateTime(2013, 1, 2);
DateTime date2 = new DateTime(2014, 2, 15);
TimeSpan difference = date2.Subtract(date1);
double elapsedMonths = difference.TotalDays / 30;
答案 4 :(得分:0)
如果您每月收费而不仅仅是Math.Floor
和不收取这些额外的几天。您的客户会很高兴,甚至可能会回来(或至少告诉其他潜在客户)。
另外,你已经解决这个问题的时间可能少于你将要放弃的金额......