簡體   English   中英

DateTime 差異返回正確的月數甚至數年?

[英]DateTime difference returing correct no of months and or even years?

是否有任何內置的 function 如何以比天數更好的方式獲得 DateTime 對象之間的差異? 我的意思是1個月23天。 由於每個月的天數不同,閏年等,我發現很難計算。謝謝

看看野田時間 一般來說,它還沒有准備好生產,但相關位可能足以滿足您當前的要求:)

請注意, TimeSpan不會做您想做的事情,因為“1 個月”可能意味着不同的天數,具體取決於月份,並且TimeSpan沒有錨定。

在 Noda Time 中,您需要一個Period 例如:

LocalDate start = new LocalDate(2010, 4, 15);
LocalDate end = new LocalDate(2010, 6, 19);
Period period = Period.Between(start, end); // Defaults to Year/Month/Day

Console.WriteLine(period.Months); // 2
Console.WriteLine(period.Days); // 4

請注意, 日期/時間算術很難......在某些情況下,“正確答案”並不明顯。

簡單的減法就可以了:

int months = departure.Months - arrival.Months;
int years = departure.Years - arrival.Years;
//in case multiple years have elapsed .
int months += years * 12;

顯然,當涉及到天數時,您需要做一些數學運算,如果您不關心精度,如果日差為負數,您將需要從月中減去一個。


然后你可以使用TimeSpan來獲得更精確的時間。

//Microsoft Documentation Example:

DateTime departure = new DateTime(2010, 6, 12, 18, 32, 0);
DateTime arrival = new DateTime(2010, 6, 13, 22, 47, 0);
TimeSpan travelTime = arrival - departure;  
Console.WriteLine("{0} - {1} = {2}", arrival, departure, travelTime);   

// The example displays the following output:
//       6/13/2010 10:47:00 PM - 6/12/2010 6:32:00 PM = 1.04:15:00

月份可以由 28、29、30 或 31 天組成; 年可以是 365 或 366 天。 因此,當您嘗試計算月份和年份的完整時間單位時會出現問題,因此,如果您可以假設某些事情,那么您可以檢查一下

這種問題出奇地難以為日歷日期指定。 看看這里,了解如何計算一個人的年齡(以年為單位)。

在 C# 中計算年齡

復雜性來自邊緣情況。 顯然,1 月 31 日是 12 月 31 日之后的一個月。 但是,2 月 28 日是 1 月 31 日之后的一個月嗎? 在一個正常的年份? 在閏年? 在編寫代碼之前,您需要指定這些情況。

生日算法使用向下舍入和遞增策略。 考慮到您對上一段中問題的回答,這也適用於月份差異。

這是我剛剛編寫的一些代碼,用於計算年、月和日的差異。 它屬於公共領域。

    public sealed class DateDifference {
            int years;

            public int Years {
                get { return years; }
            }
            int months;

            public int Months {
                get { return months; }
            }
            int days;

            public int Days {
                get { return days; }
            }

            public override string ToString()
            {
                return string.Format("[DateDifference Years={0}, Months={1}, Days={2}]", years, months, days);
            }


            public DateDifference(DateTime earlier, DateTime later){
                if(later<earlier)
                    throw new ArgumentException("later is earlier than 'earlier'.");
                bool isleapday=(earlier.Month==2 && earlier.Day==29);
                DateTime tmp=isleapday ? new DateTime(earlier.Year,2,28) : earlier;
                while(true){
                    try {
                        tmp=tmp.AddYears(1);
                        if(isleapday && DateTime.IsLeapYear(tmp.Year))
                            tmp=new DateTime(tmp.Year,2,29);
                    } catch(ArgumentOutOfRangeException){
                        break;
                    }
                    if(tmp<=later){
                        years++;
                        earlier=tmp;
                    } else {
                        break;
                    }
                }
                // Add months
                tmp=earlier;
                while(true){
                    try {
                        tmp=tmp.AddMonths(1);
                    if(isleapday && tmp.Day!=29 && tmp.Month!=2)
                        tmp=new DateTime(tmp.Year,tmp.Month,29);
                    } catch(ArgumentOutOfRangeException){
                        break;
                    }
                    if(tmp<=later){
                        months++;
                        earlier=tmp;
                    } else {
                        break;
                    }
                }
                tmp=earlier;
                while(true){
                    try {
                        tmp=tmp.AddDays(1);
                    } catch(ArgumentOutOfRangeException){
                        break;
                    }
                    if(tmp<=later){
                        days++;
                        earlier=tmp;
                    } else {
                        break;
                    }
                }
            }
        }

例子:

var dd=new DateDifference(new DateTime(2010,6,29),new DateTime(2012,2,29));
Console.WriteLine(dd.Years); // displays 1
Console.WriteLine(dd.Months); // displays 8
Console.WriteLine(dd.Days); // displays 0

試試這個

    public string YearsMonthsDaysDiff(DateTime dateFrom, DateTime dateTo)
    {
        Int32 mD = DateTime.DaysInMonth(dateTo.Year, dateTo.AddMonths(-1).Month); //first check out days in month before dateTo month
        Int32 D1 = dateFrom.Day;
        Int32 M1 = dateFrom.Month;
        Int32 Y1 = dateFrom.Year;
        Int32 D2 = dateTo.Day;
        Int32 M2 = dateTo.Month;
        Int32 Y2 = dateTo.Year;

        // Substract each datetime components accordingly
        D2 -= D1;
        M2 -= M1;
        Y2 -= Y1;
        if (D2 < 0)
        {
            D2 += mD;// D2 is less then D1, then add mD
            M2 -= 1; // but, substract 1 from M2 
        }
        if (M2 < 0)
        {
            M2 += 12; // if M2 is less then M1, then add with 12
            Y2 -= 1; // but substract 1 from Y2 
        }
        return Y2.ToString("## years ") + M2.ToString("##  months ") + D2.ToString("## days");
    }

這對我來說可以

這是一個class,它允許您查詢一對DateTimes差異的各種屬性。 我現在剛剛把它攪起來,並將它發布到公共領域。 隨心所欲地使用它,但使用它需要您自擔風險。

public static class DateCalcs
{
    /// <summary>
    /// returns the integer number of years between start and finish
    /// </summary>
    /// <param name="start">Start DateTime</param>
    /// <param name="finish">FinishDateTime</param>
    /// <returns></returns>
    public static int YearDiff(DateTime start, DateTime finish)
    {
        DateTime _start, _finish;
        bool _negate = (finish < start);
        if(_negate)
        {
            _start = finish;
            _finish = start;
        }
        else
        {
            _start = start;
            _finish = finish;
        }
        int _diff = 0;
        while(_start.AddYears(1) < _finish)
        {
            _diff++;
            _start = _start.AddYears(1);
        }

        if(_negate)
        {
            _diff = _diff * (-1);
        }

        return _diff;
    }

    /// <summary>
    /// returns the integer number of months between start and finish
    /// </summary>
    /// <param name="start">Start DateTime</param>
    /// <param name="finish">Finish DateTime</param>
    /// <returns></returns>
    public static int MonthDiff(DateTime start, DateTime finish)
    {
        DateTime _start, _finish;
        bool _negate = (finish < start);
        if (_negate)
        {
            _start = finish;
            _finish = start;
        }
        else
        {
            _start = start;
            _finish = finish;
        }
        int _diff = 0;
        while (_start.AddMonths(1) < _finish)
        {
            _diff++;
            _start = _start.AddMonths(1);
        }

        if (_negate)
        {
            _diff = _diff * (-1);
        }

        return _diff;
    }

    /// <summary>
    /// returns the integer number of days between start and finish
    /// </summary>
    /// <param name="start">start DateTime</param>
    /// <param name="finish">finish DateTime</param>
    /// <returns></returns>
    public static int DayDiff(DateTime start, DateTime finish)
    {

        var _diff = finish - start;
        return (int)_diff.TotalDays;
    }

    /// <summary>
    /// returns the integer number of hours between start and finish
    /// </summary>
    /// <param name="start">start DateTime</param>
    /// <param name="finish">finish DateTime</param>
    /// <returns></returns>
    public static int HourDiff(DateTime start, DateTime finish)
    {
        var _diff = finish - start;
        return(int)_diff.TotalHours;
    }

    /// <summary>
    /// returns the integer number of minutes between start and finish
    /// </summary>
    /// <param name="start">start DateTime</param>
    /// <param name="finish">finish DateTime</param>
    /// <returns></returns>
    public static int MinuteDiff(DateTime start, DateTime finish)
    {
        var _diff = finish - start;
        return (int)_diff.TotalMinutes;
    }

    /// <summary>
    /// returns the integer number of seconds between start and finish
    /// </summary>
    /// <param name="start">start DateTime</param>
    /// <param name="finish">finish DateTime</param>
    /// <returns></returns>
    public static int SecondDiff(DateTime start, DateTime finish)
    {
        var _diff = finish - start;
        return (int)_diff.TotalSeconds;
    }

    /// <summary>
    /// returns the integer number of milliseconds between start and finish
    /// </summary>
    /// <param name="start">start DateTime</param>
    /// <param name="finish">finish DateTime</param>
    /// <returns></returns>
    public static int MilliSecondDiff(DateTime start, DateTime finish)
    {
        var _diff = finish - start;
        return (int)_diff.TotalMilliseconds;
    }

    /// <summary>
    /// returns the integer remaining number of months between two DateTimes 
    /// after the year difference has been removed
    /// </summary>
    /// <param name="start">start DateTime</param>
    /// <param name="finish">finish DateTime</param>
    /// <returns></returns>
    public static int MonthPartDiff(DateTime start, DateTime finish)
    {
        return MonthDiff(start.AddYears(YearDiff(start, finish)), finish);
    }

    /// <summary>
    /// returns the integer remaining number of days between two DateTimes 
    /// after the year difference and the month difference has been removed
    /// </summary>
    /// <param name="start"></param>
    /// <param name="finish"></param>
    /// <returns></returns>
    public static int DayPartDiff(DateTime start, DateTime finish)
    {
        return DayDiff(start.AddMonths(MonthDiff(start, finish)), finish);
    }

    /// <summary>
    /// returns the integer remaining number of hours between two DateTimes 
    /// after the year, month and day difference has been removed
    /// </summary>
    /// <param name="start"></param>
    /// <param name="finish"></param>
    /// <returns></returns>
    public static int HourPartDiff(DateTime start, DateTime finish)
    {
        return (finish-start).Hours;
    }

    /// <summary>
    /// returns the integer remaining number of minutes between two DateTimes 
    /// after the year, month, day and hour difference has been removed
    /// </summary>
    /// <param name="start"></param>
    /// <param name="finish"></param>
    /// <returns></returns>
    public static int MinutePartDiff(DateTime start, DateTime finish)
    {
        return (finish-start).Minutes;
    }

    /// <summary>
    /// returns the integer remaining number of seconds between two DateTimes 
    /// after the year, month, day, hour and minute difference has been removed
    /// </summary>
    /// <param name="start"></param>
    /// <param name="finish"></param>
    /// <returns></returns>
    public static int SecondPartDiff(DateTime start, DateTime finish)
    {
        return (finish - start).Seconds;
    }

    /// <summary>
    /// returns the integer remaining number of milliseconds between two DateTimes 
    /// after the year, month, day, hour, minute and second difference has been removed
    /// </summary>
    /// <param name="start"></param>
    /// <param name="finish"></param>
    /// <returns></returns>
    public static int MilliSecondPartDiff(DateTime start, DateTime finish)
    {
        return (finish - start).Milliseconds;
    }

}

所以你可以這樣稱呼它:

var finish = DateTime.Now;
var start = new DateTime(1967, 7, 3);

var years = DateCalcs.YearDiff(start, finish);
Console.WriteLine ("Age in years: {0}", years);
var months = DateCalcs.MonthDiff(start, finish);
Console.WriteLine("Age in months: {0}", months);
var days = DateCalcs.DayDiff(start, finish);
Console.WriteLine("Age in days: {0}", days);
var hours = DateCalcs.HourDiff(start, finish);
Console.WriteLine("Age in hours: {0}", hours);
var minutes = DateCalcs.MinuteDiff(start, finish);
Console.WriteLine("Age in minutes: {0}", minutes);
var seconds = DateCalcs.SecondDiff(start, finish);
Console.WriteLine("Age in seconds: {0}", seconds);
var milliSeconds = DateCalcs.MilliSecondDiff(start, finish);
Console.WriteLine("Age in milliseconds: {0}", milliSeconds);

var AgeString = string.Format("{0}yr, {1}mo, {2}d, {3}h, {4}m, {5}s, {6}ms",
    DateCalcs.YearDiff(start, finish),
    DateCalcs.MonthPartDiff(start, finish),
    DateCalcs.DayPartDiff(start, finish),
    DateCalcs.HourPartDiff(start, finish),
    DateCalcs.MinutePartDiff(start, finish),
    DateCalcs.SecondPartDiff(start, finish),
    DateCalcs.MilliSecondPartDiff(start, finish)
    );

Console.WriteLine("Or {0}", AgeString);

剛剛返回

Age in years: 46
Age in months: 560
Age in days: 17073
Age in hours: 409771
Age in minutes: 24586290
Age in seconds: 1475177401
Age in milliseconds: -2147483648
Or 46yr, 8mo, 28d, 19h, 30m, 1s, 792ms

您可以將時間段庫DateDiff class 用於 .NET :

// ----------------------------------------------------------------------
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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM