Format A TimeSpan With Years

后端 未结 6 1194
深忆病人
深忆病人 2020-11-27 06:45

I have a class with 2 date properties: FirstDay and LastDay. LastDay is nullable. I would like to generate a string in the format of

相关标签:
6条回答
  • 2020-11-27 07:23

    I needed to do this for Core 3. NodaTime seems to have a dependancy on Framework 4.7.2. I wrote the below method which seems to work to format a timespan into years, months and days, omitting the parts it doesn't need.

    public static string ToYearsMonthsAndDays(this TimeSpan span)
        {
            var result = string.Empty;
            var totalYears = span.Days / 364.25;
            var fullYears = Math.Floor(totalYears);
    
            var totalMonths = (span.Days - (365.24 * fullYears)) / 30;
            var fullMonths = Math.Floor(totalMonths);
    
            var totalDays = (span.Days - (365.24 * totalYears) - (30 * fullMonths)) / 30;
            var fullDays = Math.Floor(totalDays);
            var sb = new StringBuilder();
            if (fullYears > 0)
            {
                if (sb.Length > 0)
                    sb.Append(", ");
                sb.Append(fullYears + "y");
            }
            if (fullMonths > 0)
            {
                if (sb.Length > 0)
                    sb.Append(", ");
                sb.Append(fullMonths + "m");
            }
            if (fullDays > 0)
            {
                if (sb.Length > 0)
                    sb.Append(", ");
                sb.Append(fullDays + "d");
            }
            return sb.ToString();
        }
    
    0 讨论(0)
  • 2020-11-27 07:30

    I wouldn't do this with a TimeSpan. Date math gets tricky as soon as you go beyond days because the number of days in a month and days in a year is no longer constant. It's likely why TimeSpan does not contain properties for Years and Months. I would instead determine the number of years/months/days, etc between the two DateTime values and display the results accordingly.

    0 讨论(0)
  • 2020-11-27 07:31
    Public Function TimeYMDBetween(StartDate As DateTime, EndDate As DateTime) As String
        Dim Years As Integer = EndDate.Year - StartDate.Year
        Dim Months As Integer = EndDate.Month - StartDate.Month
        Dim Days As Integer = EndDate.Day - StartDate.Day
        Dim DaysLastMonth As Integer
    
        'figure out how many days were in last month
        If EndDate.Month = 1 Then
            DaysLastMonth = DateTime.DaysInMonth(EndDate.Year - 1, 12)
        Else
            DaysLastMonth = DateTime.DaysInMonth(EndDate.Year, EndDate.Month - 1)
        End If
    
        'adjust for negative days
        If Days < 0 Then
            Months = Months - 1
            Days = Days + DaysLastMonth 'borrowing from last month
        End If
    
        'adjust for negative Months
        If Months < 0 Then 'startdate hasn't happend this year yet
            Years = Years - 1
            Months = Months + 12
        End If
    
        Return Years.ToString() + " Years, " + Months.ToString() + " Months and " + Days.ToString() + " Days"
    
    End Function
    
    0 讨论(0)
  • 2020-11-27 07:32

    I think this should work:

    public static int DiffYears(DateTime dateValue1, DateTime dateValue2)
    {
        var intToCompare1 = Convert.ToInt32(dateValue1.ToString("yyyyMMdd"));
        var intToCompare2 = Convert.ToInt32(dateValue2.ToString("yyyyMMdd"));
        return (intToCompare2 - intToCompare1) / 10000;
    }
    
    0 讨论(0)
  • 2020-11-27 07:35
    public string GetAgeText(DateTime birthDate)
    {
            const double ApproxDaysPerMonth = 30.4375;
            const double ApproxDaysPerYear = 365.25;
    
            /*
            The above are the average days per month/year over a normal 4 year period
            We use these approximations as they are more accurate for the next century or so
            After that you may want to switch over to these 400 year approximations
    
               ApproxDaysPerMonth = 30.436875
               ApproxDaysPerYear  = 365.2425 
    
              How to get theese numbers:
                The are 365 days in a year, unless it is a leepyear.
                Leepyear is every forth year if Year % 4 = 0
                unless year % 100 == 1
                unless if year % 400 == 0 then it is a leep year.
    
                This gives us 97 leep years in 400 years. 
                So 400 * 365 + 97 = 146097 days.
                146097 / 400      = 365.2425
                146097 / 400 / 12 = 30,436875
    
            Due to the nature of the leap year calculation, on this side of the year 2100
            you can assume every 4th year is a leap year and use the other approximatiotions
    
            */
        //Calculate the span in days
        int iDays = (DateTime.Now - birthDate).Days;
    
        //Calculate years as an integer division
        int iYear = (int)(iDays / ApproxDaysPerYear);
    
        //Decrease remaing days
        iDays -= (int)(iYear * ApproxDaysPerYear);
    
        //Calculate months as an integer division
        int iMonths = (int)(iDays / ApproxDaysPerMonth);
    
        //Decrease remaing days
        iDays -= (int)(iMonths * ApproxDaysPerMonth);
    
        //Return the result as an string   
        return string.Format("{0} years, {1} months, {2} days", iYear, iMonths, iDays);
    }
    
    0 讨论(0)
  • 2020-11-27 07:39

    A TimeSpan doesn't have a sensible concept of "years" because it depends on the start and end point. (Months is similar - how many months are there in 29 days? Well, it depends...)

    To give a shameless plug, my Noda Time project makes this really simple though:

    using System;
    using NodaTime;
    
    public class Test
    {
        static void Main(string[] args)
        {
            LocalDate start = new LocalDate(2010, 6, 19);
            LocalDate end = new LocalDate(2013, 4, 11);
            Period period = Period.Between(start, end,
                                           PeriodUnits.Years | PeriodUnits.Days);
    
            Console.WriteLine("Between {0} and {1} are {2} years and {3} days",
                              start, end, period.Years, period.Days);
        }
    }
    

    Output:

    Between 19 June 2010 and 11 April 2013 are 2 years and 296 days
    
    0 讨论(0)
提交回复
热议问题