berkeleybross
berkeleybross

Reputation: 1386

Getting number of seconds in a day

I have a list of datetimes that have always hold the time midnight, and the number of seconds a website was considered "up" on that day.

I need to work out the percentage of "uptime", so I need to know exactly how many seconds are in that day. I was wondering if there is anything in .NET similar to DateTime.DaysInMonth(year, month) but for seconds in a day.

My Google-fu seems to have let me down, and all I can find is .NET constant for number of seconds in a day? - but that doesn't take into account daylight savings.

I think it is as simple as

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

But I was wondering if this is correct (simple but not exhaustive tests indicate it is)?
Is there a more efficient way of calculating the number of seconds in a given day?

Please note - This needs to take account of daylight saving hours

Upvotes: 1

Views: 192

Answers (3)

Matt Johnson-Pint
Matt Johnson-Pint

Reputation: 241450

Here is a function that will do what you asked:

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;
}

As an example:

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

Upvotes: 0

jorgehmv
jorgehmv

Reputation: 3713

I think you need to use DateTimeOffset and TimeZoneInfo. This article can help you, specifically the second code snippet at section Comparisons and Arithmetic Operations with DateTimeOffset Values.

You can see in that code that they are adding hours to a DateTimeOffset instance on a daylight savings day and the result take into account the time change.

EDIT: Code below is taken from the article mentioned above (the code doesn't do what you want but shows that DateTimeOffset used with TimeZoneInfo is considering daylight savings time:

    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

Upvotes: 1

Sten Petrov
Sten Petrov

Reputation: 11040

How about this:

TimeSpan.FromDays(1).TotalSeconds

Unless of course you're trying to account for the seconds added and removed occasionally from a day to keep Earth precession in line with clocks

For daylight tracking you can check if your day is one of the two that are returned by

TimeZone.CurrentTimeZone.GetDaylightChanges(2013)

and add/remove the Delta

OR you can skip these shenanigans by always calculating your uptime based on past 24h instead of 1 day

Upvotes: 0

Related Questions