una semanas para numero meses dias convertir como cantidad calcular años c# f#

c# - semanas - formula para calcular años meses y dias en excel



Convertir días en texto de duración legible para humanos (4)

Dada una cantidad de días, digamos 25, conviértala en un texto de duración como "3 semanas, 4 días"

Las soluciones C # y F # serían geniales si la variación de F # ofrece alguna mejora sobre C #.

Editar: la solución debería expandirse en las últimas semanas para incluir meses y años. Puntos de bonificación por incluir siglos, etc. Bonificación adicional si es algo configurable, lo que significa que puede indicarle al método que excluya la normalización de semanas.


public class UnitOfMeasure { public UnitOfMeasure(string name, int value) { Name = name; Value = value; } public string Name { get; set; } public int Value { get; set; } public static UnitOfMeasure[] All = new UnitOfMeasure[] { new UnitOfMeasure("Year", 356), new UnitOfMeasure("Month", 30), new UnitOfMeasure("Week", 7), new UnitOfMeasure("Day", 1) }; public static string ConvertToDuration(int days) { List<string> results = new List<string>(); for (int i = 0; i < All.Length; i++) { int count = days / All[i].Value; if (count >= 1) { results.Add((count + " " + All[i].Name) + (count == 1 ? string.Empty : "s")); days -= count * All[i].Value; } } return string.Join(", ", results.ToArray()); } }


String.Format("{0} Weeks, {1} days", days / 7, days % 7);


Aquí hay una versión de F # basada en la versión de C # publicada anteriormente. La principal diferencia es que es más aplicativo que imperativo (sin variables mutables).

#light let conversions = [| 365, "Year", "Years" 30, "Month", "Months" 7, "Week", "Weeks" 1, "Day", "Days" |] let ToDuration numDays = conversions |> Array.fold_left (fun (remainDays,results) (n,sing,plur) -> let count = remainDays / n if count >= 1 then remainDays - (count * n), (sprintf "%d %s" count (if count=1 then sing else plur)) :: results else remainDays, results ) (numDays,[]) |> snd |> (fun rs -> System.String.Join(", ", List.rev rs |> List.to_array)) printfn "%s" (ToDuration 1008)


Esta es una solución recursiva. Tenga en cuenta que una duración solo realmente tiene sentido contra un punto particular en el tiempo en un calendario dado porque las longitudes de mes y año varían. Pero aquí hay una solución simple asumiendo longitudes fijas:

let divmod n m = n / m, n % m let units = [ ("Centuries", TimeSpan.TicksPerDay * 365L * 100L ); ("Years", TimeSpan.TicksPerDay * 365L); ("Weeks", TimeSpan.TicksPerDay * 7L); ("Days", TimeSpan.TicksPerDay) ] let duration days = let rec duration'' ticks units acc = match units with | [] -> acc | (u::us) -> let (wholeUnits, ticksRemaining) = divmod ticks (snd u) duration'' ticksRemaining us (((fst u), wholeUnits) :: acc) duration'' (TimeSpan.FromDays(float days).Ticks) units []