aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/cctz/README.md
blob: baf079b20eaa36121d6fc5cca511a2b18ba92ca6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
This is not an official Google product. 
 
# Overview 
 
CCTZ contains two libraries that cooperate with `<chrono>` to give C++ 
programmers all the necessary tools for computing with dates, times, and time 
zones in a simple and correct manner. The libraries in CCTZ are: 
 
*   **The Civil-Time Library** &mdash; This is a header-only library that 
    supports computing with human-scale time, such as dates (which are 
    represented by the `cctz::civil_day` class). This library is declared in 
    [`include/cctz/civil_time.h`](https://github.com/google/cctz/blob/master/include/cctz/civil_time.h). 
*   **The Time-Zone Library** &mdash; This library uses the IANA time zone 
    database that is installed on the system to convert between *absolute time* 
    and *civil time*. This library is declared in 
    [`include/cctz/time_zone.h`](https://github.com/google/cctz/blob/master/include/cctz/time_zone.h). 
 
These libraries are currently known to work on **Linux**, **Mac OS X**, and 
**Android**. 
 
They will also work on **Windows** if you install the zoneinfo files. We are 
interested, though, in an implementation of the cctz::TimeZoneIf interface that 
calls the Windows time APIs instead. Please contact us if you're interested in 
contributing. 
 
# Getting Started 
 
CCTZ is best built and tested using the [Bazel](https://bazel.io) build system 
and the [Google Test](https://github.com/google/googletest) framework. (There is 
also a simple [`Makefile`](https://github.com/google/cctz/blob/master/Makefile) 
and a 
[`CMakeLists.txt`](https://github.com/google/cctz/blob/master/CMakeLists.txt) 
that should work if you're unable to use Bazel.) 
 
1.  Download/install 
    [Bazel](https://docs.bazel.build/versions/master/install.html) 
2.  Get the cctz source: `git clone https://github.com/google/cctz.git` then `cd 
    cctz` 
3.  Build cctz and run the tests: `bazel test :all` 
 
With CMake: 
 
1.  Make sure you have CMake >= 2.8.12 installed. 
2.  Get the cctz source: `git clone https://github.com/google/cctz.git` then `cd 
    cctz`. 
3.  Build cctz so that is can be used by shared libraries and run the tests (use 
    `-DBUILD_TESTING=OFF` to skip the tests): 
 
        mkdir mybuild 
        cd mybuild 
        cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON .. 
        cmake --build . --config Release 
        ctest 
        cmake --build . --config Release --target install 
 
4.  Use in your CMake-based project with: 
 
    ```cmake 
    find_package(cctz REQUIRED) 
    add_executable(mytarget file.cc) 
    target_link_libraries(mytarget cctz::cctz) 
    ``` 
 
Note: When using CCTZ in your own project, you might find it easiest to compile 
the sources using your existing build system. 
 
Next Steps: 
 
1.  See the documentation for the libraries in CCTZ: 
    *   Civil Time: 
        [`include/cctz/civil_time.h`](https://github.com/google/cctz/blob/master/include/cctz/civil_time.h) 
    *   Time Zone: 
        [`include/cctz/time_zone.h`](https://github.com/google/cctz/blob/master/include/cctz/time_zone.h) 
2.  Look at the examples in https://github.com/google/cctz/tree/master/examples 
3.  Join our mailing list to ask questions and keep informed of changes: 
    *   https://groups.google.com/forum/#!forum/cctz 
 
# Fundamental Concepts 
 
*[The concepts presented here describe general truths about the problem domain 
and are library and language agnostic. An understanding of these concepts helps 
the programmer correctly reason about even the most-complicated time-programming 
challenges and produce the simplest possible solutions.]* 
 
There are two main ways to think about time in a computer program: as *absolute 
time*, and as *civil time*. Both have their uses and it is important to 
understand when each is appropriate. Absolute and civil times may be converted 
back and forth using a *time zone* &mdash; this is the only way to correctly 
convert between them. Let us now look more deeply at the three main concepts of 
time programming: Absolute Time, Civil Time, and Time Zone. 
 
*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`. 
 
*Civil time* is the legally recognized representation of time for ordinary 
affairs (cf. https://www.merriam-webster.com/dictionary/civil). It is a 
human-scale representation of time that consists of the six fields &mdash; year, 
month, day, hour, minute, and second (sometimes shortened to "YMDHMS") &mdash; 
and it follows the rules of the Proleptic Gregorian Calendar, with 24-hour days 
divided into 60-minute hours and 60-second minutes. Like absolute times, civil 
times are also independent of all time zones and their related complexities 
(e.g., DST). While `std::tm` contains the six civil-time fields (YMDHMS), plus a 
few more, it does not have behavior to enforce the rules of civil time. 
 
*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. There is 
currently no C++ standard library supporting arbitrary time zones. 
 
In order for programmers to reason about and program applications that correctly 
deal with these concepts, they must have a library that correctly implements the 
above concepts. CCTZ adds to the existing C++11 `<chrono>` library to fully 
implement the above concepts. 
 
*   Absolute time &mdash; This is implemented by the existing C++11 
    [`<chrono>`](https://en.cppreference.com/w/cpp/chrono) library without 
    modification. For example, an absolute point in time is represented by a 
    `std::chrono::time_point`. 
*   Civil time &mdash; This is implemented by the 
    [`include/cctz/civil_time.h`](https://github.com/google/cctz/blob/master/include/cctz/civil_time.h) 
    library that is provided as part of CCTZ. For example, a "date" is 
    represented by a `cctz::civil_day`. 
*   Time zone &mdash; This is implemented by the 
    [`include/cctz/time_zone.h`](https://github.com/google/cctz/blob/master/include/cctz/time_zone.h) 
    library that is provided as part of CCTZ. For example, a time zone is 
    represented by an instance of the class `cctz::time_zone`. 
 
# Examples 
 
## Hello February 2016 
 
This "hello world" example uses a for-loop to iterate the days from the first of 
February until the month of March. Each day is streamed to output, and if the 
day happens to be the 29th, we also output the day of the week. 
 
``` 
#include <iostream> 
#include "cctz/civil_time.h" 
 
int main() { 
  for (cctz::civil_day d(2016, 2, 1); d < cctz::civil_month(2016, 3); ++d) { 
    std::cout << "Hello " << d; 
    if (d.day() == 29) { 
      std::cout << " <- leap day is a " << cctz::get_weekday(d); 
    } 
    std::cout << "\n"; 
  } 
} 
``` 
 
The output of the above program is 
 
``` 
Hello 2016-02-01 
Hello 2016-02-02 
Hello 2016-02-03 
[...] 
Hello 2016-02-27 
Hello 2016-02-28 
Hello 2016-02-29 <- leap day is a Monday 
``` 
 
## One giant leap 
 
This example shows how to use all three libraries (`<chrono>`, civil time, and 
time zone) together. In this example, we know that viewers in New York watched 
Neil Armstrong's first walk on the moon on July 20, 1969 at 10:56 PM. But we'd 
like to see what time it was for our friend watching in Sydney, Australia. 
 
``` 
#include <iostream> 
#include "cctz/civil_time.h" 
#include "cctz/time_zone.h" 
 
int main() { 
  cctz::time_zone nyc; 
  cctz::load_time_zone("America/New_York", &nyc); 
 
  // Converts the input civil time in NYC to an absolute time. 
  const auto moon_walk = 
    cctz::convert(cctz::civil_second(1969, 7, 20, 22, 56, 0), nyc); 
 
  std::cout << "Moon walk in NYC: " 
            << cctz::format("%Y-%m-%d %H:%M:%S %Ez\n", moon_walk, nyc); 
 
  cctz::time_zone syd; 
  if (!cctz::load_time_zone("Australia/Sydney", &syd)) return -1; 
  std::cout << "Moon walk in SYD: " 
            << cctz::format("%Y-%m-%d %H:%M:%S %Ez\n", moon_walk, syd); 
} 
``` 
 
The output of the above program is 
 
``` 
Moon walk in NYC: 1969-07-20 22:56:00 -04:00 
Moon walk in SYD: 1969-07-21 12:56:00 +10:00 
``` 
 
This example shows that the absolute time (the `std::chrono::time_point`) of the 
first walk on the moon is the same no matter the time zone of the viewer (the 
same time point is used in both calls to `format()`). The only difference is the 
time zone in which the `moon_walk` time point is rendered. And in this case we 
can see that our friend in Sydney was probably eating lunch while watching that 
historic event. 
 
# References 
 
*   CCTZ [FAQ](https://github.com/google/cctz/wiki/FAQ) 
*   See also the [Time Programming Fundamentals](https://youtu.be/2rnIHsqABfM) 
    talk from CppCon 2015 ([slides available here](https://goo.gl/ofof4N)). This 
    talk mostly describes the older CCTZ v1 API, but the *concepts* are the 
    same. 
*   ISO C++ proposal to standardize the Civil-Time Library: 
    https://github.com/devjgm/papers/blob/master/d0215r1.md 
*   ISO C++ proposal to standardize the Time-Zone Library: 
    https://github.com/devjgm/papers/blob/master/d0216r1.md