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 // Parsing of a POSIX zone spec as described in the TZ part of section 8.3 in 00016 // http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html. 00017 // 00018 // The current POSIX spec for America/Los_Angeles is "PST8PDT,M3.2.0,M11.1.0", 00019 // which would be broken down as ... 00020 // 00021 // PosixTimeZone { 00022 // std_abbr = "PST" 00023 // std_offset = -28800 00024 // dst_abbr = "PDT" 00025 // dst_offset = -25200 00026 // dst_start = PosixTransition { 00027 // date { 00028 // m { 00029 // month = 3 00030 // week = 2 00031 // weekday = 0 00032 // } 00033 // } 00034 // time { 00035 // offset = 7200 00036 // } 00037 // } 00038 // dst_end = PosixTransition { 00039 // date { 00040 // m { 00041 // month = 11 00042 // week = 1 00043 // weekday = 0 00044 // } 00045 // } 00046 // time { 00047 // offset = 7200 00048 // } 00049 // } 00050 // } 00051 00052 #ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_POSIX_H_ 00053 #define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_POSIX_H_ 00054 00055 #include <cstdint> 00056 #include <string> 00057 00058 namespace absl { 00059 namespace time_internal { 00060 namespace cctz { 00061 00062 // The date/time of the transition. The date is specified as either: 00063 // (J) the Nth day of the year (1 <= N <= 365), excluding leap days, or 00064 // (N) the Nth day of the year (0 <= N <= 365), including leap days, or 00065 // (M) the Nth weekday of a month (e.g., the 2nd Sunday in March). 00066 // The time, specified as a day offset, identifies the particular moment 00067 // of the transition, and may be negative or >= 24h, and in which case 00068 // it would take us to another day, and perhaps week, or even month. 00069 struct PosixTransition { 00070 enum DateFormat { J, N, M }; 00071 00072 struct Date { 00073 struct NonLeapDay { 00074 std::int_fast16_t day; // day of non-leap year [1:365] 00075 }; 00076 struct Day { 00077 std::int_fast16_t day; // day of year [0:365] 00078 }; 00079 struct MonthWeekWeekday { 00080 std::int_fast8_t month; // month of year [1:12] 00081 std::int_fast8_t week; // week of month [1:5] (5==last) 00082 std::int_fast8_t weekday; // 0==Sun, ..., 6=Sat 00083 }; 00084 00085 DateFormat fmt; 00086 00087 union { 00088 NonLeapDay j; 00089 Day n; 00090 MonthWeekWeekday m; 00091 }; 00092 }; 00093 00094 struct Time { 00095 std::int_fast32_t offset; // seconds before/after 00:00:00 00096 }; 00097 00098 Date date; 00099 Time time; 00100 }; 00101 00102 // The entirety of a POSIX-string specified time-zone rule. The standard 00103 // abbreviation and offset are always given. If the time zone includes 00104 // daylight saving, then the daylight abbrevation is non-empty and the 00105 // remaining fields are also valid. Note that the start/end transitions 00106 // are not ordered---in the southern hemisphere the transition to end 00107 // daylight time occurs first in any particular year. 00108 struct PosixTimeZone { 00109 std::string std_abbr; 00110 std::int_fast32_t std_offset; 00111 00112 std::string dst_abbr; 00113 std::int_fast32_t dst_offset; 00114 PosixTransition dst_start; 00115 PosixTransition dst_end; 00116 }; 00117 00118 // Breaks down a POSIX time-zone specification into its constituent pieces, 00119 // filling in any missing values (DST offset, or start/end transition times) 00120 // with the standard-defined defaults. Returns false if the specification 00121 // could not be parsed (although some fields of *res may have been altered). 00122 bool ParsePosixSpec(const std::string& spec, PosixTimeZone* res); 00123 00124 } // namespace cctz 00125 } // namespace time_internal 00126 } // namespace absl 00127 00128 #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_POSIX_H_