00001 // Copyright 2018 The Abseil Authors. 00002 // 00003 // Licensed under the Apache License, Version 2.0 (the "License"); 00004 // you may not use this file except in compliance with the License. 00005 // You may obtain a copy of the License at 00006 // 00007 // https://www.apache.org/licenses/LICENSE-2.0 00008 // 00009 // Unless required by applicable law or agreed to in writing, software 00010 // distributed under the License is distributed on an "AS IS" BASIS, 00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 // See the License for the specific language governing permissions and 00013 // limitations under the License. 00014 // 00015 // ----------------------------------------------------------------------------- 00016 // File: civil_time.h 00017 // ----------------------------------------------------------------------------- 00018 // 00019 // This header file defines abstractions for computing with "civil time". 00020 // The term "civil time" refers to the legally recognized human-scale time 00021 // that is represented by the six fields `YYYY-MM-DD hh:mm:ss`. A "date" 00022 // is perhaps the most common example of a civil time (represented here as 00023 // an `absl::CivilDay`). 00024 // 00025 // Modern-day civil time follows the Gregorian Calendar and is a 00026 // time-zone-independent concept: a civil time of "2015-06-01 12:00:00", for 00027 // example, is not tied to a time zone. Put another way, a civil time does not 00028 // map to a unique point in time; a civil time must be mapped to an absolute 00029 // time *through* a time zone. 00030 // 00031 // Because a civil time is what most people think of as "time," it is common to 00032 // map absolute times to civil times to present to users. 00033 // 00034 // Time zones define the relationship between absolute and civil times. Given an 00035 // absolute or civil time and a time zone, you can compute the other time: 00036 // 00037 // Civil Time = F(Absolute Time, Time Zone) 00038 // Absolute Time = G(Civil Time, Time Zone) 00039 // 00040 // The Abseil time library allows you to construct such civil times from 00041 // absolute times; consult time.h for such functionality. 00042 // 00043 // This library provides six classes for constructing civil-time objects, and 00044 // provides several helper functions for rounding, iterating, and performing 00045 // arithmetic on civil-time objects, while avoiding complications like 00046 // daylight-saving time (DST): 00047 // 00048 // * `absl::CivilSecond` 00049 // * `absl::CivilMinute` 00050 // * `absl::CivilHour` 00051 // * `absl::CivilDay` 00052 // * `absl::CivilMonth` 00053 // * `absl::CivilYear` 00054 // 00055 // Example: 00056 // 00057 // // Construct a civil-time object for a specific day 00058 // const absl::CivilDay cd(1969, 07, 20); 00059 // 00060 // // Construct a civil-time object for a specific second 00061 // const absl::CivilSecond cd(2018, 8, 1, 12, 0, 1); 00062 // 00063 // Note: In C++14 and later, this library is usable in a constexpr context. 00064 // 00065 // Example: 00066 // 00067 // // Valid in C++14 00068 // constexpr absl::CivilDay cd(1969, 07, 20); 00069 00070 #ifndef ABSL_TIME_CIVIL_TIME_H_ 00071 #define ABSL_TIME_CIVIL_TIME_H_ 00072 00073 #include <string> 00074 00075 #include "absl/strings/string_view.h" 00076 #include "absl/time/internal/cctz/include/cctz/civil_time.h" 00077 00078 namespace absl { 00079 00080 namespace time_internal { 00081 struct second_tag : cctz::detail::second_tag {}; 00082 struct minute_tag : second_tag, cctz::detail::minute_tag {}; 00083 struct hour_tag : minute_tag, cctz::detail::hour_tag {}; 00084 struct day_tag : hour_tag, cctz::detail::day_tag {}; 00085 struct month_tag : day_tag, cctz::detail::month_tag {}; 00086 struct year_tag : month_tag, cctz::detail::year_tag {}; 00087 } // namespace time_internal 00088 00089 // ----------------------------------------------------------------------------- 00090 // CivilSecond, CivilMinute, CivilHour, CivilDay, CivilMonth, CivilYear 00091 // ----------------------------------------------------------------------------- 00092 // 00093 // Each of these civil-time types is a simple value type with the same 00094 // interface for construction and the same six accessors for each of the civil 00095 // time fields (year, month, day, hour, minute, and second, aka YMDHMS). These 00096 // classes differ only in their alignment, which is indicated by the type name 00097 // and specifies the field on which arithmetic operates. 00098 // 00099 // CONSTRUCTION 00100 // 00101 // Each of the civil-time types can be constructed in two ways: by directly 00102 // passing to the constructor up to six integers representing the YMDHMS fields, 00103 // or by copying the YMDHMS fields from a differently aligned civil-time type. 00104 // Omitted fields are assigned their minimum valid value. Hours, minutes, and 00105 // seconds will be set to 0, month and day will be set to 1. Since there is no 00106 // minimum year, the default is 1970. 00107 // 00108 // Examples: 00109 // 00110 // absl::CivilDay default_value; // 1970-01-01 00:00:00 00111 // 00112 // absl::CivilDay a(2015, 2, 3); // 2015-02-03 00:00:00 00113 // absl::CivilDay b(2015, 2, 3, 4, 5, 6); // 2015-02-03 00:00:00 00114 // absl::CivilDay c(2015); // 2015-01-01 00:00:00 00115 // 00116 // absl::CivilSecond ss(2015, 2, 3, 4, 5, 6); // 2015-02-03 04:05:06 00117 // absl::CivilMinute mm(ss); // 2015-02-03 04:05:00 00118 // absl::CivilHour hh(mm); // 2015-02-03 04:00:00 00119 // absl::CivilDay d(hh); // 2015-02-03 00:00:00 00120 // absl::CivilMonth m(d); // 2015-02-01 00:00:00 00121 // absl::CivilYear y(m); // 2015-01-01 00:00:00 00122 // 00123 // m = absl::CivilMonth(y); // 2015-01-01 00:00:00 00124 // d = absl::CivilDay(m); // 2015-01-01 00:00:00 00125 // hh = absl::CivilHour(d); // 2015-01-01 00:00:00 00126 // mm = absl::CivilMinute(hh); // 2015-01-01 00:00:00 00127 // ss = absl::CivilSecond(mm); // 2015-01-01 00:00:00 00128 // 00129 // Each civil-time class is aligned to the civil-time field indicated in the 00130 // class's name after normalization. Alignment is performed by setting all the 00131 // inferior fields to their minimum valid value (as described above). The 00132 // following are examples of how each of the six types would align the fields 00133 // representing November 22, 2015 at 12:34:56 in the afternoon. (Note: the 00134 // string format used here is not important; it's just a shorthand way of 00135 // showing the six YMDHMS fields.) 00136 // 00137 // absl::CivilSecond : 2015-11-22 12:34:56 00138 // absl::CivilMinute : 2015-11-22 12:34:00 00139 // absl::CivilHour : 2015-11-22 12:00:00 00140 // absl::CivilDay : 2015-11-22 00:00:00 00141 // absl::CivilMonth : 2015-11-01 00:00:00 00142 // absl::CivilYear : 2015-01-01 00:00:00 00143 // 00144 // Each civil-time type performs arithmetic on the field to which it is 00145 // aligned. This means that adding 1 to an absl::CivilDay increments the day 00146 // field (normalizing as necessary), and subtracting 7 from an absl::CivilMonth 00147 // operates on the month field (normalizing as necessary). All arithmetic 00148 // produces a valid civil time. Difference requires two similarly aligned 00149 // civil-time objects and returns the scalar answer in units of the objects' 00150 // alignment. For example, the difference between two absl::CivilHour objects 00151 // will give an answer in units of civil hours. 00152 // 00153 // ALIGNMENT CONVERSION 00154 // 00155 // The alignment of a civil-time object cannot change, but the object may be 00156 // used to construct a new object with a different alignment. This is referred 00157 // to as "realigning". When realigning to a type with the same or more 00158 // precision (e.g., absl::CivilDay -> absl::CivilSecond), the conversion may be 00159 // performed implicitly since no information is lost. However, if information 00160 // could be discarded (e.g., CivilSecond -> CivilDay), the conversion must 00161 // be explicit at the call site. 00162 // 00163 // Examples: 00164 // 00165 // void UseDay(absl::CivilDay day); 00166 // 00167 // absl::CivilSecond cs; 00168 // UseDay(cs); // Won't compile because data may be discarded 00169 // UseDay(absl::CivilDay(cs)); // OK: explicit conversion 00170 // 00171 // absl::CivilDay cd; 00172 // UseDay(cd); // OK: no conversion needed 00173 // 00174 // absl::CivilMonth cm; 00175 // UseDay(cm); // OK: implicit conversion to absl::CivilDay 00176 // 00177 // NORMALIZATION 00178 // 00179 // Normalization takes invalid values and adjusts them to produce valid values. 00180 // Within the civil-time library, integer arguments passed to the Civil* 00181 // constructors may be out-of-range, in which case they are normalized by 00182 // carrying overflow into a field of courser granularity to produce valid 00183 // civil-time objects. This normalization enables natural arithmetic on 00184 // constructor arguments without worrying about the field's range. 00185 // 00186 // Examples: 00187 // 00188 // // Out-of-range; normalized to 2016-11-01 00189 // absl::CivilDay d(2016, 10, 32); 00190 // // Out-of-range, negative: normalized to 2016-10-30T23 00191 // absl::CivilHour h1(2016, 10, 31, -1); 00192 // // Normalization is cumulative: normalized to 2016-10-30T23 00193 // absl::CivilHour h2(2016, 10, 32, -25); 00194 // 00195 // Note: If normalization is undesired, you can signal an error by comparing 00196 // the constructor arguments to the normalized values returned by the YMDHMS 00197 // properties. 00198 // 00199 // COMPARISON 00200 // 00201 // Comparison between civil-time objects considers all six YMDHMS fields, 00202 // regardless of the type's alignment. Comparison between differently aligned 00203 // civil-time types is allowed. 00204 // 00205 // Examples: 00206 // 00207 // absl::CivilDay feb_3(2015, 2, 3); // 2015-02-03 00:00:00 00208 // absl::CivilDay mar_4(2015, 3, 4); // 2015-03-04 00:00:00 00209 // // feb_3 < mar_4 00210 // // absl::CivilYear(feb_3) == absl::CivilYear(mar_4) 00211 // 00212 // absl::CivilSecond feb_3_noon(2015, 2, 3, 12, 0, 0); // 2015-02-03 12:00:00 00213 // // feb_3 < feb_3_noon 00214 // // feb_3 == absl::CivilDay(feb_3_noon) 00215 // 00216 // // Iterates all the days of February 2015. 00217 // for (absl::CivilDay d(2015, 2, 1); d < absl::CivilMonth(2015, 3); ++d) { 00218 // // ... 00219 // } 00220 // 00221 // ARITHMETIC 00222 // 00223 // Civil-time types support natural arithmetic operators such as addition, 00224 // subtraction, and difference. Arithmetic operates on the civil-time field 00225 // indicated in the type's name. Difference operators require arguments with 00226 // the same alignment and return the answer in units of the alignment. 00227 // 00228 // Example: 00229 // 00230 // absl::CivilDay a(2015, 2, 3); 00231 // ++a; // 2015-02-04 00:00:00 00232 // --a; // 2015-02-03 00:00:00 00233 // absl::CivilDay b = a + 1; // 2015-02-04 00:00:00 00234 // absl::CivilDay c = 1 + b; // 2015-02-05 00:00:00 00235 // int n = c - a; // n = 2 (civil days) 00236 // int m = c - absl::CivilMonth(c); // Won't compile: different types. 00237 // 00238 // ACCESSORS 00239 // 00240 // Each civil-time type has accessors for all six of the civil-time fields: 00241 // year, month, day, hour, minute, and second. 00242 // 00243 // civil_year_t year() 00244 // int month() 00245 // int day() 00246 // int hour() 00247 // int minute() 00248 // int second() 00249 // 00250 // Recall that fields inferior to the type's aligment will be set to their 00251 // minimum valid value. 00252 // 00253 // Example: 00254 // 00255 // absl::CivilDay d(2015, 6, 28); 00256 // // d.year() == 2015 00257 // // d.month() == 6 00258 // // d.day() == 28 00259 // // d.hour() == 0 00260 // // d.minute() == 0 00261 // // d.second() == 0 00262 // 00263 // CASE STUDY: Adding a month to January 31. 00264 // 00265 // One of the classic questions that arises when considering a civil time 00266 // library (or a date library or a date/time library) is this: 00267 // "What is the result of adding a month to January 31?" 00268 // This is an interesting question because it is unclear what is meant by a 00269 // "month", and several different answers are possible, depending on context: 00270 // 00271 // 1. March 3 (or 2 if a leap year), if "add a month" means to add a month to 00272 // the current month, and adjust the date to overflow the extra days into 00273 // March. In this case the result of "February 31" would be normalized as 00274 // within the civil-time library. 00275 // 2. February 28 (or 29 if a leap year), if "add a month" means to add a 00276 // month, and adjust the date while holding the resulting month constant. 00277 // In this case, the result of "February 31" would be truncated to the last 00278 // day in February. 00279 // 3. An error. The caller may get some error, an exception, an invalid date 00280 // object, or perhaps return `false`. This may make sense because there is 00281 // no single unambiguously correct answer to the question. 00282 // 00283 // Practically speaking, any answer that is not what the programmer intended 00284 // is the wrong answer. 00285 // 00286 // The Abseil time library avoids this problem by making it impossible to 00287 // ask ambiguous questions. All civil-time objects are aligned to a particular 00288 // civil-field boundary (such as aligned to a year, month, day, hour, minute, 00289 // or second), and arithmetic operates on the field to which the object is 00290 // aligned. This means that in order to "add a month" the object must first be 00291 // aligned to a month boundary, which is equivalent to the first day of that 00292 // month. 00293 // 00294 // Of course, there are ways to compute an answer the question at hand using 00295 // this Abseil time library, but they require the programmer to be explicit 00296 // about the answer they expect. To illustrate, let's see how to compute all 00297 // three of the above possible answers to the question of "Jan 31 plus 1 00298 // month": 00299 // 00300 // Example: 00301 // 00302 // const absl::CivilDay d(2015, 1, 31); 00303 // 00304 // // Answer 1: 00305 // // Add 1 to the month field in the constructor, and rely on normalization. 00306 // const auto normalized = absl::CivilDay(d.year(), d.month() + 1, d.day()); 00307 // // normalized == 2015-03-03 (aka Feb 31) 00308 // 00309 // // Answer 2: 00310 // // Add 1 to month field, capping to the end of next month. 00311 // const auto next_month = absl::CivilMonth(d) + 1; 00312 // const auto last_day_of_next_month = absl::CivilDay(next_month + 1) - 1; 00313 // const auto capped = std::min(normalized, last_day_of_next_month); 00314 // // capped == 2015-02-28 00315 // 00316 // // Answer 3: 00317 // // Signal an error if the normalized answer is not in next month. 00318 // if (absl::CivilMonth(normalized) != next_month) { 00319 // // error, month overflow 00320 // } 00321 // 00322 using CivilSecond = 00323 time_internal::cctz::detail::civil_time<time_internal::second_tag>; 00324 using CivilMinute = 00325 time_internal::cctz::detail::civil_time<time_internal::minute_tag>; 00326 using CivilHour = 00327 time_internal::cctz::detail::civil_time<time_internal::hour_tag>; 00328 using CivilDay = 00329 time_internal::cctz::detail::civil_time<time_internal::day_tag>; 00330 using CivilMonth = 00331 time_internal::cctz::detail::civil_time<time_internal::month_tag>; 00332 using CivilYear = 00333 time_internal::cctz::detail::civil_time<time_internal::year_tag>; 00334 00335 // civil_year_t 00336 // 00337 // Type alias of a civil-time year value. This type is guaranteed to (at least) 00338 // support any year value supported by `time_t`. 00339 // 00340 // Example: 00341 // 00342 // absl::CivilSecond cs = ...; 00343 // absl::civil_year_t y = cs.year(); 00344 // cs = absl::CivilSecond(y, 1, 1, 0, 0, 0); // CivilSecond(CivilYear(cs)) 00345 // 00346 using civil_year_t = time_internal::cctz::year_t; 00347 00348 // civil_diff_t 00349 // 00350 // Type alias of the difference between two civil-time values. 00351 // This type is used to indicate arguments that are not 00352 // normalized (such as parameters to the civil-time constructors), the results 00353 // of civil-time subtraction, or the operand to civil-time addition. 00354 // 00355 // Example: 00356 // 00357 // absl::civil_diff_t n_sec = cs1 - cs2; // cs1 == cs2 + n_sec; 00358 // 00359 using civil_diff_t = time_internal::cctz::diff_t; 00360 00361 // Weekday::monday, Weekday::tuesday, Weekday::wednesday, Weekday::thursday, 00362 // Weekday::friday, Weekday::saturday, Weekday::sunday 00363 // 00364 // The Weekday enum class represents the civil-time concept of a "weekday" with 00365 // members for all days of the week. 00366 // 00367 // absl::Weekday wd = absl::Weekday::thursday; 00368 // 00369 using Weekday = time_internal::cctz::weekday; 00370 00371 // GetWeekday() 00372 // 00373 // Returns the absl::Weekday for the given absl::CivilDay. 00374 // 00375 // Example: 00376 // 00377 // absl::CivilDay a(2015, 8, 13); 00378 // absl::Weekday wd = absl::GetWeekday(a); // wd == absl::Weekday::thursday 00379 // 00380 inline Weekday GetWeekday(CivilDay cd) { 00381 return time_internal::cctz::get_weekday(cd); 00382 } 00383 00384 // NextWeekday() 00385 // PrevWeekday() 00386 // 00387 // Returns the absl::CivilDay that strictly follows or precedes a given 00388 // absl::CivilDay, and that falls on the given absl::Weekday. 00389 // 00390 // Example, given the following month: 00391 // 00392 // August 2015 00393 // Su Mo Tu We Th Fr Sa 00394 // 1 00395 // 2 3 4 5 6 7 8 00396 // 9 10 11 12 13 14 15 00397 // 16 17 18 19 20 21 22 00398 // 23 24 25 26 27 28 29 00399 // 30 31 00400 // 00401 // absl::CivilDay a(2015, 8, 13); 00402 // // absl::GetWeekday(a) == absl::Weekday::thursday 00403 // absl::CivilDay b = absl::NextWeekday(a, absl::Weekday::thursday); 00404 // // b = 2015-08-20 00405 // absl::CivilDay c = absl::PrevWeekday(a, absl::Weekday::thursday); 00406 // // c = 2015-08-06 00407 // 00408 // absl::CivilDay d = ... 00409 // // Gets the following Thursday if d is not already Thursday 00410 // absl::CivilDay thurs1 = absl::PrevWeekday(d, absl::Weekday::thursday) + 7; 00411 // // Gets the previous Thursday if d is not already Thursday 00412 // absl::CivilDay thurs2 = absl::NextWeekday(d, absl::Weekday::thursday) - 7; 00413 // 00414 inline CivilDay NextWeekday(CivilDay cd, Weekday wd) { 00415 return CivilDay(time_internal::cctz::next_weekday(cd, wd)); 00416 } 00417 inline CivilDay PrevWeekday(CivilDay cd, Weekday wd) { 00418 return CivilDay(time_internal::cctz::prev_weekday(cd, wd)); 00419 } 00420 00421 // GetYearDay() 00422 // 00423 // Returns the day-of-year for the given absl::CivilDay. 00424 // 00425 // Example: 00426 // 00427 // absl::CivilDay a(2015, 1, 1); 00428 // int yd_jan_1 = absl::GetYearDay(a); // yd_jan_1 = 1 00429 // absl::CivilDay b(2015, 12, 31); 00430 // int yd_dec_31 = absl::GetYearDay(b); // yd_dec_31 = 365 00431 // 00432 inline int GetYearDay(CivilDay cd) { 00433 return time_internal::cctz::get_yearday(cd); 00434 } 00435 00436 // FormatCivilTime() 00437 // 00438 // Formats the given civil-time value into a string value of the following 00439 // format: 00440 // 00441 // Type | Format 00442 // --------------------------------- 00443 // CivilSecond | YYYY-MM-DDTHH:MM:SS 00444 // CivilMinute | YYYY-MM-DDTHH:MM 00445 // CivilHour | YYYY-MM-DDTHH 00446 // CivilDay | YYYY-MM-DD 00447 // CivilMonth | YYYY-MM 00448 // CivilYear | YYYY 00449 // 00450 // Example: 00451 // 00452 // absl::CivilDay d = absl::CivilDay(1969, 7, 20); 00453 // std::string day_string = absl::FormatCivilTime(d); // "1969-07-20" 00454 // 00455 std::string FormatCivilTime(CivilSecond c); 00456 std::string FormatCivilTime(CivilMinute c); 00457 std::string FormatCivilTime(CivilHour c); 00458 std::string FormatCivilTime(CivilDay c); 00459 std::string FormatCivilTime(CivilMonth c); 00460 std::string FormatCivilTime(CivilYear c); 00461 00462 namespace time_internal { // For functions found via ADL on civil-time tags. 00463 00464 // Streaming Operators 00465 // 00466 // Each civil-time type may be sent to an output stream using operator<<(). 00467 // The result matches the string produced by `FormatCivilTime()`. 00468 // 00469 // Example: 00470 // 00471 // absl::CivilDay d = absl::CivilDay("1969-07-20"); 00472 // std::cout << "Date is: " << d << "\n"; 00473 // 00474 std::ostream& operator<<(std::ostream& os, CivilYear y); 00475 std::ostream& operator<<(std::ostream& os, CivilMonth m); 00476 std::ostream& operator<<(std::ostream& os, CivilDay d); 00477 std::ostream& operator<<(std::ostream& os, CivilHour h); 00478 std::ostream& operator<<(std::ostream& os, CivilMinute m); 00479 std::ostream& operator<<(std::ostream& os, CivilSecond s); 00480 00481 } // namespace time_internal 00482 00483 } // namespace absl 00484 00485 #endif // ABSL_TIME_CIVIL_TIME_H_