1 /* 2 * Copyright 2006-2008 The FLWOR Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 #ifndef ZORBA_DATETIME_H 18 #define ZORBA_DATETIME_H 19 20 #include <iostream> 21 22 #include <zorba/config.h> 23 #include "zorbatypes/timezone.h" 24 #include "zorbatypes/duration.h" 25 26 #include "util/ascii_util.h" 27 28 29 namespace zorba 30 { 31 32 class DateTime; 33 34 35 namespace serialization 36 { 37 class Archiver; 38 void operator&(Archiver& ar, DateTime& obj); 39 } 40 41 42 43 class InvalidTimezoneException : public std::exception 44 { 45 }; 46 47 48 class DateTime 49 { 50 friend void serialization::operator&(serialization::Archiver& ar, DateTime& obj); 51 52 public: 53 54 /** Available facets for the DateTime class */ 55 typedef enum 56 { 57 DATETIME_FACET = 0, 58 DATE_FACET = 1, 59 TIME_FACET = 2, 60 GYEARMONTH_FACET = 3, 61 GYEAR_FACET = 4, 62 GMONTH_FACET = 5, 63 GMONTHDAY_FACET = 6, 64 GDAY_FACET = 7 65 } FACET_TYPE; 66 67 // Only year may be negative, all other must be positive 68 // The year gives the sign of DateTime, Date, etc 69 70 typedef enum 71 { 72 YEAR_DATA = 0, 73 MONTH_DATA = 1, 74 DAY_DATA = 2, 75 HOUR_DATA = 3, 76 MINUTE_DATA = 4, 77 SECONDS_DATA = 5, 78 FRACSECONDS_DATA = 6 79 } DATA_TYPE; 80 81 82 static const int FACET_MEMBERS[8][8]; 83 84 // fractional seconds have 6 digits. 0.1 seconds are represented as 100000, 85 // 0.01 seconds as 10000, etc. 86 static const int FRAC_SECONDS_UPPER_LIMIT; // = 1000000, maximum 6 digits 87 88 protected: 89 FACET_TYPE facet; 90 91 long data[7]; 92 93 TimeZone the_time_zone; 94 95 public: 96 /** 97 * Returns 0 on success 98 * Returns 2 if both the Date and the Time have a timezone, and they differ (FORG0008) 99 */ 100 static int createDateTime( 101 const DateTime* date, 102 const DateTime* time, 103 DateTime& result); 104 105 /** 106 * The function will use the absolute values of all int parameters except 107 * years. No TimeZone. 108 * Returns 0 on success 109 */ 110 static int createDateTime( 111 int years, 112 int months, 113 int days, 114 int hours, 115 int minutes, 116 int seconds, 117 int fractional_seconds, 118 DateTime& dt); 119 120 /** 121 * The function will use the absolute values of all int parameters except 122 * years. TimeZone may be NULL 123 * Returns 0 on success 124 */ 125 static int createDateTime( 126 int years, 127 int months, 128 int days, 129 int hours, 130 int minutes, 131 double seconds, 132 const TimeZone* tz, 133 DateTime& dt); 134 135 /** 136 * The function will use the absolute values of all int parameters except 137 * years. TimeZone may be NULL 138 * Returns 0 on success 139 */ 140 static int createDateTime( 141 int years, 142 int months, 143 int days, 144 int hours, 145 int minutes, 146 int seconds, 147 int fractional_seconds, 148 const TimeZone* tz, 149 DateTime& dt); 150 151 /** 152 * The function will use the absolute values of all int parameters except years. 153 * TimeZone may be NULL 154 * Returns 0 on success 155 */ 156 static int createDate( 157 int years, 158 int months, 159 int days, 160 const TimeZone* tz, 161 DateTime& dt); 162 163 /** 164 * The function will use the absolute values of all int parameters. TimeZone 165 * is a reference 166 * Returns 0 on success 167 */ 168 static int createTime( 169 int hours, 170 int minutes, 171 double seconds, 172 const TimeZone* tz, 173 DateTime& dt); 174 175 /** 176 * The function will use the absolute value of the months parameter. 177 * Returns 0 on success 178 */ 179 static int createGYearMonth(int years, int months, DateTime& dt); 180 181 /** 182 * Returns 0 on success 183 */ 184 static int createGYear(int years, DateTime& dt); 185 186 /** 187 * The function will use the absolute values of all int parameters. 188 * Returns 0 on success 189 */ 190 static int createGMonth(int months, DateTime& dt); 191 192 /** 193 * The function will use the absolute values of all int parameters. 194 * Returns 0 on success 195 */ 196 static int createGMonthDay(int months, int days, DateTime& dt); 197 198 /** 199 * The function will use the absolute values of all int parameters. 200 * Returns 0 on success 201 */ 202 static int createGDay(int days, DateTime& dt); 203 204 static int getLocalTime(DateTime& dt); 205 206 /** 207 * Returns 0 on success 208 */ 209 static int parseDateTime(const char* str, ascii::size_type strlen, DateTime& dt); 210 211 /** 212 * Returns 0 on success 213 */ 214 static int parseDate(const char* str, ascii::size_type strlen, DateTime& dt); 215 216 /** 217 * Returns 0 on success 218 */ 219 static int parseTime(const char* str, ascii::size_type strlen, DateTime& dt); 220 221 /** 222 * Returns 0 on success 223 */ 224 static int parseGYearMonth(const char* str, ascii::size_type strlen, DateTime& dt); 225 226 /** 227 * Returns 0 on success 228 */ 229 static int parseGYear(const char* str, ascii::size_type strlen, DateTime& dt); 230 231 /** 232 * Returns 0 on success 233 */ 234 static int parseGMonth(const char* str, ascii::size_type strlen, DateTime& dt); 235 236 /** 237 * Returns 0 on success 238 */ 239 static int parseGMonthDay(const char* str, ascii::size_type strlen, DateTime& dt); 240 241 /** 242 * Returns 0 on success 243 */ 244 static int parseGDay(const char* str, ascii::size_type strlen, DateTime& dt); 245 246 static int getDayOfWeek(int year, int month, int day); 247 248 static int getDayOfYear(int year, int month, int day); 249 250 static int getWeekInYear(int year, int month, int day); 251 252 static int getWeekInMonth(int year, int month, int day); 253 254 static bool isLeapYear(int year); 255 256 protected: 257 static int parse_date( 258 const char* str, 259 ascii::size_type strlen, 260 ascii::size_type& position, 261 long& year, 262 long& month, 263 long& day); 264 265 static int parse_time( 266 const char* str, 267 ascii::size_type strlen, 268 ascii::size_type& position, 269 long& hour, 270 long& minute, 271 long& seconds, 272 long& frac_seconds); 273 274 public: 275 DateTime(); 276 ~DateTime()277 virtual ~DateTime() { }; 278 279 void init(); 280 281 DateTime& operator=(const DateTime* dt); 282 283 /** 284 * Creates a new DateTime object from the given one, adjusting it to the newly 285 * given facet. Useful for casting. Will always return 0. 286 */ 287 int createWithNewFacet(FACET_TYPE new_facet, DateTime& dt) const; 288 289 zstring toString() const; 290 291 DateTime* getDate() const; 292 293 DateTime* getTime() const; 294 295 int getYear() const; 296 297 int getMonth() const; 298 299 int getDay() const; 300 301 int getHours() const; 302 303 int getMinutes() const; 304 305 xs_decimal getSeconds() const; 306 307 int getIntSeconds() const; 308 309 int getFractionalSeconds() const; 310 311 TimeZone getTimezone() const; 312 313 /** 314 * Returns -1 if the DateTime is less than the given DateTime 315 * Returns 0 if the DateTimes are equal 316 * Returns 1 if the DateTime is greater than the given DateTime 317 * 318 * Throws InvalidTimezoneException if the given timezone is not valid. 319 */ 320 int compare(const DateTime* dt, long timezone_seconds) const; 321 322 uint32_t hash(int implicit_timezone_seconds) const; 323 324 DateTime* addDuration(const Duration& d, bool adjust_facet = true) const; 325 326 DateTime* subtractDuration(const Duration& d, bool adjust_facet = true) const; 327 328 /** 329 * Throws InvalidTimezoneException if the given timezone is not valid. 330 */ 331 Duration* subtractDateTime(const DateTime* dt, int implicit_timezone_seconds) const; 332 333 /** 334 * Throws InvalidTimezoneException if the given timezone is not valid. 335 */ 336 DateTime* normalizeTimeZone(int tz_seconds) const; 337 338 /** 339 * Throws InvalidTimezoneException if the given timezone is not valid. 340 */ 341 DateTime* adjustToTimeZone(int tz_seconds) const; 342 343 /** 344 * Throws InvalidTimezoneException if the given timezone is not valid. 345 */ 346 DateTime* adjustToTimeZone(const Duration* db_t) const; 347 getFacet()348 FACET_TYPE getFacet() const { return facet; }; 349 350 /** 351 * For a given Date or DateTime, it will return the respective day of the week, 352 * with the index being 0 based, with 0 being Sunday, 1 Monday, etc. If the give 353 * DateTime does not have a Date or DateTime facet, the function will return -1. 354 */ 355 int getDayOfWeek() const; 356 int getDayOfYear() const; 357 int getWeekInYear() const; 358 int getWeekInMonth() const; 359 bool isLeapYear() const; 360 361 protected: 362 Duration* toDayTimeDuration() const; 363 364 void adjustToFacet(); 365 366 void setFacet(FACET_TYPE a_facet); 367 }; 368 369 inline std::ostream& operator<<( std::ostream &o, DateTime const &dt ) { 370 return o << dt.toString(); 371 } 372 373 } // namespace zorba 374 #endif /* ZORBA_DATETIME_H */ 375 /* 376 * Local variables: 377 * mode: c++ 378 * End: 379 */ 380 /* vim:set et sw=2 ts=2: */ 381