【问题标题】:Converting Days into Human Readable Duration Text将天数转换为人类可读的持续时间文本
【发布时间】:2008-11-17 20:43:27
【问题描述】:

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

如果 F# 变体提供了对 C# 的任何改进,C# 和 F# 解决方案都会很棒。

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

【问题讨论】:

    标签: c# f#


    【解决方案1】:
    String.Format("{0} Weeks, {1} days", days / 7, days % 7);
    

    【讨论】:

    • 或许可以添加一些基本的逻辑。例如。如果 days
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:
          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());
              }
          }
      

      【讨论】:

        【解决方案4】:

        这是基于之前发布的 C# 版本的 F# 版本。主要区别在于它是应用性的而不是命令性的(没有可变变量)。

        #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)    
        

        【讨论】:

          猜你喜欢
          • 2012-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-16
          • 2011-03-22
          • 1970-01-01
          • 2012-08-16
          • 1970-01-01
          • 2014-04-30
          相关资源
          最近更新 更多