civil_time.h
Go to the documentation of this file.
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_


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:14