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