【问题标题】:Getting number of seconds in a day获取一天中的秒数
【发布时间】:2013-04-05 20:44:41
【问题描述】:

我有一个始终保持午夜时间的日期时间列表,以及当天网站被视为“正常运行”的秒数。

我需要计算出“正常运行时间”的百分比,所以我需要知道当天有多少秒。我想知道 .NET 中是否有任何类似于 DateTime.DaysInMonth(year, month) 但一天中的秒数的东西。

我的 Google-fu 似乎让我失望了,我只能找到 .NET constant for number of seconds in a day? - 但这并没有考虑夏令时。

我觉得很简单

var secondsInDay = (startDay.AddDays(1) - startDay).TotalSeconds;

但我想知道这是否正确(简单但并非详尽的测试表明它是正确的)?
有没有更有效的方法来计算一天中的秒数?

请注意 - 这需要考虑夏令时

【问题讨论】:

  • 我认为你把事情复杂化了。为什么不 KISS 并仅以 UTC 天数为基础?
  • 这用于监控托管网站的网站统计信息。我们需要能够承诺 99.9% 的正常运行时间

标签: .net datetime


【解决方案1】:

我认为您需要使用DateTimeOffsetTimeZoneInfo。这个article 可以帮助您,特别是 Comparisons and Arithmetic Operations with DateTimeOffset Values 部分的第二个代码 sn-p。

您可以在该代码中看到他们在夏令时向 DateTimeOffset 实例添加小时数,结果考虑了时间变化。

编辑:下面的代码取自上述文章(代码没有达到您想要的效果,但表明与TimeZoneInfo 一起使用的DateTimeOffset 正在考虑夏令时:

    public static void Main()
   {
      DateTime generalTime = new DateTime(2008, 3, 9, 1, 30, 0);
      const string tzName = "Central Standard Time";
      TimeSpan twoAndAHalfHours = new TimeSpan(2, 30, 0);

      // Instantiate DateTimeOffset value to have correct CST offset 
      try
      {
         DateTimeOffset centralTime1 = new DateTimeOffset(generalTime, 
                    TimeZoneInfo.FindSystemTimeZoneById(tzName).GetUtcOffset(generalTime));

         // Add two and a half hours      
         DateTimeOffset centralTime2 = centralTime1.Add(twoAndAHalfHours);
         // Display result
         Console.WriteLine("{0} + {1} hours = {2}", centralTime1, 
                                                    twoAndAHalfHours.ToString(), 
                                                    centralTime2);  
      }
      catch (TimeZoneNotFoundException)
      {
         Console.WriteLine("Unable to retrieve Central Standard Time zone information.");
      }
   }

    // The example displays the following output to the console: 
    //    3/9/2008 1:30:00 AM -06:00 + 02:30:00 hours = 3/9/2008 4:00:00 AM -06:00

【讨论】:

    【解决方案2】:

    这是一个可以满足您要求的功能:

    public int SecondsInDay(DateTime dateTime, string timeZoneId)
    {
        var dt1 = dateTime.Date;
        var dt2 = dt1.AddDays(1);
        var zone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
    
        var dto1 = new DateTimeOffset(dt1, zone.GetUtcOffset(dt1));
        var dto2 = new DateTimeOffset(dt2, zone.GetUtcOffset(dt2));
        var seconds = (dto2 - dto1).TotalSeconds;
    
        return (int) seconds;
    }
    

    举个例子:

    int s = SecondsInDay(new DateTime(2013, 1, 1), "Central Standard Time");
    // 86400
    
    int s = SecondsInDay(new DateTime(2013, 3, 10), "Central Standard Time");
    // 82800
    
    int s = SecondsInDay(new DateTime(2013, 11, 3), "Central Standard Time");
    // 90000
    

    【讨论】:

      【解决方案3】:

      这个怎么样:

      TimeSpan.FromDays(1).TotalSeconds

      当然,除非您尝试计算一天中偶尔添加和删除的秒数,以使地球进动与时钟保持一致

      对于日光跟踪,您可以检查您的一天是否是返回的两个日期之一

      TimeZone.CurrentTimeZone.GetDaylightChanges(2013)

      并添加/删除增量

      或者您可以通过始终根据过去 24 小时而不是 1 天计算正常运行时间来跳过这些恶作剧

      【讨论】:

      • 我必须承认,我没有尝试过。是否考虑夏令时?我没有尝试过,因为我不知道它如何知道夏令时何时开始/停止(即有些日子有 23 小时,有些有 25 小时)
      猜你喜欢
      • 2011-01-06
      • 1970-01-01
      • 1970-01-01
      • 2019-07-28
      • 2015-01-29
      • 2020-11-21
      • 2011-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多