# 24-Hour Time (HH:MM:SS)

Key: `datetime.time.hms_24h`

Standard 24-hour time without fractional seconds. The most common time representation in data systems.

Page: <https://meridian.online/docs/projects/finetype/types/datetime/time/hms_24h>

Format: `%H:%M:%S`

Samples: `10:30:00`, `23:59:59`, `00:00:00`

## Background

### Origin

The modern 24-hour system is a late-19th century adaptation of the German midnight-starting system.[[1]](https://en.wikipedia.org/wiki/24-hour_clock) The Canadian Pacific Railway was among the first organisations to adopt the 24-hour clock, at midsummer 1886.[[1]](https://en.wikipedia.org/wiki/24-hour_clock) In 1920 the United States Navy became the first United States organisation to adopt the 24-hour clock.[[1]](https://en.wikipedia.org/wiki/24-hour_clock) In the United States the 24-hour clock is often referred to as military time.[[1]](https://en.wikipedia.org/wiki/24-hour_clock)

ISO 8601 was first published as ISO 8601:1988 in June 1988.[[2]](https://en.wikipedia.org/wiki/ISO_8601) ISO 8601 writes a time in its extended format as hh:mm:ss, with colons between hours, minutes and seconds.[[2]](https://en.wikipedia.org/wiki/ISO_8601) ISO 8601's basic format writes the same fields without separators, as hhmmss.[[2]](https://en.wikipedia.org/wiki/ISO_8601) ISO 8601 allows a seconds value of 60 only to denote an added leap second.[[2]](https://en.wikipedia.org/wiki/ISO_8601) ISO 8601-1:2019 removed 24:00:00 as a representation for the end of day.[[2]](https://en.wikipedia.org/wiki/ISO_8601) A 2022 amendment to ISO 8601-1 restored 24:00:00 to mean midnight at the end of a calendar day.[[2]](https://en.wikipedia.org/wiki/ISO_8601)

RFC 3339 was written by G. Klyne and C. Newman and published in July 2002.[[3]](https://www.rfc-editor.org/rfc/rfc3339) RFC 3339 defines partial-time as a two-digit hour, minute and second separated by colons, with optional fractional seconds.[[3]](https://www.rfc-editor.org/rfc/rfc3339) RFC 3339 limits the hour to 00 through 23, although ISO 8601 permits the hour to be 24.[[3]](https://www.rfc-editor.org/rfc/rfc3339) Frictionless Table Schema's time type defaults to an ISO8601 time string, giving hh:mm:ss as its example.[[4]](https://specs.frictionlessdata.io/table-schema/)

### Use

Python's time.isoformat writes HH:MM:SS when the microsecond is 0.[[5]](https://docs.python.org/3/library/datetime.html) Python's time.isoformat writes HH:MM:SS.ffffff when the microsecond is not 0.[[5]](https://docs.python.org/3/library/datetime.html) PostgreSQL lists 04:05:06 among its ISO 8601 examples of time input.[[6]](https://www.postgresql.org/docs/current/datatype-datetime.html) PostgreSQL's time type runs from 00:00:00 to 24:00:00 with a resolution of 1 microsecond.[[6]](https://www.postgresql.org/docs/current/datatype-datetime.html) DuckDB's TIME type specifies the hour, minute, second and microsecond of a day.[[7]](https://duckdb.org/docs/current/sql/data_types/time.html) A column that mixes 10:30:00 with 10:30:00.250 may be one source writing whole and fractional seconds differently, so check for both before you fix a format string. (Meridian's view)

The General Transit Feed Specification writes times in the HH:MM:SS format and also accepts H:MM:SS.[[8]](https://gtfs.org/documentation/schedule/reference/) The General Transit Feed Specification enters a time after midnight on the service day as a value greater than 24:00:00, such as 25:35:00.[[8]](https://gtfs.org/documentation/schedule/reference/) Before casting a transit feed's times, look at the largest hour in the column and decide whether values past 24 should become a next-day time or stay as an offset from the service day. (Meridian's view)

Python's strptime makes the leading zero optional for %H, %M and %S.[[5]](https://docs.python.org/3/library/datetime.html) Python's datetime module does not support leap seconds.[[5]](https://docs.python.org/3/library/datetime.html) Decide before parsing what to do with 23:59:60 and 24:00:00, because a value one standard accepts can still be rejected by a parser. (Meridian's view)

Excel's TIMEVALUE function returns a decimal number from 0 to 0.99988426 for times from 0:00:00 to 23:59:59.[[9]](https://support.microsoft.com/en-us/office/timevalue-function-0b615c12-33d8-4431-bf3d-f3eb6d186645) When a time column from a spreadsheet arrives as a decimal between 0 and 1, treat it as a fraction of a day and convert it back before comparing it with text times. (Meridian's view)

DuckDB's documentation says the TIME type should only be used in rare cases, where the date part of the timestamp can be disregarded.[[7]](https://duckdb.org/docs/current/sql/data_types/time.html) Keep the date beside a time of day wherever the source offers it, since a bare time cannot be ordered across midnight. (Meridian's view)

## Sources

1. [24-hour clock](https://en.wikipedia.org/wiki/24-hour_clock) — secondary source
2. [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) — secondary source
3. [Date and Time on the Internet: Timestamps](https://www.rfc-editor.org/rfc/rfc3339) — standard
4. [Table Schema \| Data Package (v1)](https://specs.frictionlessdata.io/table-schema/) — standard
5. [datetime — Basic date and time types](https://docs.python.org/3/library/datetime.html) — documentation
6. [PostgreSQL: Documentation: 18: 8.5. Date/Time Types](https://www.postgresql.org/docs/current/datatype-datetime.html) — documentation
7. [Time Types](https://duckdb.org/docs/current/sql/data_types/time.html) — documentation
8. [Reference - General Transit Feed Specification](https://gtfs.org/documentation/schedule/reference/) — documentation
9. [TIMEVALUE function \| Microsoft Support](https://support.microsoft.com/en-us/office/timevalue-function-0b615c12-33d8-4431-bf3d-f3eb6d186645) — documentation
