Skip to content
Greg Miller edited this page Mar 11, 2016 · 7 revisions

What is an absolute time?

Absolute time uniquely and universally represents a specific instant in time. It has no notion of calendars, or dates, or times of day. Instead, it is a measure of the passage of real time, typically as a simple count of ticks since some epoch. Absolute times are independent of all time zones and do not suffer from human-imposed complexities such as daylight-saving time (DST). Many C++ types exist to represent absolute times, classically time_t and more recently std::chrono::time_point.

What is a civil time?

Civil time is the legally recognized representation of time for ordinary affairs (cf. http://www.merriam-webster.com/dictionary/civil). It is a human-scale representation of time that consists of the six fields — year, month, day, hour, minute, and second (sometimes shortened to "YMDHMS") — and it follows the rules of the Proleptic Gregorian Calendar, with 24-hour days divided into 60-minute hours and 60-second minutes. Civil times are independent of all time zones and do not suffer from human-imposed complexities such as daylight-saving time (DST).

What is a time zone?

Time zones are geo-political regions within which human-defined rules are shared to convert between the absolute-time and civil-time domains. A time zone's rules include things like the region's offset from the UTC time standard, daylight-saving adjustments, and short abbreviation strings. Time zones often have a history of disparate rules that apply only for certain periods, because the rules may change at the whim of a region's local government. For this reason, time-zone rules are usually compiled into data snapshots that are used at runtime to perform conversions between absolute and civil times. Time zones are named using names defined by the IANA time zone database. Examples of time zone names are

  • "America/Los_Angeles"
  • "Europe/London"
  • "Australia/Sydney"
  • "Asia/Tokyo"

Note that "PST" and "EDT" are abbreviations, not time zone names.

How do I represent a "date"?

Date's (i.e., a year, month, and day following the rules of the Gregorian calendar) are the most common representation of civil time. In the CCTZ civil-time library dates are represented by instances of thecctz::civil_day class. For example:

#include "civil_time.h"
cctz::civil_day april_fools(2016, 4, 1);
cctz::civil_day tax_day = april_fools + 14;

How do I get the offset for a time zone?

Well-written time code should never care about UTC offsets. Seriously. Time-zone offsets can and do change, and they are only valid at particular times. Moreover, there is nothing correct that can be done with a UTC offset other than print it, and for this there is the cctz::format() function. So, the answer to the question is that you should never care about the UTC offset.

Oh, come on. Just tell me how to get the offset, please.

OK, fine. We're aware that there are some regrettable APIs that require UTC offsets. In these cases you can get the offset from the cctz::time_zone::absolute_lookup struct. But note that the offset is only valid for the specific time point that was used to look it up.

How do I compute a "local" time point?

There is no such thing as "local" absolute time, so you cannot compute a local std::chrono::time_point. However, it is not uncommon to see legacy code that attempts this in order to make the absolute time in UTC appear to be in some other time zone. This mistaken technique is called "epoch shifting". It is done by finding a time-zone offset and adding that offset to, or subtracting it from, an absolute time. The problem is that simply produces a different point in time, not a "local" version of the absolute time. This strategy throws away information, may not be reversible, can be wrong near offset transitions, and should always be avoided. Any library that requires or encourages this should be strictly avoided. For more information about epoch shifting, see the video talk from CppCon 2015.

Fortunately, epoch shifting is never needed when using a proper time-zone library such as the one provided with CCTZ. Anywhere you think you need an offset, you really need a cctz::time_zone. If you follow the concepts and APIs provided by CCTZ, you'll find that you never need to compute with UTC offsets and your code is much simpler.

Rule of thumb: never do arithmetic with a UTC offset.

What exactly is UTC?

UTC is the international standard for civil time. It is defined in terms of the six civil-time fields — year, month, day, hour, minute, second — that follow the rules of the Gregorian calendar. Local times around the world are defined as offsets from this UTC time standard. For example, a time zone with a 1-hour offset from UTC is one civil hour ahead of UTC.

Where is the data used by the CCTZ time-zone library?

The CCTZ time-zone library uses the compiled IANA time zone database files that exist on the system. These are typically found in /usr/share/zoneinfo or in the directory named in the TZDIR environment variable.

Clone this wiki locally