F912d7c5332fb479523439b9da1dbeae

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

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 !

F912d7c5332fb479523439b9da1dbeae

fezmonkey

October 21, 2008, October 21, 2008 19:24, permalink

No rating. Login to rate!

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

Moonshield

October 23, 2008, October 23, 2008 02:35, permalink

No rating. Login to rate!

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());
F912d7c5332fb479523439b9da1dbeae

fezmonkey

October 23, 2008, October 23, 2008 18:14, permalink

No rating. Login to rate!

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...

Your refactoring





Format Copy from initial code

or Cancel