【问题标题】:Rounding Time with NodaTime使用 NodaTime 舍入时间
【发布时间】:2018-03-20 13:49:34
【问题描述】:

我有一些LocalDateTimes,我需要根据定义的分钟列表将一天中的时间向上/向下舍入到最接近的分钟数。 例如,如果我有日期时间 2018-03-20T12:13:47 并且我必须将它四舍五入到下一个半小时(所以分钟是 00 或 30),我会得到 2018-03-20T12:30:00。四舍五入将给出2018-03-20T12:00:00

四舍五入可以是任意分钟,例如每 10 分钟 (0, 10, 20, 30, 40, 50),每一刻钟 (0, 15, 30, 45),或者说到一刻钟或之后 (15, 45)。这意味着四舍五入的日期可能会在另一个日期结束。

NodaTime 中是否有任何功能可以帮助进行这种舍入,还是我必须自己编写?我现在有一个工作版本,但它包括双循环并在午夜添加小时和分钟。

【问题讨论】:

    标签: c# time rounding nodatime


    【解决方案1】:

    有一个排序的功能会有所帮助:“调节器”的概念。如果您编写自己的返回 Func<LocalTime, LocalTime> 的方法,则可以使用 With 方法将其应用于 LocalTimeLocalDateTimeOffsetDateTimeOffsetTime(在 2.3+ 中)。

    这将很容易帮助截断大小写:

    using System;
    using NodaTime;
    
    class Test
    {
        static void Main()
        {
            var truncator = CreateTruncator(10);
            var start = new LocalDateTime(2018, 3, 21, 7, 32, 15);
            var truncated = start.With(truncator);
            Console.WriteLine(truncated); // 2018-03-21T07:30:00
        }
    
        static Func<LocalTime, LocalTime> CreateTruncator(int minuteGranularity) =>
            input => new LocalTime(
                input.Hour,
                input.Minute / minuteGranularity * minuteGranularity);
    }
    

    (请注意,如果您将 minuteGranularity 指定为 7 或其他不是 60 的因子,它仍会截断为始终从整点开始的句点。)

    但是,没有办法提前日期。调节器机制也适用于Func&lt;LocalDateTime, LocalDateTime&gt; - 您可以将其应用于LocalDateTimeOffsetDateTime。但是,是的,您需要自己编写代码来进行调整。正如您所说,您可能需要许多不同的选项来进行舍入,而 Noda Time 很难涵盖所有可能的用例。

    我绝对建议编写一个方法来创建一个调整器,而不是仅仅编写一个接受 LocalDateTime 和几分钟的方法 - 它提供了一种非常容易传递调整器的方法,正如我已经如图所示,它符合野田时代自己的调整。 (在 TimeAdjustersDateAdjusters 类中查找我们提供的开箱即用的类。)

    如果您在编写特定调整器时需要帮助,这可能值得在单独的问题中提出。我不会期望它需要双循环等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 2018-09-09
      • 2011-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多