00001 // Copyright 2016 Google Inc. All Rights Reserved. 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 #ifndef ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_ 00016 #define ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_ 00017 00018 #include "absl/time/internal/cctz/include/cctz/civil_time_detail.h" 00019 00020 namespace absl { 00021 namespace time_internal { 00022 namespace cctz { 00023 00024 // The term "civil time" refers to the legally recognized human-scale time 00025 // that is represented by the six fields YYYY-MM-DD hh:mm:ss. Modern-day civil 00026 // time follows the Gregorian Calendar and is a time-zone-independent concept. 00027 // A "date" is perhaps the most common example of a civil time (represented in 00028 // this library as cctz::civil_day). This library provides six classes and a 00029 // handful of functions that help with rounding, iterating, and arithmetic on 00030 // civil times while avoiding complications like daylight-saving time (DST). 00031 // 00032 // The following six classes form the core of this civil-time library: 00033 // 00034 // * civil_second 00035 // * civil_minute 00036 // * civil_hour 00037 // * civil_day 00038 // * civil_month 00039 // * civil_year 00040 // 00041 // Each class is a simple value type with the same interface for construction 00042 // and the same six accessors for each of the civil fields (year, month, day, 00043 // hour, minute, and second, aka YMDHMS). These classes differ only in their 00044 // alignment, which is indicated by the type name and specifies the field on 00045 // which arithmetic operates. 00046 // 00047 // Each class can be constructed by passing up to six optional integer 00048 // arguments representing the YMDHMS fields (in that order) to the 00049 // constructor. Omitted fields are assigned their minimum valid value. Hours, 00050 // minutes, and seconds will be set to 0, month and day will be set to 1, and 00051 // since there is no minimum valid year, it will be set to 1970. So, a 00052 // default-constructed civil-time object will have YMDHMS fields representing 00053 // "1970-01-01 00:00:00". Fields that are out-of-range are normalized (e.g., 00054 // October 32 -> November 1) so that all civil-time objects represent valid 00055 // values. 00056 // 00057 // Each civil-time class is aligned to the civil-time field indicated in the 00058 // class's name after normalization. Alignment is performed by setting all the 00059 // inferior fields to their minimum valid value (as described above). The 00060 // following are examples of how each of the six types would align the fields 00061 // representing November 22, 2015 at 12:34:56 in the afternoon. (Note: the 00062 // string format used here is not important; it's just a shorthand way of 00063 // showing the six YMDHMS fields.) 00064 // 00065 // civil_second 2015-11-22 12:34:56 00066 // civil_minute 2015-11-22 12:34:00 00067 // civil_hour 2015-11-22 12:00:00 00068 // civil_day 2015-11-22 00:00:00 00069 // civil_month 2015-11-01 00:00:00 00070 // civil_year 2015-01-01 00:00:00 00071 // 00072 // Each civil-time type performs arithmetic on the field to which it is 00073 // aligned. This means that adding 1 to a civil_day increments the day field 00074 // (normalizing as necessary), and subtracting 7 from a civil_month operates 00075 // on the month field (normalizing as necessary). All arithmetic produces a 00076 // valid civil time. Difference requires two similarly aligned civil-time 00077 // objects and returns the scalar answer in units of the objects' alignment. 00078 // For example, the difference between two civil_hour objects will give an 00079 // answer in units of civil hours. 00080 // 00081 // In addition to the six civil-time types just described, there are 00082 // a handful of helper functions and algorithms for performing common 00083 // calculations. These are described below. 00084 // 00085 // Note: In C++14 and later, this library is usable in a constexpr context. 00086 // 00087 // CONSTRUCTION: 00088 // 00089 // Each of the civil-time types can be constructed in two ways: by directly 00090 // passing to the constructor up to six (optional) integers representing the 00091 // YMDHMS fields, or by copying the YMDHMS fields from a differently aligned 00092 // civil-time type. 00093 // 00094 // civil_day default_value; // 1970-01-01 00:00:00 00095 // 00096 // civil_day a(2015, 2, 3); // 2015-02-03 00:00:00 00097 // civil_day b(2015, 2, 3, 4, 5, 6); // 2015-02-03 00:00:00 00098 // civil_day c(2015); // 2015-01-01 00:00:00 00099 // 00100 // civil_second ss(2015, 2, 3, 4, 5, 6); // 2015-02-03 04:05:06 00101 // civil_minute mm(ss); // 2015-02-03 04:05:00 00102 // civil_hour hh(mm); // 2015-02-03 04:00:00 00103 // civil_day d(hh); // 2015-02-03 00:00:00 00104 // civil_month m(d); // 2015-02-01 00:00:00 00105 // civil_year y(m); // 2015-01-01 00:00:00 00106 // 00107 // m = civil_month(y); // 2015-01-01 00:00:00 00108 // d = civil_day(m); // 2015-01-01 00:00:00 00109 // hh = civil_hour(d); // 2015-01-01 00:00:00 00110 // mm = civil_minute(hh); // 2015-01-01 00:00:00 00111 // ss = civil_second(mm); // 2015-01-01 00:00:00 00112 // 00113 // ALIGNMENT CONVERSION: 00114 // 00115 // The alignment of a civil-time object cannot change, but the object may be 00116 // used to construct a new object with a different alignment. This is referred 00117 // to as "realigning". When realigning to a type with the same or more 00118 // precision (e.g., civil_day -> civil_second), the conversion may be 00119 // performed implicitly since no information is lost. However, if information 00120 // could be discarded (e.g., civil_second -> civil_day), the conversion must 00121 // be explicit at the call site. 00122 // 00123 // void fun(const civil_day& day); 00124 // 00125 // civil_second cs; 00126 // fun(cs); // Won't compile because data may be discarded 00127 // fun(civil_day(cs)); // OK: explicit conversion 00128 // 00129 // civil_day cd; 00130 // fun(cd); // OK: no conversion needed 00131 // 00132 // civil_month cm; 00133 // fun(cm); // OK: implicit conversion to civil_day 00134 // 00135 // NORMALIZATION: 00136 // 00137 // Integer arguments passed to the constructor may be out-of-range, in which 00138 // case they are normalized to produce a valid civil-time object. This enables 00139 // natural arithmetic on constructor arguments without worrying about the 00140 // field's range. Normalization guarantees that there are no invalid 00141 // civil-time objects. 00142 // 00143 // civil_day d(2016, 10, 32); // Out-of-range day; normalized to 2016-11-01 00144 // 00145 // Note: If normalization is undesired, you can signal an error by comparing 00146 // the constructor arguments to the normalized values returned by the YMDHMS 00147 // properties. 00148 // 00149 // PROPERTIES: 00150 // 00151 // All civil-time types have accessors for all six of the civil-time fields: 00152 // year, month, day, hour, minute, and second. Recall that fields inferior to 00153 // the type's aligment will be set to their minimum valid value. 00154 // 00155 // civil_day d(2015, 6, 28); 00156 // // d.year() == 2015 00157 // // d.month() == 6 00158 // // d.day() == 28 00159 // // d.hour() == 0 00160 // // d.minute() == 0 00161 // // d.second() == 0 00162 // 00163 // COMPARISON: 00164 // 00165 // Comparison always considers all six YMDHMS fields, regardless of the type's 00166 // alignment. Comparison between differently aligned civil-time types is 00167 // allowed. 00168 // 00169 // civil_day feb_3(2015, 2, 3); // 2015-02-03 00:00:00 00170 // civil_day mar_4(2015, 3, 4); // 2015-03-04 00:00:00 00171 // // feb_3 < mar_4 00172 // // civil_year(feb_3) == civil_year(mar_4) 00173 // 00174 // civil_second feb_3_noon(2015, 2, 3, 12, 0, 0); // 2015-02-03 12:00:00 00175 // // feb_3 < feb_3_noon 00176 // // feb_3 == civil_day(feb_3_noon) 00177 // 00178 // // Iterates all the days of February 2015. 00179 // for (civil_day d(2015, 2, 1); d < civil_month(2015, 3); ++d) { 00180 // // ... 00181 // } 00182 // 00183 // STREAMING: 00184 // 00185 // Each civil-time type may be sent to an output stream using operator<<(). 00186 // The output format follows the pattern "YYYY-MM-DDThh:mm:ss" where fields 00187 // inferior to the type's alignment are omitted. 00188 // 00189 // civil_second cs(2015, 2, 3, 4, 5, 6); 00190 // std::cout << cs << "\n"; // Outputs: 2015-02-03T04:05:06 00191 // 00192 // civil_day cd(cs); 00193 // std::cout << cd << "\n"; // Outputs: 2015-02-03 00194 // 00195 // civil_year cy(cs); 00196 // std::cout << cy << "\n"; // Outputs: 2015 00197 // 00198 // ARITHMETIC: 00199 // 00200 // Civil-time types support natural arithmetic operators such as addition, 00201 // subtraction, and difference. Arithmetic operates on the civil-time field 00202 // indicated in the type's name. Difference requires arguments with the same 00203 // alignment and returns the answer in units of the alignment. 00204 // 00205 // civil_day a(2015, 2, 3); 00206 // ++a; // 2015-02-04 00:00:00 00207 // --a; // 2015-02-03 00:00:00 00208 // civil_day b = a + 1; // 2015-02-04 00:00:00 00209 // civil_day c = 1 + b; // 2015-02-05 00:00:00 00210 // int n = c - a; // n = 2 (civil days) 00211 // int m = c - civil_month(c); // Won't compile: different types. 00212 // 00213 // EXAMPLE: Adding a month to January 31. 00214 // 00215 // One of the classic questions that arises when considering a civil-time 00216 // library (or a date library or a date/time library) is this: "What happens 00217 // when you add a month to January 31?" This is an interesting question 00218 // because there could be a number of possible answers: 00219 // 00220 // 1. March 3 (or 2 if a leap year). This may make sense if the operation 00221 // wants the equivalent of February 31. 00222 // 2. February 28 (or 29 if a leap year). This may make sense if the operation 00223 // wants the last day of January to go to the last day of February. 00224 // 3. Error. The caller may get some error, an exception, an invalid date 00225 // object, or maybe false is returned. This may make sense because there is 00226 // no single unambiguously correct answer to the question. 00227 // 00228 // Practically speaking, any answer that is not what the programmer intended 00229 // is the wrong answer. 00230 // 00231 // This civil-time library avoids the problem by making it impossible to ask 00232 // ambiguous questions. All civil-time objects are aligned to a particular 00233 // civil-field boundary (such as aligned to a year, month, day, hour, minute, 00234 // or second), and arithmetic operates on the field to which the object is 00235 // aligned. This means that in order to "add a month" the object must first be 00236 // aligned to a month boundary, which is equivalent to the first day of that 00237 // month. 00238 // 00239 // Of course, there are ways to compute an answer the question at hand using 00240 // this civil-time library, but they require the programmer to be explicit 00241 // about the answer they expect. To illustrate, let's see how to compute all 00242 // three of the above possible answers to the question of "Jan 31 plus 1 00243 // month": 00244 // 00245 // const civil_day d(2015, 1, 31); 00246 // 00247 // // Answer 1: 00248 // // Add 1 to the month field in the constructor, and rely on normalization. 00249 // const auto ans_normalized = civil_day(d.year(), d.month() + 1, d.day()); 00250 // // ans_normalized == 2015-03-03 (aka Feb 31) 00251 // 00252 // // Answer 2: 00253 // // Add 1 to month field, capping to the end of next month. 00254 // const auto next_month = civil_month(d) + 1; 00255 // const auto last_day_of_next_month = civil_day(next_month + 1) - 1; 00256 // const auto ans_capped = std::min(ans_normalized, last_day_of_next_month); 00257 // // ans_capped == 2015-02-28 00258 // 00259 // // Answer 3: 00260 // // Signal an error if the normalized answer is not in next month. 00261 // if (civil_month(ans_normalized) != next_month) { 00262 // // error, month overflow 00263 // } 00264 // 00265 using civil_year = detail::civil_year; 00266 using civil_month = detail::civil_month; 00267 using civil_day = detail::civil_day; 00268 using civil_hour = detail::civil_hour; 00269 using civil_minute = detail::civil_minute; 00270 using civil_second = detail::civil_second; 00271 00272 // An enum class with members monday, tuesday, wednesday, thursday, friday, 00273 // saturday, and sunday. These enum values may be sent to an output stream 00274 // using operator<<(). The result is the full weekday name in English with a 00275 // leading capital letter. 00276 // 00277 // weekday wd = weekday::thursday; 00278 // std::cout << wd << "\n"; // Outputs: Thursday 00279 // 00280 using detail::weekday; 00281 00282 // Returns the weekday for the given civil_day. 00283 // 00284 // civil_day a(2015, 8, 13); 00285 // weekday wd = get_weekday(a); // wd == weekday::thursday 00286 // 00287 using detail::get_weekday; 00288 00289 // Returns the civil_day that strictly follows or precedes the given 00290 // civil_day, and that falls on the given weekday. 00291 // 00292 // For example, given: 00293 // 00294 // August 2015 00295 // Su Mo Tu We Th Fr Sa 00296 // 1 00297 // 2 3 4 5 6 7 8 00298 // 9 10 11 12 13 14 15 00299 // 16 17 18 19 20 21 22 00300 // 23 24 25 26 27 28 29 00301 // 30 31 00302 // 00303 // civil_day a(2015, 8, 13); // get_weekday(a) == weekday::thursday 00304 // civil_day b = next_weekday(a, weekday::thursday); // b = 2015-08-20 00305 // civil_day c = prev_weekday(a, weekday::thursday); // c = 2015-08-06 00306 // 00307 // civil_day d = ... 00308 // // Gets the following Thursday if d is not already Thursday 00309 // civil_day thurs1 = prev_weekday(d, weekday::thursday) + 7; 00310 // // Gets the previous Thursday if d is not already Thursday 00311 // civil_day thurs2 = next_weekday(d, weekday::thursday) - 7; 00312 // 00313 using detail::next_weekday; 00314 using detail::prev_weekday; 00315 00316 // Returns the day-of-year for the given civil_day. 00317 // 00318 // civil_day a(2015, 1, 1); 00319 // int yd_jan_1 = get_yearday(a); // yd_jan_1 = 1 00320 // civil_day b(2015, 12, 31); 00321 // int yd_dec_31 = get_yearday(b); // yd_dec_31 = 365 00322 // 00323 using detail::get_yearday; 00324 00325 } // namespace cctz 00326 } // namespace time_internal 00327 } // namespace absl 00328 00329 #endif // ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_