time point class

class Time

The turbo::Time class represents a specific instant in time.

Arithmetic operators are provided for naturally expressing time calculations. Instances are created using turbo::time_now() and the turbo::From*() factory functions that accept the gamut of other time representations. Formatting and parsing functions are provided for conversion to and from strings. turbo::Time should be passed by value rather than const reference.

turbo::Time assumes there are 60 seconds in a minute, which means the underlying time scales must be “smeared” to eliminate leap seconds. See https://developers.google.com/time/smear.

Even though turbo::Time supports a wide range of timestamps, exercise caution when using values in the distant past. turbo::Time uses the Proleptic Gregorian calendar, which extends the Gregorian calendar backward to dates before its introduction in 1582. See https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar for more information. Use the ICU calendar classes to convert a date in some other calendar (http://userguide.icu-project.org/datetime/calendar).

Similarly, standardized time zones are a reasonably recent innovation, with the Greenwich prime meridian being established in 1884. The TZ database itself does not profess accurate offsets for timestamps prior to 1970. The breakdown of future timestamps is subject to the whim of regional governments.

The turbo::Time class represents an instant in time as a count of clock ticks of some granularity (resolution) from some starting point (epoch).

turbo::Time uses a resolution that is high enough to avoid loss in precision, and a range that is wide enough to avoid overflow, when converting between tick counts in most Google time scales (i.e., resolution of at least one nanosecond, and range +/-100 billion years). Conversions between the time scales are performed by truncating (towards negative infinity) to the nearest representable point.

Examples:

turbo::Time t1 = ...;
turbo::Time t2 = t1 + turbo::Duration::minutes(2);
turbo::Duration d = t2 - t1;  // == turbo::Duration::minutes(2)

Public Functions

std::string to_string(std::string_view format, TimeZone tz) const

Formats the given turbo::Time in the turbo::TimeZone according to the provided format string.

Uses strftime()-like formatting options, with the following extensions:

  • Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm)

  • E*z - Full-resolution numeric UTC offset (+hh:mm:ss or -hh:mm:ss)

  • E#S - seconds with # digits of fractional precision

  • E*S - seconds with full fractional precision (a literal ‘*’)

  • E#f - Fractional seconds with # digits of precision

  • E*f - Fractional seconds with full precision (a literal ‘*’)

  • E4Y - Four-character years (-999 … -001, 0000, 0001 … 9999)

  • ET - The RFC3339 “date-time” separator “T” Note that E0S behaves like S, and E0f produces no characters. In contrast E*f always produces at least one digit, which may be ‘0’. Note that Y produces as many characters as it takes to fully render the year. A year outside of [-999:9999] when formatted with E4Y will produce more than four characters, just like Y. We recommend that format strings include the UTC offset (z, Ez, or E*z) so that the result uniquely identifies a time instant. Example:

    turbo::CivilSecond cs(2013, 1, 2, 3, 4, 5);
    turbo::Time t = turbo::Time::from_civil(cs, lax);
    std::string f = turbo::format_time("%H:%M:%S", t, lax);  // "03:04:05"
    f = turbo::format_time("%H:%M:%E3S", t, lax);  // "03:04:05.000"
    
    Note: If the given turbo::Time is turbo::Time::infinite_future(), the returned string will be exactly “infinite-future”. If the given turbo::Time is turbo::Time::infinite_past(), the returned string will be exactly “infinite-past”. In both cases the given format string and turbo::TimeZone are ignored. Example:
    turbo::Time t = turbo::Time::infinite_future();
    std::string f = turbo::format_time("%H:%M:%S", t, lax);  // "infinite-future"
    

Parameters:
  • format

  • t

  • tz

Returns:

bool parse_time(std::string_view format, std::string_view input, std::string *err)

Parses an input string according to the provided format string and returns the corresponding turbo::Time.

Uses strftime()-like formatting options, with the same extensions as format_time(), but with the exceptions that E#S is interpreted as E*S, and E#f as E*f. Ez and E*z also accept the same inputs, which (along with z) includes ‘z’ and ‘Z’ as synonyms for +00:00. ET accepts either ‘T’ or ‘t’. Y consumes as many numeric characters as it can, so the matching data should always be terminated with a non-numeric. E4Y always consumes exactly four characters, including any sign. Unspecified fields are taken from the default date and time of … “1970-01-01 00:00:00.0 +0000” For example, parsing a string of “15:45” (H:M) will return an turbo::Time that represents “1970-01-01 15:45:00.0 +0000”. Note that since parse_time() returns time instants, it makes the most sense to parse fully-specified date/time strings that include a UTC offset (z, Ez, or E*z). Note also that turbo::parse_time() only heeds the fields year, month, day, hour, minute, (fractional) second, and UTC offset. Other fields, like weekday (a or A), while parsed for syntactic validity, are ignored in the conversion. Date and time fields that are out-of-range will be treated as errors rather than normalizing them like turbo::CivilSecond does. For example, it is an error to parse the date “Oct 32, 2013” because 32 is out of range. A leap second of “:60” is normalized to “:00” of the following minute with fractional seconds discarded. The following table shows how the given seconds and subseconds will be parsed: “59.x” -> 59.x // exact “60.x” -> 00.0 // normalized “00.x” -> 00.x // exact Errors are indicated by returning false and assigning an error message to the “err” out param if it is non-null. Note: If the input string is exactly “infinite-future”, the returned turbo::Time will be turbo::Time::infinite_future() and true will be returned. If the input string is “infinite-past”, the returned turbo::Time will be turbo::Time::infinite_past() and true will be returned.

Parameters:
  • format

  • input

  • time

  • err

Returns:

bool parse_time(std::string_view format, std::string_view input, TimeZone tz, std::string *err)

Like parse_time() above, but if the format string does not contain a UTC offset specification (z/Ez/E*z) then the input is interpreted in the given TimeZone.

This means that the input, by itself, does not identify a unique instant. Being time-zone dependent, it also admits the possibility of ambiguity or non-existence, in which case the “pre” time (as defined by TimeZone::TimeInfo) is returned. For these reasons we recommend that all date/time strings include a UTC offset so they’re context independent. Example:

turbo::Time t;
std::string err;
bool b = turbo::parse_time("%Y-%m-%d %H:%M:%S", "2013-10-19 12:34:56",
                           lax, &t, &err);
// b == true && err.empty() && t == 2013-10-19 12:34:56 -0700

Parameters:
  • format

  • input

  • tz

  • time

  • err

Returns:

Public Static Functions

static inline Time from_date_time(int64_t year, int mon, int day, int hour, int min, int sec, TimeZone tz)

similar to convert_date_time() but returns the “pre” turbo::Time (the unique result, or the instant that is correct using the pre-transition offset (as if the transition never happened)).

Deprecated. Use turbo::Time::from_civil(CivilSecond, TimeZone). Note that the behavior of from_civil() differs from from_date_time() for skipped civil times. If you care about that see turbo::TimeZone::At(turbo::CivilSecond). Example:

turbo::Time t = turbo::from_date_time(2017, 9, 26, 9, 30, 0, lax);
// t = 2017-09-26 09:30:00 -0700

See also

convert_date_time()

Parameters:
  • year

  • mon

  • day

  • hour

  • min

  • sec

  • tz

Returns: