Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing times above 24 hours in C#

Tags:

c#

datetime

Suppose a time stamp (just time or date and time) where the time can roll over to the next day:

00:00:00 <- midnight

01:00:00 <- 1 AM

23:00:00 <- 11 PM

24:00:00 <- midnight, day + 1

25:00:00 <- 1 AM, day + 1

What would be a way to parse it easily into a C# DateTime that would perform the carry-over to the next day? In other words, "01:00:00" would become "0001-01-01 01:00:00" and "25:00:00" would become "0001-01-02 01:00:00".

EDIT:

I should mention that this fails miserably (i.e FormatException):

DateTime.ParseExact("0001-01-01 25:00:00", "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
like image 386
MPelletier Avatar asked Mar 06 '11 04:03

MPelletier


4 Answers

Since you're trying to represent a period of time from an arbitrary point, rather than as a specific date, perhaps you would be better off using the System.TimeSpan class? This allows you to set values of more than 24 hours in the constructor, and can be used with DateTime objects like this:

System.TimeSpan timestamp = new System.TimeSpan(25, 0, 0);
System.DateTime parsedDateTime = new DateTime(0, 0, 0);
parsedDateTime = parsedDateTime.Add(timestamp);
Console.WriteLine(parsedDateTime.ToString("yyyy-MM-dd HH:mm:ss"));  //Output as "0001-01-02 01:00:00"

NOTE: Code is untested.

EDIT: In terms of parsing the strings, I can't think of any basic .NET objects that parse strings with values greater than 23 for the hour (since 25 is an invalid hour of the day), but assuming that the format is consistent, you could create a very simple string parsing routine (or even a regular expression) to read the values individually, and load the constructor manually.

like image 120
Karl Nicoll Avatar answered Nov 15 '22 14:11

Karl Nicoll


If you have an existing DateTime value you can add to, you can always use a TimeSpan:

string dt = "25:00:00";
int hours = int.Parse(dt.Split(':')[0]);
TimeSpan ts = TimeSpan.FromHours(hours);

TimeSpan.Parse() doesn't work directly in this case because it complains (fair enough!) about the 25 in the hour notation.

like image 26
kprobst Avatar answered Nov 15 '22 14:11

kprobst


If you want to code it out... this should be a starting point:

 string dateString = "0001-01-01 25:00:00";
 string[] parts = dateString.Split(' '); //now have '0001-01-01' and '25:00:00'

 string datePart = parts[0]; // '0001-01-01'
 string[] timeParts = parts[1].Split(':'); //now have '25', '00', and '00

 DateTime initialDate = DateTime.ParseExact(datePart, "yyyy-MM-dd", CultureInfo.InvariantCulture);//use the date as a starting point

 //use the add methods to get your desired datetime
 int hours = int.Parse(timeParts[0]);
 int minutes = int.Parse(timeParts[1]);
 int seconds = int.Parse(timeParts[2]);

 DateTime resultDate = initialDate.AddHours(hours)
                                    .AddMinutes(minutes)
                                    .AddSeconds(seconds);

Of course, it makes assumptions that the input is formatted properly and is parsable, etc.. In addition, you could definitely use timespan instead of the individual add methods for hour, minute, second as some other answers are..

like image 23
markt Avatar answered Nov 15 '22 15:11

markt


In case nobody points out an out-of-the-box answer, here is a neat ActionScript class I wrote to parse time inputs (human input)...

https://github.com/appcove/AppStruct/blob/master/Flex/AppStruct/src/AppStruct/TimeInput.as

It would be very simple to port this to C#, and you could tweak the 24 hour logic to result in #days, #hours, #minutes.

Good luck!

like image 26
gahooa Avatar answered Nov 15 '22 14:11

gahooa