Reputation: 1386
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
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
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
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