Converting Days into Human Readable Duration Text

前端 未结 4 905
终归单人心
终归单人心 2021-01-14 03:17

Given an amount of days, say 25, convert it into a duration text such as \"3 Weeks, 4 Days\"

C# and F# solutions would both be great if the F# variation offers any i

相关标签:
4条回答
  • 2021-01-14 03:48

    Here's an F# version based on the previously posted C# version. The main difference is it's applicative rather than imperative (no mutable variables).

    #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)    
    
    0 讨论(0)
  • 2021-01-14 03:51

    This is a recursive solution. Note that a duration only really makes sense measured against a particular point in time on a given calendar because month and year lengths vary. But here is a simple solution assuming fixed lengths:

    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 []
    
    0 讨论(0)
  • 2021-01-14 03:54
    String.Format("{0} Weeks, {1} days", days / 7, days % 7);
    
    0 讨论(0)
  • 2021-01-14 04:07
        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());
            }
        }
    
    0 讨论(0)
提交回复
热议问题