Data Types
For the string "07:35"
given in the question, there are three possible data types to choose from:
TimeSpan
- Primarily intended for a duration of elapsed time.
- Sometimes used for a time-of-day, especially prior to .NET 6.
- Range:
-10675199.02:48:05.4775808
to 10675199.02:48:05.4775807
- Magnitudes of 24 hours or larger are represented in terms of standard (24 hour) days, which are separated by a period in the default string representation.
- Negative values represent moving backwards in time.
TimeOnly
- Intended for a time-of-day value, without any date component.
- Range:
00:00:00.000000
to 23:59:59.9999999
- Available since .NET 6. For older .NET, consider a polyfill library such as
Portable.System.DateTimeOnly
.
DateTime
- Primarily intended for a date combined with a time.
- Range:
0001-01-01 00:00:00.0000000
to 9999-12-31 23:59:59.9999999
- Sometimes used for representing time-only values, by using an arbitrary date such as
0001-01-01
or 2000-01-01
, etc. When doing so, it's important to disregard the date in all usages. Generally, this was done in older software to support parsing am/pm components, but is no longer necessary since .NET 6.
Parsing
Methods
All three data types support the following methods:
Parse
- Attempts to parse using a variety of known formats. Throws an exception if parsing does not succeed.
TryParse
- Like Parse
, but returns false
if the parsing does not succeed. Useful for validation logic.
ParseExact
- Attempts to parse using a specific format. Throws an exception if parsing does not succeed.
TryParseExact
- Like ParseExact
, but returns false
if parsing does not succeed. Useful for validation logic.
Format Specifiers (tokens)
The ParseExact
and TryParseExact
methods require a format specification, which can be either in a standard form represented by a a single character, or a custom form represented by multiple characters. The format strings differ by data type.
Examples
I'll demonstrate both TimeSpan
and TimeOnly
. (Generally speaking, DateTime
is no longer needed for such strings.) In all cases, be sure to import both System
and System.Globalization
in your using statements, unless you're already importing them implicitly.
Flexible parsing (using current culture):
TimeSpan duration = TimeSpan.Parse("07:35");
TimeOnly time = TimeOnly.Parse("07:35");
Fixed parsing (performant, using invariant culture):
TimeSpan duration = TimeSpan.ParseExact("07:35", @"hh\:mm",
CultureInfo.InvariantCulture);
TimeOnly time = TimeOnly.ParseExact("07:35", "HH:mm",
CultureInfo.InvariantCulture);
Flexible parsing for validation (using current culture):
TimeSpan duration;
if (!TimeSpan.TryParse("07:35", out duration))
{
// handle validation error
}
TimeOnly time;
if (!TimeOnly.TryParse("07:35", out time))
{
// handle validation error
}
Fixed parsing for validation (performant, using invariant culture):
TimeSpan duration;
if (!TimeSpan.TryParseExact("07:35", @"hh\:mm",
CultureInfo.InvariantCulture, out duration))
{
// handle validation error
}
TimeOnly time;
if (!TimeOnly.TryParseExact("07:35", "HH:mm",
CultureInfo.InvariantCulture, DateTimeStyles.None, out time))
{
// handle validation error
}