关于c#:计算年,月,周和日

Calculate Years, Months, weeks and Days

在我的应用程序中,用户输入两个日期。计划开始日期和计划结束日期。我们必须获取这些日期,并根据差异填充4个字段。

所以,假设他选择2010年1月1日作为开始,2011年3月2日作为结束,我们需要以:

年份:1月份:2周:0第1天

这意味着总持续时间是1年、2个月和1天。

有没有一个标准的方法来做到这一点?或者我需要写一个有很多非常复杂逻辑的方法来解决这个问题?我希望我能走运,会有一个日期差异类型的.NET类可用。


这里有一个完整的方法,不包括星期,但可以相对简单地添加。这是一个有点复杂的问题(在stackoverflow上以多种方式提问,并以多种方式回答得很差),但回答的也不尽相同。TimeSpan对象为我们提供了所需的部分内容,但只在几天内有效。我已经针对这个方法编写了大量的测试,如果你发现了一个漏洞,请发表评论。

这将要做的是比较两个日期,分别是年、月、日、小时和分钟。(例如,1年、6个月、3天、4小时和7分钟前发生了一些事件)

因为这个问题已经被问过很多次,并且试图回答过很多次,我不确定这是否会被注意到,但是如果是这样的话,它应该提供价值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    public static void TimeSpanToDateParts(DateTime d1, DateTime d2, out int years, out int months, out int days, out int hours, out int minutes)
    {
        if (d1 < d2)
        {
            var d3 = d2;
            d2 = d1;
            d1 = d3;
        }

        var span = d1 - d2;

        months = 12 * (d1.Year - d2.Year) + (d1.Month - d2.Month);

        //month may need to be decremented because the above calculates the ceiling of the months, not the floor.
        //to do so we increase d2 by the same number of months and compare.
        //(500ms fudge factor because datetimes are not precise enough to compare exactly)
        if (d1.CompareTo(d2.AddMonths(months).AddMilliseconds(-500)) <= 0)
        {
            --months;
        }

        years = months / 12;
        months -= years * 12;

        if (months == 0 && years == 0)
        {
            days = span.Days;
        }
        else
        {
            var md1 = new DateTime(d1.Year, d1.Month, d1.Day);
            // Fixed to use d2.Day instead of d1.Day
            var md2 = new DateTime(d2.Year, d2.Month, d2.Day);
            var mDays = (int) (md1 - md2).TotalDays;

            if (mDays > span.Days)
            {
                mDays = (int)(md1.AddMonths(-1) - md2).TotalDays;
            }

            days = span.Days - mDays;


        }
        hours = span.Hours;
        minutes = span.Minutes;
    }

您可以使用此免费库的datediff类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// ----------------------------------------------------------------------
public void DateDiffSample()
{
  DateTime date1 = new DateTime( 2009, 11, 8, 7, 13, 59 );
  Console.WriteLine("Date1: {0}", date1 );
  // > Date1: 08.11.2009 07:13:59
  DateTime date2 = new DateTime( 2011, 3, 20, 19, 55, 28 );
  Console.WriteLine("Date2: {0}", date2 );
  // > Date2: 20.03.2011 19:55:28

  DateDiff dateDiff = new DateDiff( date1, date2 );

  // differences
  Console.WriteLine("DateDiff.Years: {0}", dateDiff.Years );
  // > DateDiff.Years: 1
  Console.WriteLine("DateDiff.Quarters: {0}", dateDiff.Quarters );
  // > DateDiff.Quarters: 5
  Console.WriteLine("DateDiff.Months: {0}", dateDiff.Months );
  // > DateDiff.Months: 16
  Console.WriteLine("DateDiff.Weeks: {0}", dateDiff.Weeks );
  // > DateDiff.Weeks: 70
  Console.WriteLine("DateDiff.Days: {0}", dateDiff.Days );
  // > DateDiff.Days: 497
  Console.WriteLine("DateDiff.Weekdays: {0}", dateDiff.Weekdays );
  // > DateDiff.Weekdays: 71
  Console.WriteLine("DateDiff.Hours: {0}", dateDiff.Hours );
  // > DateDiff.Hours: 11940
  Console.WriteLine("DateDiff.Minutes: {0}", dateDiff.Minutes );
  // > DateDiff.Minutes: 716441
  Console.WriteLine("DateDiff.Seconds: {0}", dateDiff.Seconds );
  // > DateDiff.Seconds: 42986489

  // elapsed
  Console.WriteLine("DateDiff.ElapsedYears: {0}", dateDiff.ElapsedYears );
  // > DateDiff.ElapsedYears: 1
  Console.WriteLine("DateDiff.ElapsedMonths: {0}", dateDiff.ElapsedMonths );
  // > DateDiff.ElapsedMonths: 4
  Console.WriteLine("DateDiff.ElapsedDays: {0}", dateDiff.ElapsedDays );
  // > DateDiff.ElapsedDays: 12
  Console.WriteLine("DateDiff.ElapsedHours: {0}", dateDiff.ElapsedHours );
  // > DateDiff.ElapsedHours: 12
  Console.WriteLine("DateDiff.ElapsedMinutes: {0}", dateDiff.ElapsedMinutes );
  // > DateDiff.ElapsedMinutes: 41
  Console.WriteLine("DateDiff.ElapsedSeconds: {0}", dateDiff.ElapsedSeconds );
  // > DateDiff.ElapsedSeconds: 29
} // DateDiffSample


我认为时间跨度是你想要的,但它不适用于年或月,因为它们的长度不同。

下面的例子来自上面的链接;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Define two dates.
DateTime date1 = new DateTime(2010, 1, 1, 8, 0, 15);
DateTime date2 = new DateTime(2010, 8, 18, 13, 30, 30);
// Calculate the interval between the two dates.
TimeSpan interval = date2 - date1;
Console.WriteLine("{0} - {1} = {2}", date2, date1, interval.ToString());
// Display individual properties of the resulting TimeSpan object.
Console.WriteLine("   {0,-35} {1,20}","Value of Days Component:", interval.Days);
Console.WriteLine("   {0,-35} {1,20}","Total Number of Days:", interval.TotalDays);
Console.WriteLine("   {0,-35} {1,20}","Value of Hours Component:", interval.Hours);
Console.WriteLine("   {0,-35} {1,20}","Total Number of Hours:", interval.TotalHours);
Console.WriteLine("   {0,-35} {1,20}","Value of Minutes Component:", interval.Minutes);
Console.WriteLine("   {0,-35} {1,20}","Total Number of Minutes:", interval.TotalMinutes);
Console.WriteLine("   {0,-35} {1,20:N0}","Value of Seconds Component:", interval.Seconds);
Console.WriteLine("   {0,-35} {1,20:N0}","Total Number of Seconds:", interval.TotalSeconds);
Console.WriteLine("   {0,-35} {1,20:N0}","Value of Milliseconds Component:", interval.Milliseconds);
Console.WriteLine("   {0,-35} {1,20:N0}","Total Number of Milliseconds:", interval.TotalMilliseconds);
Console.WriteLine("   {0,-35} {1,20:N0}","Ticks:", interval.Ticks);
// the example displays the following output:
//       8/18/2010 1:30:30 PM - 1/1/2010 8:00:15 AM = 229.05:30:15
//          Value of Days Component:                             229
//          Total Number of Days:                   229.229340277778
//          Value of Hours Component:                              5
//          Total Number of Hours:                  5501.50416666667
//          Value of Minutes Component:                           30
//          Total Number of Minutes:                       330090.25
//          Value of Seconds Component:                           15
//          Total Number of Seconds:                      19,805,415
//          Value of Milliseconds Component:                       0
//          Total Number of Milliseconds:             19,805,415,000
//          Ticks:                               198,054,150,000,000


我也需要这个,但在我的情况下,没有周部分(所以只有年,月和天)。鉴于此,我做的是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
DateTime startDate = DateTime.ParseExact (start,"dd/MM/yyyy",CultureInfo.InvariantCulture);
DateTime endDate = DateTime.ParseExact (end,"dd/MM/yyyy",CultureInfo.InvariantCulture);
int days=0;
int months = 0;
int years = 0;
//calculate days
if (endDate.Day >= startDate.Day) {
    days = endDate.Day - startDate.Day;
} else {
    var tempDate = endDate.AddMonths (-1);
    int daysInMonth = DateTime.DaysInMonth (tempDate.Year, tempDate.Month);
    days = daysInMonth - (startDate.Day - endDate.Day);
    months--;
}
//calculate months
if (endDate.Month >= startDate.Month) {
    months+=endDate.Month - startDate.Month;
} else {
    months+= 12 - (startDate.Month - endDate.Month);
    years--;
}
//calculate years
years+=endDate.Year - startDate.Year;
Debug.WriteLine (string.Format("{0} years, {1} months, {2} days",years,months,days));

如果要更动态地显示此代码,还可以使用以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//build the string
var result ="";
if (years!=0){
    result = years == 1 ? years +" year" : years +" years";
}
if (months != 0) {
    if (result !="") {
        result +=",";
    }
    result += months == 1 ? months +" month" : months +" months";
}
if (days != 0) {
    if (result !="") {
        result +=",";
    }
    result += days == 1 ? days +" day" : days +" days";
}
Debug.WriteLine (result);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
 public partial class Age1 : System.Web.UI.Page
    {
        private int Years;
        private int Months;
        private int Days;
        DateTime Cday;
        DateTime Bday;


        protected void Page_Load(object sender, EventArgs e)
        {
            txtCurrentDate.Enabled = false;
            txtCurrentDate.Text = DateTime.Now.ToString("g");
            Cday = Convert.ToDateTime(txtCurrentDate.Text);
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            Bday = Convert.ToDateTime(txtBirthdate.Text);
            AgeCaluclation(Bday, Cday);
            txtBirthdate.Text ="";
            txtCurrentDate.Text ="";
            lblAge.Text = this.Years+"  Years"+this.Months+"  Months" +this.Days+"Days";
        }

        private Age1 AgeCaluclation(DateTime Bday, DateTime Cday)
        {

            if ((Cday.Year - Bday.Year) > 0 ||
               (((Cday.Year - Bday.Year) == 0) &&
               ((Bday.Month < Cday.Month) ||
               ((Bday.Month == Cday.Month) &&
               (Bday.Day <= Cday.Day)))))
            {

                int DaysInBdayMonth = DateTime.DaysInMonth(Bday.Year, Bday.Month);
                int DaysRemain = Cday.Day + (DaysInBdayMonth - Bday.Day);

                    if(Cday.Month > Bday.Month)
                    {
                        this.Years = Cday.Year - Bday.Year;
                        this.Months = Cday.Month - (Bday.Month + 1) + Math.Abs(DaysRemain / DaysInBdayMonth);
                        this.Days = (DaysRemain % DaysInBdayMonth + DaysInBdayMonth) % DaysInBdayMonth;
                    }
                    else if (Cday.Month == Bday.Month)
                    {
                        if (Cday.Day >= Bday.Day)
                        {
                            this.Years = Cday.Year - Bday.Year;
                            this.Months = 0;
                            this.Days = Cday.Day - Bday.Day;
                        }
                        else
                        {
                            this.Years = (Cday.Year - 1) - Bday.Year;
                            this.Months = 11;
                            this.Days = DateTime.DaysInMonth(Bday.Year, Bday.Month) - (Bday.Day - Cday.Day);

                        }
                    }
                    else
                    {
                        this.Years = (Cday.Year - 1) - Bday.Year;
                        this.Months = Cday.Month + (11 - Bday.Month) + Math.Abs(DaysRemain / DaysInBdayMonth);
                        this.Days = (DaysRemain % DaysInBdayMonth + DaysInBdayMonth) % DaysInBdayMonth;
                    }
            }
            else
            {
                throw new ArgumentException("Birthday date must be earlier than current date");
            }
            return this;
        }

    }

AgeCaluclationUsingC# and Asp.net Amazing


研究c时间跨度结构。它不需要几个月或几年,但需要几天。这使事情变得更容易。


我创建这一个是为了返回两个日期之间的年、月和日的差异。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public static Dictionary<string, int> TimeSpanToDateParts(DateTime fromDate,DateTime toDate)
        {
            int years;
            int months;
            int days;
            Dictionary<string, int> dateParts = new Dictionary<string, int>();
            if (toDate < fromDate)
            {
               return TimeSpanToDateParts(toDate,fromDate);
            }

            var span = toDate - fromDate;

            months = 12 * (toDate.Year - fromDate.Year) + (toDate.Month - fromDate.Month);

            if (toDate.CompareTo(fromDate.AddMonths(months).AddMilliseconds(-500)) <= 0)
            {
                --months;
            }

            years = months / 12;
            months -= years * 12;

            if (months == 0 && years == 0)
            {
                days = span.Days;
            }
            else
            {
                days = toDate.Day;
                if (fromDate.Day > toDate.Day)
                    days = days + (DateTime.DaysInMonth(toDate.Year, toDate.Month - 1) - fromDate.Day);
                else
                    days = days - fromDate.Day;
            }
            dateParts.Add("Years", years);
            dateParts.Add("Months", months);
            dateParts.Add("Days", days);

            return dateParts;
        }