Reputation: 12748
Is there a built-in function to calculate the number of hours in a month? It needs it take care of daylightsaving (which add or reduce an hour).
Upvotes: 5
Views: 280
Reputation: 4240
An alternative implementation in C# which allows the TimeZone to be specified:
public static int HoursInMonth(int year, int month, string timeZoneId)
{
var timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
var date = new DateTime(year, month, 1);
var nextMonth = date.AddMonths(1);
var start = TimeZoneInfo.ConvertTimeToUtc(date, timeZone);
var end = TimeZoneInfo.ConvertTimeToUtc(nextMonth, timeZone);
return (int)(end - start).TotalHours;
}
Upvotes: 0
Reputation: 1500835
If you're not in a time zone where midnight isn't always valid, you could do something like this (apologies if the VB syntax is slightly off):
Dim start = New DateTime(year, month, day, 0, 0, 0, DateTimeKind.Local)
Dim end = start.AddMonths(1)
Dim length = end.ToUniversalTime() - start.ToUniversalTime()
Dim hours = length.TotalHours
That has a potential problem if you're somewhere like Brazil where the DST transition occurs at midnight local time. Note that the above is all assuming you want to use the system-local time zone.
With Noda Time, you could create the appropriate LocalDate
values, then convert to a ZonedDateTime
at the start of the relevant day, and work out the difference that way, without any ambiguity. C# example:
var zone = ... // Whatever DateTimeZone you want...
var start = new LocalDate(year, month, day);
var end = start.PlusMonths(1);
var startInstant = zone.AtStartOfDay(start).ToInstant();
var endInstant = zone.AtStartOfDay(end).ToInstant();
var duration = endInstant - startInstant;
var hours = duration.Ticks / NodaConstants.TicksPerHour;
Upvotes: 4