C# 将天转换为人类可读的持续时间文本

C# 将天转换为人类可读的持续时间文本,c#,f#,C#,F#,给定一个天数,例如25天,将其转换为持续时间文本,例如“3周,4天” 如果F变异比C有任何改进,那么C和F的解决方案都是很好的 编辑:解决方案应该扩展到过去几周,包括几个月和几年。奖励积分包括世纪等。如果它是可配置的,则会有额外的奖励,这意味着您可以告诉该方法排除周的正常化 公共类计量单位{ String.Format("{0} Weeks, {1} days", days / 7, days % 7); 公共度量单位(字符串名称、int值){ 名称=名称; 价值=价值; } 公共字符串名称{

给定一个天数,例如25天,将其转换为持续时间文本,例如“3周,4天”

如果F变异比C有任何改进,那么C和F的解决方案都是很好的

编辑:解决方案应该扩展到过去几周,包括几个月和几年。奖励积分包括世纪等。如果它是可配置的,则会有额外的奖励,这意味着您可以告诉该方法排除周的正常化

公共类计量单位{
String.Format("{0} Weeks, {1} days", days / 7, days % 7);
公共度量单位(字符串名称、int值){ 名称=名称; 价值=价值; } 公共字符串名称{get;set;} 公共int值{get;set;} 公共静态计量单位[]全部=新计量单位[]{ 新计量单位(“年份”,356), 新的计量单位(“月”,30), 新的计量单位(“周”,7), 新计量单位(“日”,1) }; 公共静态字符串转换持续时间(整数天){ 列表结果=新列表(); for(int i=0;i=1){ 结果.Add((count+“”+All[i].Name)+(count==1?string.Empty:“s”); 天数-=计数*所有[i]。值; } } 返回字符串.Join(“,”,results.ToArray()); } }
这是一个基于先前发布的C版本的F版本。主要区别在于它的应用性而非强制性(没有可变变量)


这是一个递归解决方案。请注意,持续时间只有在给定日历上的特定时间点上才有意义,因为月和年的长度不同。但这里有一个假设固定长度的简单解决方案:

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 []

也许可以添加一些基本逻辑。例如,如果天数小于6,则将其计算为天数;如果不使用复数,则不添加s(或将s替换为“(s)”。
#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)    
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 []