Patterns for Duration values

The Duration type supports the following patterns:

Standard Patterns

The following standard pattern is supported:

  • o: General round-trip pattern, which always uses the invariant culture and a pattern string of -D:hh:mm:ss.FFFFFFFFF. This is the default format pattern.

  • j: Round-trip pattern used by NodaTime.Serialization.JsonNet, which always uses the invariant culture and a pattern string of -H:mm:ss.FFFFFFFFF.

Custom Patterns

The following custom pattern characters are supported for durations. See custom pattern notes for general notes on custom patterns, including characters used for escaping and text literals.

The pattern letters basically split into two categories:

  • "Total" values, which represent as much of the duration as possible. For example, 1 day and 2 hours has a "total hours" value of 26.
  • "Partial" values, which represent part of a duration within a larger unit. For example, 1 day and 2 hours has an "hours of day" value of 2.

A pattern can only have a single "total" value, and typically will have exactly one total value, which would be the largest unit represented. You would normally want to then use each successive "partial" unit until you've got to the precision you're interested in. For example, useful patterns are:

  • -D:hh:mm:ss - days, hours, minutes and seconds
  • -H:mm:ss.fff - hours, minutes, seconds and milliseconds
  • M:ss - just minutes and seconds (not terribly useful for very long durations, or negative ones)

Bad (but legal) patterns would be:

  • hh:MM:ss - total minutes, but only partial hours!
  • HH:ss - total hours, partial seconds... but no partial minutes

It's possible that a future release will be detect "bad" patterns and reject them more aggressively.

The total letter D can be repeated up to 8 times, and H, M and S up to 13 times. The repetition count specifies the minimum number of digits for both formatting and parsing, not a fixed width. Parsing consumes additional digits up to the corresponding limit. For example, HH:mm formats 1 hour and 30 minutes as 01:30, and parses both 01:30 and 101:30, but not 1:30. Use H:mm to allow a single-digit hour value.

Use a separator between a total value and a following numeric field to avoid ambiguity. For example, HHmm does not split 1213 into 12 hours and 13 minutes: it consumes all four digits as hours, leaving no digits for the minutes, and resulting in a parse failure. A pattern such as HH:mm avoids this failure. We acknowledge that Noda Time could allow such patterns, determine the minimum and maximum length of the total field, and handle situations like this. A later release may improve this, but for now it is recommended to use a separator.

Partial letters for hours, minutes and seconds can be repeated once or twice (so 'h' and 'hh' are valid, but 'hhh' is not); again, this is for zero-padding, so a value of 3 hours and 2 minutes formatted with 'H:m' would simply be "3:2", whereas formatted with 'H:mm' it would be "3:02". We recommend using the repeated form in most cases.

Character Meaning Example
D (DD etc) Total days 54 hours with a pattern of D:hh:mm => 2:06:00
H (HH etc) Total hours 54 hours with a pattern of H:mm => 54:00
h or hh Hours within a day (0-23) 54 hours with a pattern of D:hh => 2:06
M (MM etc) Total minutes 3 hours and 10 minutes with a pattern of M:ss => 190:00
m or mm Minutes within an hour (0-59) 3 hours and 10 minutes with a pattern of H:mm:ss => 3:10:00
S (SS etc) Total seconds 2 minutes and 10 seconds with a pattern of S.fff => 70.000
s or ss Seconds within a minute (0-59) 2 minutes and 10 seconds with a pattern of M:ss.fff => 2:10.000
f ... fffffffff The fractional second part of the duration, using exactly the specified number of characters. Trailing digits are truncated towards zero. 1 second, 123450000 nanoseconds: s.fffffffff => 1.123450000
Exactly 1 second: s.f => 1.0
F ... FFFFFFFFF The fractional second part of the duration, using at most the specified number of characters (up to 9). Trailing digits are truncated towards zero, and trailing insignificant zeroes are truncated. If this comes after a decimal separator and the value is zero, the decimal separator is also truncated. 1 second, 123450000 nanoseconds: s.FFFFFFF => 1.12345
Exactly 1 second: s.F => 1
+ The sign of the value, always specified whether positive or negative. The character used will depend on the format provider; + and - are used by the invariant culture. Positive value: +HH:mm => +07:30
Negative value: +HH:mm => -07:30
- The sign of the value, only specified when the value is negative. The character used will depend on the format provider; - is used by the invariant culture. Positive value: -HH:mm => 07:30
Negative value: -HH:mm => -07:30
. This is always a period ("."); not a culture-sensitive decimal separator as one might expect. This follows the example of other standard libraries, however odd it may appear. The only difference between a period and any other literal character is that when followed by a series of "F" characters, the period will be removed if there are no fractional seconds.
: The time separator for the format provider; colon in the invariant culture. HH:mm => 07:30