Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
计算两个日期之间的小数月数(C#)_C#_.net - Fatal编程技术网

计算两个日期之间的小数月数(C#)

计算两个日期之间的小数月数(C#),c#,.net,C#,.net,我希望两天之间(如2013年1月2日至2014年2月15日)的日历月数(可能是小数)应为12.5个月左右 我很惊讶地发现,谷歌上没有回答这个问题 编辑:我最后写了一些代码——如果有人需要我的答案(我今天的好业力:) // ///两个日期之间的总日历月数。如果月份的日期不同, ///使用每月平均天数给出分数近似值。 /// 公共静态双月间隔(日期时间开始,日期时间结束) { //日期切换时处理-计算相同,但有一个负结果: 双乘数; 如果(完成2*12个月 //2) 2011年1月15日至2012

我希望两天之间(如2013年1月2日至2014年2月15日)的日历月数(可能是小数)应为12.5个月左右

我很惊讶地发现,谷歌上没有回答这个问题

编辑:我最后写了一些代码——如果有人需要我的答案(我今天的好业力:)

//
///两个日期之间的总日历月数。如果月份的日期不同,
///使用每月平均天数给出分数近似值。
/// 
公共静态双月间隔(日期时间开始,日期时间结束)
{
//日期切换时处理-计算相同,但有一个负结果:
双乘数;
如果(完成<开始)
{
var-temp=启动;
开始=结束;
完成=温度;
乘数=-1;
}
其他的
{
乘数=1;
}
//1) 2012年3月20日至2014年1月13日-->2*12个月
//2) 2011年1月15日至2012年7月30日-->1*12个月
//3) 2010年1月20日-2010年1月25日-->0*12个月
双倍总月数=(完成年-开始年)*12;
//1) 2012年3月20日至2014年1月13日-->2*12+1-3=22个月
//2) 2011年1月15日至2012年7月30日-->1*12+7-1=18个月
//3) 2010年1月20日-2010年1月25日-->0*12+0个月=0个月
totalMonths+=完成月份-开始月份;
///现在我们有了“月1日到月1日”的差异。天数只能近似,
///因为每个月都有不同的天数(http://en.wikipedia.org/wiki/Month#Julian_and_Gregorian_calendars):
const double averageDaysInMonth=30.436875;
///删除开始月份(非实际期间)中包含的天数:
totalMonths-=开始日/每月的平均日;
///添加完成月份的天数(尚未包括在内,因为有“1到1”):
totalMonths+=完成日/每月的平均日;
//1) 2012年3月20日至2014年1月13日-->2*12+1-3-20/30+13/30=22-7/30=21.76个月
//2) 2011年1月15日至2012年7月30日-->1*12+7-1-15/30+30/30=18+15/30=18.5个月
//3) 2010年1月20日-2010年1月25日-->0*12+0-20/30+25/30=0+5/30=0.17个月
返回总月数*乘数;
}
同样地,我意识到,就在几年前,我需要类似的东西。这也是代码,以防对某人有所帮助:

/// <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;
}
//
///两个日期之间的总日历年数。给出分数
///月/日不同时的近似值。
/// 
公共静态两年(日期时间开始,日期时间结束)
{
//日期切换时处理-计算相同,但有一个负结果:
双乘数;
如果(完成<开始)
{
var-temp=启动;
开始=结束;
完成=温度;
乘数=-1;
}
其他的
{
乘数=1;
}
//1) 2012年3月20日至2014年1月13日-->两年
//2) 2011年1月15日至2012年7月30日-->一年
//3) 2010年1月20日至2010年1月25日-->0年
double totalYears=完成。年份-开始。年份;
///现在我们有了“1月1日到1月1日”的差异。天/月只能是近似值,
///因为每年都有不同的天数(http://en.wikipedia.org/wiki/Year):
const double average daysperyear=365.2425;
///删除我们在起始年(非实际期间)中包含的天数:
totalYears-=start.DayOfYear/averageDaysPerYear;
///添加完成年份中的天数(由于“1月1日至1月1日”,尚未包括在内):
totalYears+=finish.DayOfYear/averageDaysPerYear;
//1) 2012年3月20日至2014年1月13日-->2-~(2*30+20)/365+13/365=1.82年
//2) 2011年1月15日至2012年7月30日-->1-15/365+~(6*30+30)/365=1.53年
//3) 2010年1月20日-2010年1月25日-->0-20/365+25/365=0.01年
返回总年数*乘数;
}

可能是使用假设的最佳选择

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

使用以下内容:

TimeSpan timeSpan = laterDate.Subtract(earlierDate);
var monthsCount = timeSpan.TotalDays / MonthDaysCount;

如果你真的想要分数月,那么一种方法是用天数除以(近似)一个月的平均天数

e、 g

其结果为-13.4373716632444。这可以四舍五入到您需要的精度,例如13.5(我认为您问题中的12.5应该是13.5)

这里的近似值是一个月的平均天数365.25/12。这应该适用于所有日期范围,但非常大的日期范围除外

编辑

但是,需要注意的是,这都是一个近似值-日历月是一个不一致的度量(天数不同),因此一个月的一半不一定等于另一个月的一半


考虑到这一点,a)每个日历月收费并制定一项政策,如果服务提供时间为15天或以上,则对给定的一个月收费,或b)按日收费,都会容易得多。如果你真的想降到“半月”的水平,那么你需要决定一个标准的“半月”已经过去了,例如15天,但在决定下一个“半月”应该在什么时候收费时,这会变得复杂。

如果你愿意使用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;

如果你按月收费,而不仅仅是做数学地板,并且不收取额外的几天的费用。你的客户会很惊喜,甚至会回来(或者至少告诉其他潜在客户)


而且,你已经花在解决这个问题上的时间可能比你将要花掉的钱要少……

什么是“每月0.5次”的定义?有多少天?0.5对我来说已经足够了。在非整数的情况下,我只需要一个合理且一致的分数。收取分数月份的概念必须出自喜欢处理永无止境的账单纠纷的人的头脑。也许是律师?好吧。用测试替换这些评论…在我的情况下,我需要一个精确的1.0000的答案,例如1 Febr
(new DateTime(2013, 1, 2) - new DateTime(2014, 2, 15)).TotalDays / (365.25 / 12)
DateTime date1 = new DateTime(2013, 1, 2);
DateTime date2 = new DateTime(2014, 2, 15);

TimeSpan difference = date2.Subtract(date1);

double elapsedMonths = difference.TotalDays / 30;