1 /* 2 Copyright (C) 2010 DeSmuME team 3 4 This file is based on System.DateTime.cs and System.TimeSpan.cs from mono-2.6.7 5 6 This file is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 2 of the License, or 9 (at your option) any later version. 10 11 This file is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with the this software. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 // 21 // System.DateTime.cs 22 // 23 // author: 24 // Marcel Narings (marcel@narings.nl) 25 // Martin Baulig (martin@gnome.org) 26 // Atsushi Enomoto (atsushi@ximian.com) 27 // 28 // (C) 2001 Marcel Narings 29 // Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com) 30 // 31 // Permission is hereby granted, free of charge, to any person obtaining 32 // a copy of this software and associated documentation files (the 33 // "Software"), to deal in the Software without restriction, including 34 // without limitation the rights to use, copy, modify, merge, publish, 35 // distribute, sublicense, and/or sell copies of the Software, and to 36 // permit persons to whom the Software is furnished to do so, subject to 37 // the following conditions: 38 // 39 // The above copyright notice and this permission notice shall be 40 // included in all copies or substantial portions of the Software. 41 // 42 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 43 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 44 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 45 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 46 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 47 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 48 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 49 50 // 51 // System.TimeSpan.cs 52 // 53 // Authors: 54 // Duco Fijma (duco@lorentz.xs4all.nl) 55 // Andreas Nahr (ClassDevelopment@A-SoftTech.com) 56 // Sebastien Pouliot <sebastien@ximian.com> 57 // 58 // (C) 2001 Duco Fijma 59 // (C) 2004 Andreas Nahr 60 // Copyright (C) 2004 Novell (http://www.novell.com) 61 // 62 // Permission is hereby granted, free of charge, to any person obtaining 63 // a copy of this software and associated documentation files (the 64 // "Software"), to deal in the Software without restriction, including 65 // without limitation the rights to use, copy, modify, merge, publish, 66 // distribute, sublicense, and/or sell copies of the Software, and to 67 // permit persons to whom the Software is furnished to do so, subject to 68 // the following conditions: 69 // 70 // The above copyright notice and this permission notice shall be 71 // included in all copies or substantial portions of the Software. 72 // 73 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 74 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 75 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 76 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 77 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 78 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 79 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 80 // 81 82 #ifndef _DATETIME_H_ 83 #define _DATETIME_H_ 84 85 #include <math.h> 86 #include <time.h> 87 #include <string.h> 88 #include <stdio.h> 89 90 #include <string> 91 92 #include "../types.h" 93 94 enum DayOfWeek { 95 DayOfWeek_Sunday=0, 96 DayOfWeek_Monday=1, 97 DayOfWeek_Tuesday=2, 98 DayOfWeek_Wednesday=3, 99 DayOfWeek_Thursday=4, 100 DayOfWeek_Friday=5, 101 DayOfWeek_Saturday=6 102 }; 103 104 class TimeSpan 105 { 106 friend class DateTime; 107 108 public: get_MaxValue()109 static const TimeSpan& get_MaxValue() 110 { 111 static TimeSpan val(0x7FFFFFFFFFFFFFFFLL); 112 return val; 113 } 114 get_MinValue()115 static const TimeSpan& get_MinValue() 116 { 117 static TimeSpan val(0x8000000000000000LL); 118 return val; 119 } 120 get_Zero()121 static const TimeSpan& get_Zero() 122 { 123 static TimeSpan val(0); 124 return val; 125 } 126 127 static const s64 TicksPerDay = 864000000000LL; 128 static const s64 TicksPerHour = 36000000000LL; 129 static const s64 TicksPerMillisecond = 10000LL; 130 static const s64 TicksPerMinute = 600000000LL; 131 static const s64 TicksPerSecond = 10000000LL; 132 TimeSpan()133 TimeSpan () 134 { 135 } 136 TimeSpan(s64 ticks)137 TimeSpan (s64 ticks) 138 : _ticks(ticks) 139 { 140 } 141 TimeSpan(int hours,int minutes,int seconds)142 TimeSpan (int hours, int minutes, int seconds) 143 { 144 _ticks = CalculateTicks (0, hours, minutes, seconds, 0); 145 } 146 TimeSpan(int days,int hours,int minutes,int seconds)147 TimeSpan (int days, int hours, int minutes, int seconds) 148 { 149 _ticks = CalculateTicks (days, hours, minutes, seconds, 0); 150 } 151 TimeSpan(int days,int hours,int minutes,int seconds,int milliseconds)152 TimeSpan (int days, int hours, int minutes, int seconds, int milliseconds) 153 { 154 _ticks = CalculateTicks (days, hours, minutes, seconds, milliseconds); 155 } 156 get_Days()157 int get_Days() const { return (int) (_ticks / TicksPerDay); } get_Hours()158 int get_Hours() const { return (int) (_ticks % TicksPerDay / TicksPerHour); } get_Milliseconds()159 int get_Milliseconds() const { return (int) (_ticks % TicksPerSecond / TicksPerMillisecond); } get_Minutes()160 int get_Minutes() const { return (int) (_ticks % TicksPerHour / TicksPerMinute); } get_Seconds()161 int get_Seconds() const { return (int) (_ticks % TicksPerMinute / TicksPerSecond); } get_Ticks()162 s64 get_Ticks() const { return _ticks; } get_TotalDays()163 double get_TotalDays() const { return (double) _ticks / TicksPerDay; } get_TotalHours()164 double get_TotalHours() const { return (double) _ticks / TicksPerHour; } get_TotalMilliseconds()165 double get_TotalMilliseconds() const { return (double) _ticks / TicksPerMillisecond; } get_TotalMinutes()166 double get_TotalMinutes() const { return (double) _ticks / TicksPerMinute; } get_TotalSeconds()167 double get_TotalSeconds() const { return (double) _ticks / TicksPerSecond; } 168 Add(const TimeSpan & ts)169 TimeSpan Add (const TimeSpan &ts) 170 { 171 return TimeSpan (_ticks + ts._ticks); 172 //removed: 173 //catch (OverflowException) throw new OverflowException (Locale.GetText ("Resulting timespan is too big.")); 174 } 175 Compare(const TimeSpan & t1,const TimeSpan & t2)176 static int Compare (const TimeSpan& t1, const TimeSpan& t2) 177 { 178 if (t1._ticks < t2._ticks) 179 return -1; 180 if (t1._ticks > t2._ticks) 181 return 1; 182 return 0; 183 } 184 CompareTo(const TimeSpan & value)185 int CompareTo (const TimeSpan& value) 186 { 187 return Compare (*this, value); 188 } 189 Duration()190 TimeSpan Duration () 191 { 192 return TimeSpan(_ticks<0?-_ticks:_ticks); 193 //removed: 194 //catch (OverflowException) throw new OverflowException (Locale.GetText ("This TimeSpan value is MinValue so you cannot get the duration.")); 195 } 196 197 //removed per http://sourceforge.net/p/desmume/bugs/1484/ since it was erroneous (well, From() was) and wasn't being used 198 //static TimeSpan FromDays (double value) 199 //{ 200 // return From (value, TicksPerDay); 201 //} 202 203 //static TimeSpan FromHours (double value) 204 //{ 205 // return From (value, TicksPerHour); 206 //} 207 208 //static TimeSpan FromMinutes (double value) 209 //{ 210 // return From (value, TicksPerMinute); 211 //} 212 213 //static TimeSpan FromSeconds (double value) 214 //{ 215 // return From (value, TicksPerSecond); 216 //} 217 218 //static TimeSpan FromMilliseconds (double value) 219 //{ 220 // return From (value, TicksPerMillisecond); 221 //} 222 FromTicks(s64 value)223 static TimeSpan FromTicks (s64 value) 224 { 225 return TimeSpan (value); 226 } 227 Negate()228 TimeSpan Negate () 229 { 230 //removed error handling 231 //if (_ticks == MinValue()._ticks) throw new OverflowException (Locale.GetText ( "This TimeSpan value is MinValue and cannot be negated.")); 232 return TimeSpan (-_ticks); 233 } 234 Subtract(const TimeSpan & ts)235 TimeSpan Subtract (const TimeSpan& ts) 236 { 237 //removed error handling 238 //try { checked { 239 return TimeSpan (_ticks - ts._ticks); 240 // } 241 //} 242 //catch (OverflowException) { 243 // throw new OverflowException (Locale.GetText ("Resulting timespan is too big.")); 244 //} 245 } 246 247 TimeSpan operator + (const TimeSpan& t2) const 248 { 249 TimeSpan temp = *this; 250 temp.Add (t2); 251 return temp; 252 } 253 254 bool operator == (const TimeSpan& t2) const 255 { 256 return _ticks == t2._ticks; 257 } 258 259 bool operator > (const TimeSpan& t2) const 260 { 261 return _ticks > t2._ticks; 262 } 263 264 bool operator >= (const TimeSpan& t2) const 265 { 266 return _ticks >= t2._ticks; 267 } 268 269 bool operator != (const TimeSpan& t2) const 270 { 271 return _ticks != t2._ticks; 272 } 273 274 bool operator < (const TimeSpan& t2) const 275 { 276 return _ticks < t2._ticks; 277 } 278 279 bool operator <= (const TimeSpan& t2) const 280 { 281 return _ticks <= t2._ticks; 282 } 283 284 TimeSpan operator - (const TimeSpan& t2) const 285 { 286 TimeSpan temp = *this; 287 return temp.Subtract (t2); 288 } 289 290 TimeSpan operator - () 291 { 292 return Negate (); 293 } 294 295 296 private: 297 s64 _ticks; 298 CalculateTicks(int days,int hours,int minutes,int seconds,int milliseconds)299 static s64 CalculateTicks (int days, int hours, int minutes, int seconds, int milliseconds) 300 { 301 // there's no overflow checks for hours, minutes, ... 302 // so big hours/minutes values can overflow at some point and change expected values 303 int hrssec = (hours * 3600); // break point at (Int32.MaxValue - 596523) 304 int minsec = (minutes * 60); 305 s64 t = ((s64)(hrssec + minsec + seconds) * 1000L + (s64)milliseconds); 306 t *= 10000; 307 308 bool overflow = false; 309 // days is problematic because it can overflow but that overflow can be 310 // "legal" (i.e. temporary) (e.g. if other parameters are negative) or 311 // illegal (e.g. sign change). 312 if (days > 0) { 313 s64 td = TicksPerDay * days; 314 if (t < 0) { 315 s64 ticks = t; 316 t += td; 317 // positive days -> total ticks should be lower 318 overflow = (ticks > t); 319 } 320 else { 321 t += td; 322 // positive + positive != negative result 323 overflow = (t < 0); 324 } 325 } 326 else if (days < 0) { 327 s64 td = TicksPerDay * days; 328 if (t <= 0) { 329 t += td; 330 // negative + negative != positive result 331 overflow = (t > 0); 332 } 333 else { 334 s64 ticks = t; 335 t += td; 336 // negative days -> total ticks should be lower 337 overflow = (t > ticks); 338 } 339 } 340 341 //removed: 342 //if (overflow) throw ArgumentOutOfRangeException ("The timespan is too big or too small."); 343 344 return t; 345 } 346 347 //removed per http://sourceforge.net/p/desmume/bugs/1484/ since it was erroneous and wasn't being used 348 //static TimeSpan From (double value, s64 tickMultiplicator) 349 //{ 350 // //a bunch of error handling removed 351 352 // //if (Double.IsNaN (value)) throw new ArgumentException (Locale.GetText ("Value cannot be NaN."), "value"); 353 // //if (Double.IsNegativeInfinity (value) || Double.IsPositiveInfinity (value) || 354 // // (value < MinValue.Ticks) || (value > MaxValue.Ticks)) 355 // // throw new OverflowException (Locale.GetText ("Outside range [MinValue,MaxValue]")); 356 357 // //try { 358 // value = (value * (tickMultiplicator / TicksPerMillisecond)); 359 360 // // checked { 361 // // long val = (long) Math.Round(value); 362 // // return new TimeSpan (val * TicksPerMillisecond); 363 // // } 364 // //} 365 // //catch (OverflowException) { 366 // // throw new OverflowException (Locale.GetText ("Resulting timespan is too big.")); 367 // //} 368 // //} 369 //} 370 371 }; 372 373 class DateTime 374 { 375 private: 376 TimeSpan ticks; 377 round(const double x)378 static inline double round(const double x) { return floor(x + 0.5); } 379 380 static const int dp400 = 146097; 381 static const int dp100 = 36524; 382 static const int dp4 = 1461; 383 384 // w32 file time starts counting from 1/1/1601 00:00 GMT 385 // which is the constant ticks from the .NET epoch 386 static const s64 w32file_epoch = 504911232000000000LL; 387 388 //private const long MAX_VALUE_TICKS = 3155378975400000000L; 389 // -- Microsoft .NET has this value. 390 static const s64 MAX_VALUE_TICKS = 3155378975999999999LL; 391 392 // 393 // The UnixEpoch, it begins on Jan 1, 1970 at 0:0:0, expressed 394 // in Ticks 395 // 396 static const s64 UnixEpoch = 621355968000000000LL; 397 398 399 static const int daysmonth[13]; 400 static const int daysmonthleap[13]; 401 static const char* monthnames[13]; 402 init(int year,int month,int day,int hour,int minute,int second,int millisecond)403 void init (int year, int month, int day, int hour, int minute, int second, int millisecond) 404 { 405 //removed error handling 406 /* if ( year < 1 || year > 9999 || 407 month < 1 || month >12 || 408 day < 1 || day > DaysInMonth(year, month) || 409 hour < 0 || hour > 23 || 410 minute < 0 || minute > 59 || 411 second < 0 || second > 59 || 412 millisecond < 0 || millisecond > 999) 413 throw new ArgumentOutOfRangeException ("Parameters describe an " + 414 "unrepresentable DateTime.");*/ 415 416 ticks = TimeSpan (AbsoluteDays(year,month,day), hour, minute, second, millisecond); 417 } 418 419 420 AbsoluteDays(int year,int month,int day)421 static int AbsoluteDays (int year, int month, int day) 422 { 423 const int* days; 424 int temp = 0, m=1 ; 425 426 days = (IsLeapYear(year) ? daysmonthleap : daysmonth); 427 428 while (m < month) 429 temp += days[m++]; 430 return ((day-1) + temp + (365* (year-1)) + ((year-1)/4) - ((year-1)/100) + ((year-1)/400)); 431 } 432 433 434 enum Which 435 { 436 Which_Day, 437 Which_DayYear, 438 Which_Month, 439 Which_Year 440 }; 441 FromTicks(Which what)442 int FromTicks(Which what) const 443 { 444 int num400, num100, num4, numyears; 445 int M =1; 446 447 const int* days = daysmonth; 448 int totaldays = ticks.get_Days(); 449 450 num400 = (totaldays / dp400); 451 totaldays -= num400 * dp400; 452 453 num100 = (totaldays / dp100); 454 if (num100 == 4) // leap 455 num100 = 3; 456 totaldays -= (num100 * dp100); 457 458 num4 = totaldays / dp4; 459 totaldays -= (num4 * dp4); 460 461 numyears = totaldays / 365 ; 462 463 if (numyears == 4) //leap 464 numyears =3 ; 465 if (what == Which_Year ) 466 return num400*400 + num100*100 + num4*4 + numyears + 1; 467 468 totaldays -= (numyears * 365) ; 469 if (what == Which_DayYear ) 470 return totaldays + 1; 471 472 if ((numyears==3) && ((num100 == 3) || !(num4 == 24)) ) //31 dec leapyear 473 days = daysmonthleap; 474 475 while (totaldays >= days[M]) 476 totaldays -= days[M++]; 477 478 if (what == Which_Month ) 479 return M; 480 481 return totaldays +1; 482 } 483 484 public: DateTime()485 DateTime() 486 : ticks(0) 487 { 488 } 489 GetNameOfMonth(int month)490 static const char* GetNameOfMonth(int month) { return monthnames[month]; } 491 DateTime(s64 ticks)492 DateTime (s64 ticks) 493 { 494 this->ticks = TimeSpan (ticks); 495 //removed error handling 496 //if (ticks < get_MinValue().get_Ticks() || ticks > get_MaxValue().get_Ticks()) { 497 // string msg = Locale.GetText ("Value {0} is outside the valid range [{1},{2}].", 498 // ticks, MinValue.Ticks, MaxValue.Ticks); 499 // throw new ArgumentOutOfRangeException ("ticks", msg); 500 //} 501 } 502 get_MaxValue()503 static const DateTime& get_MaxValue() { 504 static DateTime val(false, TimeSpan (MAX_VALUE_TICKS)); 505 return val; 506 } 507 get_MinValue()508 static const DateTime& get_MinValue() { 509 static DateTime val(false, TimeSpan (0)); 510 return val; 511 } 512 DateTime(int year,int month,int day)513 DateTime (int year, int month, int day) 514 { 515 init(year,month,day,0,0,0,0); 516 } 517 DateTime(int year,int month,int day,int hour,int minute,int second)518 DateTime (int year, int month, int day, int hour, int minute, int second) 519 { 520 init(year, month, day, hour, minute, second, 0); 521 } 522 DateTime(int year,int month,int day,int hour,int minute,int second,int millisecond)523 DateTime (int year, int month, int day, int hour, int minute, int second, int millisecond) 524 { 525 init(year,month,day,hour,minute,second,millisecond); 526 } 527 528 DateTime(bool check,const TimeSpan & value)529 DateTime (bool check, const TimeSpan& value) 530 { 531 //removed error handling 532 //if (check && (value.Ticks < MinValue.Ticks || value.Ticks > MaxValue.Ticks)) 533 // throw new ArgumentOutOfRangeException (); 534 535 ticks = value; 536 } 537 get_Date()538 DateTime get_Date () const 539 { 540 return DateTime (get_Year(), get_Month(), get_Day()); 541 } 542 get_Month()543 int get_Month () const { 544 return FromTicks(Which_Month); 545 } 546 get_Day()547 int get_Day() const 548 { 549 return FromTicks(Which_Day); 550 } 551 get_DayOfWeek()552 DayOfWeek get_DayOfWeek () const 553 { 554 return ( (DayOfWeek) ((ticks.get_Days()+1) % 7) ); 555 } 556 get_DayOfYear()557 int get_DayOfYear () const 558 { 559 return FromTicks(Which_DayYear); 560 } 561 get_TimeOfDay()562 TimeSpan get_TimeOfDay () const 563 { 564 return TimeSpan(ticks.get_Ticks() % TimeSpan::TicksPerDay ); 565 } 566 get_Hour()567 int get_Hour () const 568 { 569 return ticks.get_Hours(); 570 } 571 get_Minute()572 int get_Minute () const 573 { 574 return ticks.get_Minutes(); 575 } 576 get_Second()577 int get_Second () const 578 { 579 return ticks.get_Seconds(); 580 } 581 get_Millisecond()582 int get_Millisecond () const 583 { 584 return ticks.get_Milliseconds(); 585 } 586 587 //internal static extern s64 GetTimeMonotonic (); 588 //internal static extern s64 GetNow (); 589 get_Now()590 static DateTime get_Now () 591 { 592 time_t timer; 593 time(&timer); 594 struct tm *tm = localtime(&timer); 595 return DateTime(tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec); 596 } 597 get_Ticks()598 s64 get_Ticks()const 599 { 600 return ticks.get_Ticks(); 601 } 602 get_Today()603 static DateTime get_Today () 604 { 605 DateTime now = get_Now(); 606 DateTime today = DateTime (now.get_Year(), now.get_Month(), now.get_Day()); 607 return today; 608 } 609 get_Year()610 int get_Year () const 611 { 612 return FromTicks(Which_Year); 613 } 614 Add(const TimeSpan & value)615 DateTime Add (const TimeSpan& value) const 616 { 617 DateTime ret = AddTicks (value.get_Ticks()); 618 return ret; 619 } 620 AddDays(double value)621 DateTime AddDays (double value) const 622 { 623 return AddMilliseconds (round(value * 86400000)); 624 } 625 AddTicks(const s64 value)626 DateTime AddTicks (const s64 value) const 627 { 628 //removed error handling 629 //if ((value + ticks.Ticks) > MAX_VALUE_TICKS || (value + ticks.Ticks) < 0) { 630 // throw new ArgumentOutOfRangeException(); 631 //} 632 return DateTime (value + ticks.get_Ticks()); 633 } 634 AddHours(double value)635 DateTime AddHours (double value) const 636 { 637 return AddMilliseconds (value * 3600000); 638 } 639 AddMilliseconds(double value)640 DateTime AddMilliseconds (double value) const 641 { 642 //removed error handling 643 /* if ((value * TimeSpan.TicksPerMillisecond) > long.MaxValue || 644 (value * TimeSpan.TicksPerMillisecond) < long.MinValue) { 645 throw new ArgumentOutOfRangeException(); 646 } 647 */ 648 s64 msticks = (s64) round(value * TimeSpan::TicksPerMillisecond); 649 return AddTicks (msticks); 650 } 651 AddMinutes(double value)652 DateTime AddMinutes (double value) const 653 { 654 return AddMilliseconds (value * 60000); 655 } 656 AddMonths(int months)657 DateTime AddMonths (int months) const 658 { 659 int day, month, year, maxday ; 660 DateTime temp; 661 662 day = get_Day(); 663 month = get_Month() + (months % 12); 664 year = get_Year() + months/12 ; 665 666 if (month < 1) 667 { 668 month = 12 + month ; 669 year -- ; 670 } 671 else if (month>12) 672 { 673 month = month -12; 674 year ++; 675 } 676 maxday = DaysInMonth(year, month); 677 if (day > maxday) 678 day = maxday; 679 680 temp = (year, month, day); 681 return temp.Add (get_TimeOfDay()); 682 } 683 AddSeconds(double value)684 DateTime AddSeconds (double value) const 685 { 686 return AddMilliseconds (value * 1000); 687 } 688 AddYears(int value)689 DateTime AddYears (int value) const 690 { 691 return AddMonths (value * 12); 692 } 693 Compare(const DateTime & t1,const DateTime & t2)694 static int Compare (const DateTime& t1, const DateTime& t2) 695 { 696 if (t1.ticks < t2.ticks) 697 return -1; 698 else if (t1.ticks > t2.ticks) 699 return 1; 700 else 701 return 0; 702 } 703 DaysInMonth(int year,int month)704 static int DaysInMonth (int year, int month) 705 { 706 const int* days ; 707 708 //removed error handling 709 //if (month < 1 || month >12)throw new ArgumentOutOfRangeException (); 710 //if (year < 1 || year > 9999)throw new ArgumentOutOfRangeException (); 711 712 days = (IsLeapYear(year) ? daysmonthleap : daysmonth); 713 return days[month]; 714 } IsLeapYear(int year)715 static bool IsLeapYear (int year) 716 { 717 //removed error handling 718 /* if (year < 1 || year > 9999) 719 throw new ArgumentOutOfRangeException ();*/ 720 return ( (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) ; 721 } 722 Subtract(const DateTime & value)723 TimeSpan Subtract (const DateTime& value) const 724 { 725 return TimeSpan (ticks.get_Ticks()) - value.ticks; 726 } 727 Subtract(const TimeSpan & value)728 DateTime Subtract(const TimeSpan& value) const 729 { 730 TimeSpan newticks; 731 732 newticks = (TimeSpan (ticks.get_Ticks())) - value; 733 DateTime ret = DateTime (true,newticks); 734 return ret; 735 } 736 737 DateTime operator +(const TimeSpan& t) const 738 { 739 return DateTime (true, ticks + t); 740 } 741 742 bool operator ==(const DateTime& d2) const 743 { 744 return (ticks == d2.ticks); 745 } 746 747 bool operator >(const DateTime& t2) const 748 { 749 return (ticks > t2.ticks); 750 } 751 752 bool operator >=(const DateTime &t2) const 753 { 754 return (ticks >= t2.ticks); 755 } 756 757 bool operator !=(const DateTime& d2) const 758 { 759 return (ticks != d2.ticks); 760 } 761 762 bool operator <(const DateTime& t2) const 763 { 764 return (ticks < t2.ticks ); 765 } 766 767 bool operator <=(const DateTime& t2) const 768 { 769 return (ticks <= t2.ticks); 770 } 771 772 TimeSpan operator -(const DateTime& d2) const 773 { 774 return TimeSpan((ticks - d2.ticks).get_Ticks()); 775 } 776 777 DateTime operator -(const TimeSpan& t) const 778 { 779 return DateTime (true, ticks - t); 780 } 781 782 //try to have a canonical format here. this was comment was typed at 2010-oct-04 02:16:44:000 783 ToString()784 std::string ToString() const 785 { 786 char tmp[32]; 787 sprintf(tmp,"%04d-%s-%02d %02d:%02d:%02d:%03d",get_Year(),monthnames[get_Month()],get_Day(),get_Hour(),get_Minute(),get_Second(),get_Millisecond()); 788 return tmp; 789 } 790 TryParse(const char * str,DateTime & out)791 static bool TryParse(const char* str, DateTime& out) 792 { 793 int year,mon=-1,day,hour,min,sec,ms; 794 char strmon[4]; 795 int done = sscanf(str,"%04d-%3s-%02d %02d:%02d:%02d:%03d",&year,strmon,&day,&hour,&min,&sec,&ms); 796 if(done != 7) return false; 797 for(int i=1;i<12;i++) 798 if(!strncasecmp(monthnames[i],strmon,3)) 799 { 800 mon=i; 801 break; 802 } 803 if(mon==-1) return false; 804 out = DateTime(year,mon,day,hour,min,sec); 805 return true; 806 } 807 Parse(const char * str)808 static DateTime Parse(const char* str) 809 { 810 DateTime ret; 811 TryParse(str,ret); 812 return ret; 813 } 814 815 }; 816 817 818 #endif //_DATETIME_H_ 819