válido valor reconoce net larga hora formato fecha ejemplos como cadena c# .net formatting .net-4.5 timespan

valor - timespan c# ejemplos



Formato A TimeSpan con años (5)

Tengo una clase con 2 propiedades de fecha: FirstDay y LastDay . LastDay es anulable. Me gustaría generar una cadena en el formato de "x year(s) y day(s)" . Si el total de años es menor que 1, me gustaría omitir la sección de año. Si el total de días es inferior a 1, me gustaría omitir la sección del día. Si cualquiera de los años o días son 0, deben decir "día / año", en lugar de "días / años" respectivamente.

Ejemplos:
2.2 años: "2 años 73 días"
1.002738 años: "1 año 1 día"
0.2 años: "73 días"
2 años: "2 años"

Lo que tengo funciona, pero es largo:

private const decimal DaysInAYear = 365.242M; public string LengthInYearsAndDays { get { var lastDay = this.LastDay ?? DateTime.Today; var lengthValue = lastDay - this.FirstDay; var builder = new StringBuilder(); var totalDays = (decimal)lengthValue.TotalDays; var totalYears = totalDays / DaysInAYear; var years = (int)Math.Floor(totalYears); totalDays -= (years * DaysInAYear); var days = (int)Math.Floor(totalDays); Func<int, string> sIfPlural = value => value > 1 ? "s" : string.Empty; if (years > 0) { builder.AppendFormat( CultureInfo.InvariantCulture, "{0} year{1}", years, sIfPlural(years)); if (days > 0) { builder.Append(" "); } } if (days > 0) { builder.AppendFormat( CultureInfo.InvariantCulture, "{0} day{1}", days, sIfPlural(days)); } var length = builder.ToString(); return length; } }

¿Hay una forma más concisa de hacer esto (pero aún así se puede leer)?


Creo que esto debería funcionar:

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; }


Un TimeSpan no tiene un concepto sensible de "años" porque depende del punto de inicio y final. (Los meses son similares: ¿cuántos meses hay en 29 días? Bueno, depende ...)

Para dar un enchufe desvergonzado, mi proyecto Noda Time lo hace muy simple:

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); } }

Salida:

Between 19 June 2010 and 11 April 2013 are 2 years and 296 days


Yo no haría esto con un TimeSpan . Las matemáticas de fecha se vuelven difíciles tan pronto como pasan los días porque la cantidad de días en un mes y los días en un año ya no son constantes. Es probable por qué TimeSpan no contiene propiedades por Years y Months . En su lugar, determinaría el número de años / meses / días, etc., entre los dos valores de DateTime y mostraría los resultados en consecuencia.


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); }


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