DateTime todayUTC = DateTime.Today.ToUniversalTime();
DateTime currentTimeUTC = todayUTC;
DateTime currentTimeLocal, todayLocal;
int interval = 60; //in minutes
do
{
currentTimeLocal = currentTimeUTC.ToLocalTime();
todayLocal = todayUTC.ToLocalTime();
TimeSpan difference = currentTimeLocal.Subtract(todayLocal);
//Print the date in HHmm format, and append a 'd' if the time is during the
//repeated hour.
Console.WriteLine(
"{0:0000}{1}",
(Math.Floor(difference.TotalHours) * 100) + (difference.TotalMinutes % 60),
IsRepeatedHour(currentTimeLocal) ? "d" : "");
currentTimeUTC = currentTimeUTC.AddMinutes(interval);
}
while (currentTimeLocal.Day == todayLocal.Day);
bool IsRepeatedHour(DateTime time)
{
return time.ToUniversalTime().AddHours(-1).ToLocalTime() == time;
}
Refactorings
No refactoring yet !
fezmonkey
October 21, 2008, October 21, 2008 19:24, permalink
Removed the magic arithmetic and replaced it with the hour and minute values directly. The code is more straightforward, but now we have a special case at the end where the loop would print "0000" instead of "2400" so we have to hard-code the "2400", which I don't really like.
//these would be inputs to the function
int interval = 60; //in minutes
DateTime start = DateTime.Today;
DateTime startTimeUTC = start.ToUniversalTime();
DateTime startTimeLocal = start.ToLocalTime();
DateTime currentTimeUTC = startTimeUTC;
DateTime currentTimeLocal = startTimeLocal;
while (currentTimeLocal.Day == startTimeLocal.Day)
{
//calculate repeated hour flag
String repeatedHourFlag = IsDuringRepeatedHour(currentTimeLocal) ? "d" : "";
//Print the date in HHmm format, and append a 'd' if the time is during the
//repeated hour.
String itemText = String.Format(
"{0:00}{1:00}{2}",
currentTimeLocal.Hour, currentTimeLocal.Minute, repeatedHourFlag);
//Add the time to the list in UTC format
Console.WriteLine("local time: {0}, GMT value: {1}", itemText, currentTimeUTC);
//Advance time to the next interval
currentTimeUTC = currentTimeUTC.AddMinutes(interval);
//convert next interval to local time
currentTimeLocal = currentTimeUTC.ToLocalTime();
}
//last item can't be generated correctly by the main loop, so we have to print it manually
Console.WriteLine("local time: 2400, GMT value: {1}", itemText, currentTimeUTC);
bool IsDuringRepeatedHour(DateTime time)
{
return time.ToUniversalTime().AddHours(-1).ToLocalTime() == time;
}
Moonshield
October 23, 2008, October 23, 2008 02:35, permalink
I have the same console result as your code with this.
Not sure about the appended 'd', it is never displayed in my test. I'd like more explanations to know when to display it or not
int interval = 60; //in minutes
DateTime start = DateTime.Today;
for (int IntervalIndex = 0; IntervalIndex < (1440 / interval); IntervalIndex++)
Console.WriteLine("local time: {0:HHmm}, GMT value: {1}", (start = start.AddMinutes(IntervalIndex == 0 ? 0 : interval)), start.ToUniversalTime());
Console.WriteLine("local time: 2400, GMT value: {0}", start.AddMinutes(interval).ToUniversalTime());
fezmonkey
October 23, 2008, October 23, 2008 18:14, permalink
Your refactoring produces incorrect results when start = 3/9/2008 or 11/2/2008. These days have 23 and 25 hours in them, respectively. The "d" is to indicate a time when there would be an ambiguity due to the repeated hour which occurs every fall. For example, time should progress as follows on 11/2/2008: 0000 (midnight), 0100, 0100d, 0200, 0300...
I need to generate a list of time values in the local time zone in 5, 15, and 60 minute intervals. The list must take into account Daylight Saving Time. For example:
0100
0200
0300
...
2300
2400