1*a070cf53SStephan Aßmus /* 2*a070cf53SStephan Aßmus * Copyright 2007-2010, Haiku, Inc. All Rights Reserved. 3*a070cf53SStephan Aßmus * Distributed under the terms of the MIT License. 4*a070cf53SStephan Aßmus * 5*a070cf53SStephan Aßmus * Authors: 6*a070cf53SStephan Aßmus * Julun <host.haiku@gmx.de> 7*a070cf53SStephan Aßmus * Stephan Aßmus <superstippi@gmx.de> 8*a070cf53SStephan Aßmus */ 9*a070cf53SStephan Aßmus 10*a070cf53SStephan Aßmus #include "DateTime.h" 11*a070cf53SStephan Aßmus 12*a070cf53SStephan Aßmus 13*a070cf53SStephan Aßmus #include <time.h> 14*a070cf53SStephan Aßmus #include <sys/time.h> 15*a070cf53SStephan Aßmus 16*a070cf53SStephan Aßmus #include <Message.h> 17*a070cf53SStephan Aßmus 18*a070cf53SStephan Aßmus 19*a070cf53SStephan Aßmus namespace BPrivate { 20*a070cf53SStephan Aßmus 21*a070cf53SStephan Aßmus 22*a070cf53SStephan Aßmus const int32 kSecondsPerMinute = 60; 23*a070cf53SStephan Aßmus 24*a070cf53SStephan Aßmus const int32 kHoursPerDay = 24; 25*a070cf53SStephan Aßmus const int32 kMinutesPerDay = 1440; 26*a070cf53SStephan Aßmus const int32 kSecondsPerDay = 86400; 27*a070cf53SStephan Aßmus const int32 kMillisecondsPerDay = 86400000; 28*a070cf53SStephan Aßmus 29*a070cf53SStephan Aßmus const bigtime_t kMicrosecondsPerSecond = 1000000LL; 30*a070cf53SStephan Aßmus const bigtime_t kMicrosecondsPerMinute = 60000000LL; 31*a070cf53SStephan Aßmus const bigtime_t kMicrosecondsPerHour = 3600000000LL; 32*a070cf53SStephan Aßmus const bigtime_t kMicrosecondsPerDay = 86400000000LL; 33*a070cf53SStephan Aßmus 34*a070cf53SStephan Aßmus 35*a070cf53SStephan Aßmus /*! 36*a070cf53SStephan Aßmus Constructs a new BTime object. Asked for its time representation, it will 37*a070cf53SStephan Aßmus return 0 for Hour(), Minute(), Second() etc. This can represent midnight, 38*a070cf53SStephan Aßmus but be aware IsValid() will return false. 39*a070cf53SStephan Aßmus */ 40*a070cf53SStephan Aßmus BTime::BTime() 41*a070cf53SStephan Aßmus : fMicroseconds(-1) 42*a070cf53SStephan Aßmus { 43*a070cf53SStephan Aßmus } 44*a070cf53SStephan Aßmus 45*a070cf53SStephan Aßmus 46*a070cf53SStephan Aßmus /*! 47*a070cf53SStephan Aßmus Constructs a BTime object with \c hour \c minute, \c second, \c microsecond. 48*a070cf53SStephan Aßmus 49*a070cf53SStephan Aßmus \c hour must be between 0 and 23, \c minute and \c second must be between 50*a070cf53SStephan Aßmus 0 and 59 and \c microsecond should be in the range of 0 and 999999. If the 51*a070cf53SStephan Aßmus specified time is invalid, the time is not set and IsValid() returns false. 52*a070cf53SStephan Aßmus */ 53*a070cf53SStephan Aßmus BTime::BTime(int32 hour, int32 minute, int32 second, int32 microsecond) 54*a070cf53SStephan Aßmus : fMicroseconds(-1) 55*a070cf53SStephan Aßmus { 56*a070cf53SStephan Aßmus _SetTime(hour, minute, second, microsecond); 57*a070cf53SStephan Aßmus } 58*a070cf53SStephan Aßmus 59*a070cf53SStephan Aßmus 60*a070cf53SStephan Aßmus /*! 61*a070cf53SStephan Aßmus Constructs a new BTime object from the provided BMessage archive. 62*a070cf53SStephan Aßmus */ 63*a070cf53SStephan Aßmus BTime::BTime(const BMessage* archive) 64*a070cf53SStephan Aßmus : fMicroseconds(-1) 65*a070cf53SStephan Aßmus { 66*a070cf53SStephan Aßmus if (archive == NULL) 67*a070cf53SStephan Aßmus return; 68*a070cf53SStephan Aßmus archive->FindInt64("mircoseconds", &fMicroseconds); 69*a070cf53SStephan Aßmus } 70*a070cf53SStephan Aßmus 71*a070cf53SStephan Aßmus 72*a070cf53SStephan Aßmus /*! 73*a070cf53SStephan Aßmus Empty destructor. 74*a070cf53SStephan Aßmus */ 75*a070cf53SStephan Aßmus BTime::~BTime() 76*a070cf53SStephan Aßmus { 77*a070cf53SStephan Aßmus } 78*a070cf53SStephan Aßmus 79*a070cf53SStephan Aßmus 80*a070cf53SStephan Aßmus /*! 81*a070cf53SStephan Aßmus Archives the BTime object into the provided BMessage object. 82*a070cf53SStephan Aßmus @returns \c B_OK if all went well. 83*a070cf53SStephan Aßmus \c B_BAD_VALUE, if the message is \c NULL. 84*a070cf53SStephan Aßmus \c other error codes, depending on failure to append 85*a070cf53SStephan Aßmus fields to the message. 86*a070cf53SStephan Aßmus */ 87*a070cf53SStephan Aßmus status_t 88*a070cf53SStephan Aßmus BTime::Archive(BMessage* into) const 89*a070cf53SStephan Aßmus { 90*a070cf53SStephan Aßmus if (into == NULL) 91*a070cf53SStephan Aßmus return B_BAD_VALUE; 92*a070cf53SStephan Aßmus return into->AddInt64("mircoseconds", fMicroseconds); 93*a070cf53SStephan Aßmus } 94*a070cf53SStephan Aßmus 95*a070cf53SStephan Aßmus 96*a070cf53SStephan Aßmus /*! 97*a070cf53SStephan Aßmus Returns true if the time is valid, otherwise false. A valid time can be 98*a070cf53SStephan Aßmus BTime(23, 59, 59, 999999) while BTime(24, 00, 01) would be invalid. 99*a070cf53SStephan Aßmus */ 100*a070cf53SStephan Aßmus bool 101*a070cf53SStephan Aßmus BTime::IsValid() const 102*a070cf53SStephan Aßmus { 103*a070cf53SStephan Aßmus return fMicroseconds > -1 && fMicroseconds < kMicrosecondsPerDay; 104*a070cf53SStephan Aßmus } 105*a070cf53SStephan Aßmus 106*a070cf53SStephan Aßmus 107*a070cf53SStephan Aßmus /*! 108*a070cf53SStephan Aßmus This is an overloaded member function, provided for convenience. 109*a070cf53SStephan Aßmus */ 110*a070cf53SStephan Aßmus bool 111*a070cf53SStephan Aßmus BTime::IsValid(const BTime& time) const 112*a070cf53SStephan Aßmus { 113*a070cf53SStephan Aßmus return time.fMicroseconds > -1 && time.fMicroseconds < kMicrosecondsPerDay; 114*a070cf53SStephan Aßmus } 115*a070cf53SStephan Aßmus 116*a070cf53SStephan Aßmus 117*a070cf53SStephan Aßmus /*! 118*a070cf53SStephan Aßmus This is an overloaded member function, provided for convenience. 119*a070cf53SStephan Aßmus */ 120*a070cf53SStephan Aßmus bool 121*a070cf53SStephan Aßmus BTime::IsValid(int32 hour, int32 minute, int32 second, int32 microsecond) const 122*a070cf53SStephan Aßmus { 123*a070cf53SStephan Aßmus return BTime(hour, minute, second, microsecond).IsValid(); 124*a070cf53SStephan Aßmus } 125*a070cf53SStephan Aßmus 126*a070cf53SStephan Aßmus 127*a070cf53SStephan Aßmus /*! 128*a070cf53SStephan Aßmus Returns the current time as reported by the system depending on the given 129*a070cf53SStephan Aßmus time_type \c type. 130*a070cf53SStephan Aßmus */ 131*a070cf53SStephan Aßmus BTime 132*a070cf53SStephan Aßmus BTime::CurrentTime(time_type type) 133*a070cf53SStephan Aßmus { 134*a070cf53SStephan Aßmus struct timeval tv; 135*a070cf53SStephan Aßmus if (gettimeofday(&tv, NULL) != 0) { 136*a070cf53SStephan Aßmus // gettimeofday failed? 137*a070cf53SStephan Aßmus time(&tv.tv_sec); 138*a070cf53SStephan Aßmus } 139*a070cf53SStephan Aßmus 140*a070cf53SStephan Aßmus struct tm result; 141*a070cf53SStephan Aßmus struct tm* timeinfo; 142*a070cf53SStephan Aßmus if (type == B_GMT_TIME) 143*a070cf53SStephan Aßmus timeinfo = gmtime_r(&tv.tv_sec, &result); 144*a070cf53SStephan Aßmus else 145*a070cf53SStephan Aßmus timeinfo = localtime_r(&tv.tv_sec, &result); 146*a070cf53SStephan Aßmus 147*a070cf53SStephan Aßmus int32 sec = timeinfo->tm_sec; 148*a070cf53SStephan Aßmus return BTime(timeinfo->tm_hour, timeinfo->tm_min, (sec > 59) ? 59 : sec, 149*a070cf53SStephan Aßmus tv.tv_usec); 150*a070cf53SStephan Aßmus } 151*a070cf53SStephan Aßmus 152*a070cf53SStephan Aßmus 153*a070cf53SStephan Aßmus /*! 154*a070cf53SStephan Aßmus Returns a copy of the current BTime object. 155*a070cf53SStephan Aßmus */ 156*a070cf53SStephan Aßmus BTime 157*a070cf53SStephan Aßmus BTime::Time() const 158*a070cf53SStephan Aßmus { 159*a070cf53SStephan Aßmus return *this; 160*a070cf53SStephan Aßmus } 161*a070cf53SStephan Aßmus 162*a070cf53SStephan Aßmus 163*a070cf53SStephan Aßmus /*! 164*a070cf53SStephan Aßmus This is an overloaded member function, provided for convenience. Set the 165*a070cf53SStephan Aßmus current BTime object to the passed BTime \c time object. 166*a070cf53SStephan Aßmus */ 167*a070cf53SStephan Aßmus bool 168*a070cf53SStephan Aßmus BTime::SetTime(const BTime& time) 169*a070cf53SStephan Aßmus { 170*a070cf53SStephan Aßmus fMicroseconds = time.fMicroseconds; 171*a070cf53SStephan Aßmus return IsValid(); 172*a070cf53SStephan Aßmus } 173*a070cf53SStephan Aßmus 174*a070cf53SStephan Aßmus 175*a070cf53SStephan Aßmus /*! 176*a070cf53SStephan Aßmus Set the time to \c hour \c minute, \c second and \c microsecond. 177*a070cf53SStephan Aßmus 178*a070cf53SStephan Aßmus \c hour must be between 0 and 23, \c minute and \c second must be between 179*a070cf53SStephan Aßmus 0 and 59 and \c microsecond should be in the range of 0 and 999999. Returns 180*a070cf53SStephan Aßmus true if the time is valid; otherwise false. If the specified time is 181*a070cf53SStephan Aßmus invalid, the time is not set and the function returns false. 182*a070cf53SStephan Aßmus */ 183*a070cf53SStephan Aßmus bool 184*a070cf53SStephan Aßmus BTime::SetTime(int32 hour, int32 minute, int32 second, int32 microsecond) 185*a070cf53SStephan Aßmus { 186*a070cf53SStephan Aßmus return _SetTime(hour, minute, second, microsecond); 187*a070cf53SStephan Aßmus } 188*a070cf53SStephan Aßmus 189*a070cf53SStephan Aßmus 190*a070cf53SStephan Aßmus 191*a070cf53SStephan Aßmus /*! 192*a070cf53SStephan Aßmus Adds \c hours to the current time. If the passed value is negativ it will 193*a070cf53SStephan Aßmus become earlier. Note: The time will wrap if it passes midnight. 194*a070cf53SStephan Aßmus */ 195*a070cf53SStephan Aßmus void 196*a070cf53SStephan Aßmus BTime::AddHours(int32 hours) 197*a070cf53SStephan Aßmus { 198*a070cf53SStephan Aßmus _AddMicroseconds(bigtime_t(hours % kHoursPerDay) * kMicrosecondsPerHour); 199*a070cf53SStephan Aßmus } 200*a070cf53SStephan Aßmus 201*a070cf53SStephan Aßmus 202*a070cf53SStephan Aßmus /*! 203*a070cf53SStephan Aßmus Adds \c minutes to the current time. If the passed value is negativ it will 204*a070cf53SStephan Aßmus become earlier. Note: The time will wrap if it passes midnight. 205*a070cf53SStephan Aßmus */ 206*a070cf53SStephan Aßmus void 207*a070cf53SStephan Aßmus BTime::AddMinutes(int32 minutes) 208*a070cf53SStephan Aßmus { 209*a070cf53SStephan Aßmus _AddMicroseconds(bigtime_t(minutes % kMinutesPerDay) * 210*a070cf53SStephan Aßmus kMicrosecondsPerMinute); 211*a070cf53SStephan Aßmus } 212*a070cf53SStephan Aßmus 213*a070cf53SStephan Aßmus 214*a070cf53SStephan Aßmus /*! 215*a070cf53SStephan Aßmus Adds \c seconds to the current time. If the passed value is negativ it will 216*a070cf53SStephan Aßmus become earlier. Note: The time will wrap if it passes midnight. 217*a070cf53SStephan Aßmus */ 218*a070cf53SStephan Aßmus void 219*a070cf53SStephan Aßmus BTime::AddSeconds(int32 seconds) 220*a070cf53SStephan Aßmus { 221*a070cf53SStephan Aßmus _AddMicroseconds(bigtime_t(seconds % kSecondsPerDay) * 222*a070cf53SStephan Aßmus kMicrosecondsPerSecond); 223*a070cf53SStephan Aßmus } 224*a070cf53SStephan Aßmus 225*a070cf53SStephan Aßmus 226*a070cf53SStephan Aßmus /*! 227*a070cf53SStephan Aßmus Adds \c milliseconds to the current time. If the passed value is negativ it 228*a070cf53SStephan Aßmus will become earlier. Note: The time will wrap if it passes midnight. 229*a070cf53SStephan Aßmus */ 230*a070cf53SStephan Aßmus void 231*a070cf53SStephan Aßmus BTime::AddMilliseconds(int32 milliseconds) 232*a070cf53SStephan Aßmus { 233*a070cf53SStephan Aßmus _AddMicroseconds(bigtime_t(milliseconds % kMillisecondsPerDay) * 1000); 234*a070cf53SStephan Aßmus } 235*a070cf53SStephan Aßmus 236*a070cf53SStephan Aßmus 237*a070cf53SStephan Aßmus /*! 238*a070cf53SStephan Aßmus Adds \c microseconds to the current time. If the passed value is negativ it 239*a070cf53SStephan Aßmus will become earlier. Note: The time will wrap if it passes midnight. 240*a070cf53SStephan Aßmus */ 241*a070cf53SStephan Aßmus void 242*a070cf53SStephan Aßmus BTime::AddMicroseconds(int32 microseconds) 243*a070cf53SStephan Aßmus { 244*a070cf53SStephan Aßmus _AddMicroseconds(microseconds); 245*a070cf53SStephan Aßmus } 246*a070cf53SStephan Aßmus 247*a070cf53SStephan Aßmus 248*a070cf53SStephan Aßmus /*! 249*a070cf53SStephan Aßmus Returns the hour fragment of the time. 250*a070cf53SStephan Aßmus */ 251*a070cf53SStephan Aßmus int32 252*a070cf53SStephan Aßmus BTime::Hour() const 253*a070cf53SStephan Aßmus { 254*a070cf53SStephan Aßmus return int32(_Microseconds() / kMicrosecondsPerHour); 255*a070cf53SStephan Aßmus } 256*a070cf53SStephan Aßmus 257*a070cf53SStephan Aßmus 258*a070cf53SStephan Aßmus /*! 259*a070cf53SStephan Aßmus Returns the minute fragment of the time. 260*a070cf53SStephan Aßmus */ 261*a070cf53SStephan Aßmus int32 262*a070cf53SStephan Aßmus BTime::Minute() const 263*a070cf53SStephan Aßmus { 264*a070cf53SStephan Aßmus return int32(((_Microseconds() % kMicrosecondsPerHour)) / kMicrosecondsPerMinute); 265*a070cf53SStephan Aßmus } 266*a070cf53SStephan Aßmus 267*a070cf53SStephan Aßmus 268*a070cf53SStephan Aßmus /*! 269*a070cf53SStephan Aßmus Returns the second fragment of the time. 270*a070cf53SStephan Aßmus */ 271*a070cf53SStephan Aßmus int32 272*a070cf53SStephan Aßmus BTime::Second() const 273*a070cf53SStephan Aßmus { 274*a070cf53SStephan Aßmus return int32(_Microseconds() / kMicrosecondsPerSecond) % kSecondsPerMinute; 275*a070cf53SStephan Aßmus } 276*a070cf53SStephan Aßmus 277*a070cf53SStephan Aßmus 278*a070cf53SStephan Aßmus /*! 279*a070cf53SStephan Aßmus Returns the millisecond fragment of the time. 280*a070cf53SStephan Aßmus */ 281*a070cf53SStephan Aßmus int32 282*a070cf53SStephan Aßmus BTime::Millisecond() const 283*a070cf53SStephan Aßmus { 284*a070cf53SStephan Aßmus 285*a070cf53SStephan Aßmus return Microsecond() / 1000; 286*a070cf53SStephan Aßmus } 287*a070cf53SStephan Aßmus 288*a070cf53SStephan Aßmus 289*a070cf53SStephan Aßmus /*! 290*a070cf53SStephan Aßmus Returns the microsecond fragment of the time. 291*a070cf53SStephan Aßmus */ 292*a070cf53SStephan Aßmus int32 293*a070cf53SStephan Aßmus BTime::Microsecond() const 294*a070cf53SStephan Aßmus { 295*a070cf53SStephan Aßmus return int32(_Microseconds() % 1000000); 296*a070cf53SStephan Aßmus } 297*a070cf53SStephan Aßmus 298*a070cf53SStephan Aßmus 299*a070cf53SStephan Aßmus bigtime_t 300*a070cf53SStephan Aßmus BTime::_Microseconds() const 301*a070cf53SStephan Aßmus { 302*a070cf53SStephan Aßmus return fMicroseconds == -1 ? 0 : fMicroseconds; 303*a070cf53SStephan Aßmus } 304*a070cf53SStephan Aßmus 305*a070cf53SStephan Aßmus 306*a070cf53SStephan Aßmus /*! 307*a070cf53SStephan Aßmus Returns the difference between this time and the given BTime \c time based 308*a070cf53SStephan Aßmus on the passed diff_type \c type. If \c time is earlier the return value will 309*a070cf53SStephan Aßmus be negativ. 310*a070cf53SStephan Aßmus 311*a070cf53SStephan Aßmus The return value then can be hours, minutes, seconds, milliseconds or 312*a070cf53SStephan Aßmus microseconds while its range will always be between -86400000000 and 313*a070cf53SStephan Aßmus 86400000000 depending on diff_type \c type. 314*a070cf53SStephan Aßmus */ 315*a070cf53SStephan Aßmus bigtime_t 316*a070cf53SStephan Aßmus BTime::Difference(const BTime& time, diff_type type) const 317*a070cf53SStephan Aßmus { 318*a070cf53SStephan Aßmus bigtime_t diff = time._Microseconds() - _Microseconds(); 319*a070cf53SStephan Aßmus switch (type) { 320*a070cf53SStephan Aßmus case B_HOURS_DIFF: { 321*a070cf53SStephan Aßmus diff /= kMicrosecondsPerHour; 322*a070cf53SStephan Aßmus } break; 323*a070cf53SStephan Aßmus case B_MINUTES_DIFF: { 324*a070cf53SStephan Aßmus diff /= kMicrosecondsPerMinute; 325*a070cf53SStephan Aßmus } break; 326*a070cf53SStephan Aßmus case B_SECONDS_DIFF: { 327*a070cf53SStephan Aßmus diff /= kMicrosecondsPerSecond; 328*a070cf53SStephan Aßmus } break; 329*a070cf53SStephan Aßmus case B_MILLISECONDS_DIFF: { 330*a070cf53SStephan Aßmus diff /= 1000; 331*a070cf53SStephan Aßmus } break; 332*a070cf53SStephan Aßmus case B_MICROSECONDS_DIFF: 333*a070cf53SStephan Aßmus default: break; 334*a070cf53SStephan Aßmus } 335*a070cf53SStephan Aßmus return diff; 336*a070cf53SStephan Aßmus } 337*a070cf53SStephan Aßmus 338*a070cf53SStephan Aßmus 339*a070cf53SStephan Aßmus /*! 340*a070cf53SStephan Aßmus Returns true if this time is different from \c time, otherwise false. 341*a070cf53SStephan Aßmus */ 342*a070cf53SStephan Aßmus bool 343*a070cf53SStephan Aßmus BTime::operator!=(const BTime& time) const 344*a070cf53SStephan Aßmus { 345*a070cf53SStephan Aßmus return fMicroseconds != time.fMicroseconds; 346*a070cf53SStephan Aßmus } 347*a070cf53SStephan Aßmus 348*a070cf53SStephan Aßmus 349*a070cf53SStephan Aßmus /*! 350*a070cf53SStephan Aßmus Returns true if this time is equal to \c time, otherwise false. 351*a070cf53SStephan Aßmus */ 352*a070cf53SStephan Aßmus bool 353*a070cf53SStephan Aßmus BTime::operator==(const BTime& time) const 354*a070cf53SStephan Aßmus { 355*a070cf53SStephan Aßmus return fMicroseconds == time.fMicroseconds; 356*a070cf53SStephan Aßmus } 357*a070cf53SStephan Aßmus 358*a070cf53SStephan Aßmus 359*a070cf53SStephan Aßmus /*! 360*a070cf53SStephan Aßmus Returns true if this time is earlier than \c time, otherwise false. 361*a070cf53SStephan Aßmus */ 362*a070cf53SStephan Aßmus bool 363*a070cf53SStephan Aßmus BTime::operator<(const BTime& time) const 364*a070cf53SStephan Aßmus { 365*a070cf53SStephan Aßmus return fMicroseconds < time.fMicroseconds; 366*a070cf53SStephan Aßmus } 367*a070cf53SStephan Aßmus 368*a070cf53SStephan Aßmus 369*a070cf53SStephan Aßmus /*! 370*a070cf53SStephan Aßmus Returns true if this time is earlier than or equal to \c time, otherwise false. 371*a070cf53SStephan Aßmus */ 372*a070cf53SStephan Aßmus bool 373*a070cf53SStephan Aßmus BTime::operator<=(const BTime& time) const 374*a070cf53SStephan Aßmus { 375*a070cf53SStephan Aßmus return fMicroseconds <= time.fMicroseconds; 376*a070cf53SStephan Aßmus } 377*a070cf53SStephan Aßmus 378*a070cf53SStephan Aßmus 379*a070cf53SStephan Aßmus /*! 380*a070cf53SStephan Aßmus Returns true if this time is later than \c time, otherwise false. 381*a070cf53SStephan Aßmus */ 382*a070cf53SStephan Aßmus bool 383*a070cf53SStephan Aßmus BTime::operator>(const BTime& time) const 384*a070cf53SStephan Aßmus { 385*a070cf53SStephan Aßmus return fMicroseconds > time.fMicroseconds; 386*a070cf53SStephan Aßmus } 387*a070cf53SStephan Aßmus 388*a070cf53SStephan Aßmus 389*a070cf53SStephan Aßmus /*! 390*a070cf53SStephan Aßmus Returns true if this time is later than or equal to \c time, otherwise false. 391*a070cf53SStephan Aßmus */ 392*a070cf53SStephan Aßmus bool 393*a070cf53SStephan Aßmus BTime::operator>=(const BTime& time) const 394*a070cf53SStephan Aßmus { 395*a070cf53SStephan Aßmus return fMicroseconds >= time.fMicroseconds; 396*a070cf53SStephan Aßmus } 397*a070cf53SStephan Aßmus 398*a070cf53SStephan Aßmus 399*a070cf53SStephan Aßmus void 400*a070cf53SStephan Aßmus BTime::_AddMicroseconds(bigtime_t microseconds) 401*a070cf53SStephan Aßmus { 402*a070cf53SStephan Aßmus bigtime_t count = 0; 403*a070cf53SStephan Aßmus if (microseconds < 0) { 404*a070cf53SStephan Aßmus count = ((kMicrosecondsPerDay - microseconds) / kMicrosecondsPerDay) * 405*a070cf53SStephan Aßmus kMicrosecondsPerDay; 406*a070cf53SStephan Aßmus } 407*a070cf53SStephan Aßmus fMicroseconds = (_Microseconds() + microseconds + count) % kMicrosecondsPerDay; 408*a070cf53SStephan Aßmus } 409*a070cf53SStephan Aßmus 410*a070cf53SStephan Aßmus 411*a070cf53SStephan Aßmus bool 412*a070cf53SStephan Aßmus BTime::_SetTime(bigtime_t hour, bigtime_t minute, bigtime_t second, 413*a070cf53SStephan Aßmus bigtime_t microsecond) 414*a070cf53SStephan Aßmus { 415*a070cf53SStephan Aßmus fMicroseconds = hour * kMicrosecondsPerHour + 416*a070cf53SStephan Aßmus minute * kMicrosecondsPerMinute + 417*a070cf53SStephan Aßmus second * kMicrosecondsPerSecond + 418*a070cf53SStephan Aßmus microsecond; 419*a070cf53SStephan Aßmus 420*a070cf53SStephan Aßmus bool isValid = IsValid(); 421*a070cf53SStephan Aßmus if (!isValid) 422*a070cf53SStephan Aßmus fMicroseconds = -1; 423*a070cf53SStephan Aßmus 424*a070cf53SStephan Aßmus return isValid; 425*a070cf53SStephan Aßmus } 426*a070cf53SStephan Aßmus 427*a070cf53SStephan Aßmus 428*a070cf53SStephan Aßmus // #pragma mark - BDate 429*a070cf53SStephan Aßmus 430*a070cf53SStephan Aßmus 431*a070cf53SStephan Aßmus /*! 432*a070cf53SStephan Aßmus Constructs a new BDate object. IsValid() will return false. 433*a070cf53SStephan Aßmus */ 434*a070cf53SStephan Aßmus BDate::BDate() 435*a070cf53SStephan Aßmus : fDay(-1), 436*a070cf53SStephan Aßmus fYear(0), 437*a070cf53SStephan Aßmus fMonth(-1) 438*a070cf53SStephan Aßmus { 439*a070cf53SStephan Aßmus } 440*a070cf53SStephan Aßmus 441*a070cf53SStephan Aßmus 442*a070cf53SStephan Aßmus /*! 443*a070cf53SStephan Aßmus Constructs a BDate object with \c year \c month and \c day. 444*a070cf53SStephan Aßmus 445*a070cf53SStephan Aßmus Please note that a date before 1.1.4713 BC, a date with year 0 and a date 446*a070cf53SStephan Aßmus between 4.10.1582 and 15.10.1582 are considered invalid. If the specified 447*a070cf53SStephan Aßmus date is invalid, the date is not set and IsValid() returns false. Also note 448*a070cf53SStephan Aßmus that every passed year will be interpreted as is. 449*a070cf53SStephan Aßmus 450*a070cf53SStephan Aßmus */ 451*a070cf53SStephan Aßmus BDate::BDate(int32 year, int32 month, int32 day) 452*a070cf53SStephan Aßmus { 453*a070cf53SStephan Aßmus _SetDate(year, month, day); 454*a070cf53SStephan Aßmus } 455*a070cf53SStephan Aßmus 456*a070cf53SStephan Aßmus 457*a070cf53SStephan Aßmus /*! 458*a070cf53SStephan Aßmus Constructs a new BDate object from the provided archive. 459*a070cf53SStephan Aßmus */ 460*a070cf53SStephan Aßmus BDate::BDate(const BMessage* archive) 461*a070cf53SStephan Aßmus : fDay(-1), 462*a070cf53SStephan Aßmus fYear(0), 463*a070cf53SStephan Aßmus fMonth(-1) 464*a070cf53SStephan Aßmus { 465*a070cf53SStephan Aßmus if (archive == NULL) 466*a070cf53SStephan Aßmus return; 467*a070cf53SStephan Aßmus archive->FindInt32("day", &fDay); 468*a070cf53SStephan Aßmus archive->FindInt32("year", &fYear); 469*a070cf53SStephan Aßmus archive->FindInt32("month", &fMonth); 470*a070cf53SStephan Aßmus } 471*a070cf53SStephan Aßmus 472*a070cf53SStephan Aßmus 473*a070cf53SStephan Aßmus /*! 474*a070cf53SStephan Aßmus Empty destructor. 475*a070cf53SStephan Aßmus */ 476*a070cf53SStephan Aßmus BDate::~BDate() 477*a070cf53SStephan Aßmus { 478*a070cf53SStephan Aßmus } 479*a070cf53SStephan Aßmus 480*a070cf53SStephan Aßmus 481*a070cf53SStephan Aßmus /*! 482*a070cf53SStephan Aßmus Archives the BDate object into the provided BMessage object. 483*a070cf53SStephan Aßmus @returns \c B_OK if all went well. 484*a070cf53SStephan Aßmus \c B_BAD_VALUE, if the message is \c NULL. 485*a070cf53SStephan Aßmus \c other error codes, depending on failure to append 486*a070cf53SStephan Aßmus fields to the message. 487*a070cf53SStephan Aßmus */ 488*a070cf53SStephan Aßmus status_t 489*a070cf53SStephan Aßmus BDate::Archive(BMessage* into) const 490*a070cf53SStephan Aßmus { 491*a070cf53SStephan Aßmus if (into == NULL) 492*a070cf53SStephan Aßmus return B_BAD_VALUE; 493*a070cf53SStephan Aßmus status_t ret = into->AddInt32("day", fDay); 494*a070cf53SStephan Aßmus if (ret == B_OK) 495*a070cf53SStephan Aßmus ret = into->AddInt32("year", fYear); 496*a070cf53SStephan Aßmus if (ret == B_OK) 497*a070cf53SStephan Aßmus ret = into->AddInt32("month", fMonth); 498*a070cf53SStephan Aßmus return ret; 499*a070cf53SStephan Aßmus } 500*a070cf53SStephan Aßmus 501*a070cf53SStephan Aßmus 502*a070cf53SStephan Aßmus /*! 503*a070cf53SStephan Aßmus Returns true if the date is valid, otherwise false. 504*a070cf53SStephan Aßmus 505*a070cf53SStephan Aßmus Please note that a date before 1.1.4713 BC, a date with year 0 and a date 506*a070cf53SStephan Aßmus between 4.10.1582 and 15.10.1582 are considered invalid. 507*a070cf53SStephan Aßmus */ 508*a070cf53SStephan Aßmus bool 509*a070cf53SStephan Aßmus BDate::IsValid() const 510*a070cf53SStephan Aßmus { 511*a070cf53SStephan Aßmus return IsValid(fYear, fMonth, fDay); 512*a070cf53SStephan Aßmus } 513*a070cf53SStephan Aßmus 514*a070cf53SStephan Aßmus 515*a070cf53SStephan Aßmus /*! 516*a070cf53SStephan Aßmus This is an overloaded member function, provided for convenience. 517*a070cf53SStephan Aßmus */ 518*a070cf53SStephan Aßmus bool 519*a070cf53SStephan Aßmus BDate::IsValid(const BDate& date) const 520*a070cf53SStephan Aßmus { 521*a070cf53SStephan Aßmus return IsValid(date.fYear, date.fMonth, date.fDay); 522*a070cf53SStephan Aßmus } 523*a070cf53SStephan Aßmus 524*a070cf53SStephan Aßmus 525*a070cf53SStephan Aßmus /*! 526*a070cf53SStephan Aßmus This is an overloaded member function, provided for convenience. 527*a070cf53SStephan Aßmus */ 528*a070cf53SStephan Aßmus bool 529*a070cf53SStephan Aßmus BDate::IsValid(int32 year, int32 month, int32 day) const 530*a070cf53SStephan Aßmus { 531*a070cf53SStephan Aßmus // no year 0 in Julian and nothing before 1.1.4713 BC 532*a070cf53SStephan Aßmus if (year == 0 || year < -4713) 533*a070cf53SStephan Aßmus return false; 534*a070cf53SStephan Aßmus 535*a070cf53SStephan Aßmus if (month < 1 || month > 12) 536*a070cf53SStephan Aßmus return false; 537*a070cf53SStephan Aßmus 538*a070cf53SStephan Aßmus if (day < 1 || day > _DaysInMonth(year, month)) 539*a070cf53SStephan Aßmus return false; 540*a070cf53SStephan Aßmus 541*a070cf53SStephan Aßmus // 'missing' days between switch julian - gregorian 542*a070cf53SStephan Aßmus if (year == 1582 && month == 10 && day > 4 && day < 15) 543*a070cf53SStephan Aßmus return false; 544*a070cf53SStephan Aßmus 545*a070cf53SStephan Aßmus return true; 546*a070cf53SStephan Aßmus } 547*a070cf53SStephan Aßmus 548*a070cf53SStephan Aßmus 549*a070cf53SStephan Aßmus /*! 550*a070cf53SStephan Aßmus Returns the current date as reported by the system depending on the given 551*a070cf53SStephan Aßmus time_type \c type. 552*a070cf53SStephan Aßmus */ 553*a070cf53SStephan Aßmus BDate 554*a070cf53SStephan Aßmus BDate::CurrentDate(time_type type) 555*a070cf53SStephan Aßmus { 556*a070cf53SStephan Aßmus time_t timer; 557*a070cf53SStephan Aßmus struct tm result; 558*a070cf53SStephan Aßmus struct tm* timeinfo; 559*a070cf53SStephan Aßmus 560*a070cf53SStephan Aßmus time(&timer); 561*a070cf53SStephan Aßmus 562*a070cf53SStephan Aßmus if (type == B_GMT_TIME) 563*a070cf53SStephan Aßmus timeinfo = gmtime_r(&timer, &result); 564*a070cf53SStephan Aßmus else 565*a070cf53SStephan Aßmus timeinfo = localtime_r(&timer, &result); 566*a070cf53SStephan Aßmus 567*a070cf53SStephan Aßmus return BDate(timeinfo->tm_year + 1900, timeinfo->tm_mon +1, timeinfo->tm_mday); 568*a070cf53SStephan Aßmus } 569*a070cf53SStephan Aßmus 570*a070cf53SStephan Aßmus 571*a070cf53SStephan Aßmus /*! 572*a070cf53SStephan Aßmus Returns a copy of the current BTime object. 573*a070cf53SStephan Aßmus */ 574*a070cf53SStephan Aßmus BDate 575*a070cf53SStephan Aßmus BDate::Date() const 576*a070cf53SStephan Aßmus { 577*a070cf53SStephan Aßmus return *this; 578*a070cf53SStephan Aßmus } 579*a070cf53SStephan Aßmus 580*a070cf53SStephan Aßmus 581*a070cf53SStephan Aßmus /*! 582*a070cf53SStephan Aßmus This is an overloaded member function, provided for convenience. 583*a070cf53SStephan Aßmus */ 584*a070cf53SStephan Aßmus bool 585*a070cf53SStephan Aßmus BDate::SetDate(const BDate& date) 586*a070cf53SStephan Aßmus { 587*a070cf53SStephan Aßmus return _SetDate(date.fYear, date.fMonth, date.fDay); 588*a070cf53SStephan Aßmus } 589*a070cf53SStephan Aßmus 590*a070cf53SStephan Aßmus 591*a070cf53SStephan Aßmus /*! 592*a070cf53SStephan Aßmus Set the date to \c year \c month and \c day. 593*a070cf53SStephan Aßmus 594*a070cf53SStephan Aßmus Returns true if the date is valid; otherwise false. If the specified date is 595*a070cf53SStephan Aßmus invalid, the date is not set and the function returns false. 596*a070cf53SStephan Aßmus */ 597*a070cf53SStephan Aßmus bool 598*a070cf53SStephan Aßmus BDate::SetDate(int32 year, int32 month, int32 day) 599*a070cf53SStephan Aßmus { 600*a070cf53SStephan Aßmus return _SetDate(year, month, day); 601*a070cf53SStephan Aßmus } 602*a070cf53SStephan Aßmus 603*a070cf53SStephan Aßmus 604*a070cf53SStephan Aßmus /*! 605*a070cf53SStephan Aßmus This function sets the given \c year, \c month and \c day to the 606*a070cf53SStephan Aßmus representative values of this date. The pointers can be NULL. If the date is 607*a070cf53SStephan Aßmus invalid, the values will be set to -1 for \c month and \c day, the \c year 608*a070cf53SStephan Aßmus will be set to 0. 609*a070cf53SStephan Aßmus */ 610*a070cf53SStephan Aßmus void 611*a070cf53SStephan Aßmus BDate::GetDate(int32* year, int32* month, int32* day) 612*a070cf53SStephan Aßmus { 613*a070cf53SStephan Aßmus if (year) 614*a070cf53SStephan Aßmus *year = fYear; 615*a070cf53SStephan Aßmus 616*a070cf53SStephan Aßmus if (month) 617*a070cf53SStephan Aßmus *month = fMonth; 618*a070cf53SStephan Aßmus 619*a070cf53SStephan Aßmus if (day) 620*a070cf53SStephan Aßmus *day = fDay; 621*a070cf53SStephan Aßmus } 622*a070cf53SStephan Aßmus 623*a070cf53SStephan Aßmus 624*a070cf53SStephan Aßmus /*! 625*a070cf53SStephan Aßmus Adds \c days to the current date. If the passed value is negativ it will 626*a070cf53SStephan Aßmus become earlier. If the current date is invalid, the \c days are not added. 627*a070cf53SStephan Aßmus */ 628*a070cf53SStephan Aßmus void 629*a070cf53SStephan Aßmus BDate::AddDays(int32 days) 630*a070cf53SStephan Aßmus { 631*a070cf53SStephan Aßmus if (IsValid()) 632*a070cf53SStephan Aßmus *this = JulianDayToDate(DateToJulianDay() + days); 633*a070cf53SStephan Aßmus } 634*a070cf53SStephan Aßmus 635*a070cf53SStephan Aßmus 636*a070cf53SStephan Aßmus /*! 637*a070cf53SStephan Aßmus Adds \c years to the current date. If the passed value is negativ it will 638*a070cf53SStephan Aßmus become earlier. If the current date is invalid, the \c years are not added. 639*a070cf53SStephan Aßmus The day/ month combination will be adjusted if it does not exist in the 640*a070cf53SStephan Aßmus resulting year, so this function will then return the latest valid date. 641*a070cf53SStephan Aßmus */ 642*a070cf53SStephan Aßmus void 643*a070cf53SStephan Aßmus BDate::AddYears(int32 years) 644*a070cf53SStephan Aßmus { 645*a070cf53SStephan Aßmus if (IsValid()) { 646*a070cf53SStephan Aßmus const int32 tmp = fYear; 647*a070cf53SStephan Aßmus fYear += years; 648*a070cf53SStephan Aßmus 649*a070cf53SStephan Aßmus if ((tmp > 0 && fYear <= 0) || (tmp < 0 && fYear >= 0)) 650*a070cf53SStephan Aßmus fYear += (years > 0) ? +1 : -1; 651*a070cf53SStephan Aßmus 652*a070cf53SStephan Aßmus fDay = min_c(fDay, _DaysInMonth(fYear, fMonth)); 653*a070cf53SStephan Aßmus } 654*a070cf53SStephan Aßmus } 655*a070cf53SStephan Aßmus 656*a070cf53SStephan Aßmus 657*a070cf53SStephan Aßmus /*! 658*a070cf53SStephan Aßmus Adds \c months to the current date. If the passed value is negativ it will 659*a070cf53SStephan Aßmus become earlier. If the current date is invalid, the \c months are not added. 660*a070cf53SStephan Aßmus The day/ month combination will be adjusted if it does not exist in the 661*a070cf53SStephan Aßmus resulting year, so this function will then return the latest valid date. 662*a070cf53SStephan Aßmus */ 663*a070cf53SStephan Aßmus void 664*a070cf53SStephan Aßmus BDate::AddMonths(int32 months) 665*a070cf53SStephan Aßmus { 666*a070cf53SStephan Aßmus if (IsValid()) { 667*a070cf53SStephan Aßmus const int32 tmp = fYear; 668*a070cf53SStephan Aßmus fYear += months / 12; 669*a070cf53SStephan Aßmus fMonth += months % 12; 670*a070cf53SStephan Aßmus 671*a070cf53SStephan Aßmus if (fMonth > 12) { 672*a070cf53SStephan Aßmus fYear++; 673*a070cf53SStephan Aßmus fMonth -= 12; 674*a070cf53SStephan Aßmus } else if (fMonth < 1) { 675*a070cf53SStephan Aßmus fYear--; 676*a070cf53SStephan Aßmus fMonth += 12; 677*a070cf53SStephan Aßmus } 678*a070cf53SStephan Aßmus 679*a070cf53SStephan Aßmus if ((tmp > 0 && fYear <= 0) || (tmp < 0 && fYear >= 0)) 680*a070cf53SStephan Aßmus fYear += (months > 0) ? +1 : -1; 681*a070cf53SStephan Aßmus 682*a070cf53SStephan Aßmus // 'missing' days between switch julian - gregorian 683*a070cf53SStephan Aßmus if (fYear == 1582 && fMonth == 10 && fDay > 4 && fDay < 15) 684*a070cf53SStephan Aßmus fDay = (months > 0) ? 15 : 4; 685*a070cf53SStephan Aßmus 686*a070cf53SStephan Aßmus fDay = min_c(fDay, DaysInMonth()); 687*a070cf53SStephan Aßmus } 688*a070cf53SStephan Aßmus } 689*a070cf53SStephan Aßmus 690*a070cf53SStephan Aßmus 691*a070cf53SStephan Aßmus /*! 692*a070cf53SStephan Aßmus Returns the day fragment of the date. The return value will be in the range 693*a070cf53SStephan Aßmus of 1 to 31, in case the date is invalid it will be -1. 694*a070cf53SStephan Aßmus */ 695*a070cf53SStephan Aßmus int32 696*a070cf53SStephan Aßmus BDate::Day() const 697*a070cf53SStephan Aßmus { 698*a070cf53SStephan Aßmus return fDay; 699*a070cf53SStephan Aßmus } 700*a070cf53SStephan Aßmus 701*a070cf53SStephan Aßmus 702*a070cf53SStephan Aßmus /*! 703*a070cf53SStephan Aßmus Returns the year fragment of the date. If the date is invalid, the function 704*a070cf53SStephan Aßmus returns 0. 705*a070cf53SStephan Aßmus */ 706*a070cf53SStephan Aßmus int32 707*a070cf53SStephan Aßmus BDate::Year() const 708*a070cf53SStephan Aßmus { 709*a070cf53SStephan Aßmus return fYear; 710*a070cf53SStephan Aßmus } 711*a070cf53SStephan Aßmus 712*a070cf53SStephan Aßmus 713*a070cf53SStephan Aßmus /*! 714*a070cf53SStephan Aßmus Returns the month fragment of the date. The return value will be in the 715*a070cf53SStephan Aßmus range of 1 to 12, in case the date is invalid it will be -1. 716*a070cf53SStephan Aßmus */ 717*a070cf53SStephan Aßmus int32 718*a070cf53SStephan Aßmus BDate::Month() const 719*a070cf53SStephan Aßmus { 720*a070cf53SStephan Aßmus return fMonth; 721*a070cf53SStephan Aßmus } 722*a070cf53SStephan Aßmus 723*a070cf53SStephan Aßmus 724*a070cf53SStephan Aßmus /*! 725*a070cf53SStephan Aßmus Returns the difference in days between this date and the given BDate \c date. 726*a070cf53SStephan Aßmus If \c date is earlier the return value will be negativ. If the calculation 727*a070cf53SStephan Aßmus is done with an invalid date, the result is undefined. 728*a070cf53SStephan Aßmus */ 729*a070cf53SStephan Aßmus int32 730*a070cf53SStephan Aßmus BDate::Difference(const BDate& date) const 731*a070cf53SStephan Aßmus { 732*a070cf53SStephan Aßmus return date.DateToJulianDay() - DateToJulianDay(); 733*a070cf53SStephan Aßmus } 734*a070cf53SStephan Aßmus 735*a070cf53SStephan Aßmus 736*a070cf53SStephan Aßmus /*! 737*a070cf53SStephan Aßmus Returns the week number of the date, if the date is invalid it will return 738*a070cf53SStephan Aßmus B_ERROR. Please note that this function does only work within the Gregorian 739*a070cf53SStephan Aßmus calendar, thus a date before 15.10.1582 will return B_ERROR. 740*a070cf53SStephan Aßmus */ 741*a070cf53SStephan Aßmus int32 742*a070cf53SStephan Aßmus BDate::WeekNumber() const 743*a070cf53SStephan Aßmus { 744*a070cf53SStephan Aßmus /* 745*a070cf53SStephan Aßmus This algorithm is taken from: 746*a070cf53SStephan Aßmus Frequently Asked Questions about Calendars 747*a070cf53SStephan Aßmus Version 2.8 Claus Tøndering 15 December 2005 748*a070cf53SStephan Aßmus 749*a070cf53SStephan Aßmus Note: it will work only within the Gregorian Calendar 750*a070cf53SStephan Aßmus */ 751*a070cf53SStephan Aßmus 752*a070cf53SStephan Aßmus if (!IsValid() || fYear < 1582 753*a070cf53SStephan Aßmus || (fYear == 1582 && fMonth < 10) 754*a070cf53SStephan Aßmus || (fYear == 1582 && fMonth == 10 && fDay < 15)) 755*a070cf53SStephan Aßmus return int32(B_ERROR); 756*a070cf53SStephan Aßmus 757*a070cf53SStephan Aßmus int32 a; 758*a070cf53SStephan Aßmus int32 b; 759*a070cf53SStephan Aßmus int32 s; 760*a070cf53SStephan Aßmus int32 e; 761*a070cf53SStephan Aßmus int32 f; 762*a070cf53SStephan Aßmus 763*a070cf53SStephan Aßmus if (fMonth > 0 && fMonth < 3) { 764*a070cf53SStephan Aßmus a = fYear - 1; 765*a070cf53SStephan Aßmus b = (a / 4) - (a / 100) + (a / 400); 766*a070cf53SStephan Aßmus int32 c = ((a - 1) / 4) - ((a - 1) / 100) + ((a -1) / 400); 767*a070cf53SStephan Aßmus s = b - c; 768*a070cf53SStephan Aßmus e = 0; 769*a070cf53SStephan Aßmus f = fDay - 1 + 31 * (fMonth - 1); 770*a070cf53SStephan Aßmus } else if (fMonth >= 3 && fMonth <= 12) { 771*a070cf53SStephan Aßmus a = fYear; 772*a070cf53SStephan Aßmus b = (a / 4) - (a / 100) + (a / 400); 773*a070cf53SStephan Aßmus int32 c = ((a - 1) / 4) - ((a - 1) / 100) + ((a -1) / 400); 774*a070cf53SStephan Aßmus s = b - c; 775*a070cf53SStephan Aßmus e = s + 1; 776*a070cf53SStephan Aßmus f = fDay + ((153 * (fMonth - 3) + 2) / 5) + 58 + s; 777*a070cf53SStephan Aßmus } else 778*a070cf53SStephan Aßmus return int32(B_ERROR); 779*a070cf53SStephan Aßmus 780*a070cf53SStephan Aßmus int32 g = (a + b) % 7; 781*a070cf53SStephan Aßmus int32 d = (f + g - e) % 7; 782*a070cf53SStephan Aßmus int32 n = f + 3 - d; 783*a070cf53SStephan Aßmus 784*a070cf53SStephan Aßmus int32 weekNumber; 785*a070cf53SStephan Aßmus if (n < 0) 786*a070cf53SStephan Aßmus weekNumber = 53 - (g -s) / 5; 787*a070cf53SStephan Aßmus else if (n > 364 + s) 788*a070cf53SStephan Aßmus weekNumber = 1; 789*a070cf53SStephan Aßmus else 790*a070cf53SStephan Aßmus weekNumber = n / 7 + 1; 791*a070cf53SStephan Aßmus 792*a070cf53SStephan Aßmus return weekNumber; 793*a070cf53SStephan Aßmus } 794*a070cf53SStephan Aßmus 795*a070cf53SStephan Aßmus 796*a070cf53SStephan Aßmus /*! 797*a070cf53SStephan Aßmus Returns the day of the week in the range of 1 to 7, while 1 stands for 798*a070cf53SStephan Aßmus monday. If the date is invalid, the function will return B_ERROR. 799*a070cf53SStephan Aßmus */ 800*a070cf53SStephan Aßmus int32 801*a070cf53SStephan Aßmus BDate::DayOfWeek() const 802*a070cf53SStephan Aßmus { 803*a070cf53SStephan Aßmus // http://en.wikipedia.org/wiki/Julian_day#Calculation 804*a070cf53SStephan Aßmus return IsValid() ? (DateToJulianDay() % 7) + 1 : int32(B_ERROR); 805*a070cf53SStephan Aßmus } 806*a070cf53SStephan Aßmus 807*a070cf53SStephan Aßmus 808*a070cf53SStephan Aßmus /*! 809*a070cf53SStephan Aßmus Returns the day of the year in the range of 1 to 365 (366 in leap years). If 810*a070cf53SStephan Aßmus the date is invalid, the function will return B_ERROR. 811*a070cf53SStephan Aßmus */ 812*a070cf53SStephan Aßmus int32 813*a070cf53SStephan Aßmus BDate::DayOfYear() const 814*a070cf53SStephan Aßmus { 815*a070cf53SStephan Aßmus if (!IsValid()) 816*a070cf53SStephan Aßmus return int32(B_ERROR); 817*a070cf53SStephan Aßmus 818*a070cf53SStephan Aßmus return DateToJulianDay() - _DateToJulianDay(fYear, 1, 1) + 1; 819*a070cf53SStephan Aßmus } 820*a070cf53SStephan Aßmus 821*a070cf53SStephan Aßmus 822*a070cf53SStephan Aßmus /*! 823*a070cf53SStephan Aßmus Returns true if the passed \c year is a leap year, otherwise false. If the 824*a070cf53SStephan Aßmus \c year passed is before 4713 BC, the result is undefined. 825*a070cf53SStephan Aßmus */ 826*a070cf53SStephan Aßmus bool 827*a070cf53SStephan Aßmus BDate::IsLeapYear(int32 year) const 828*a070cf53SStephan Aßmus { 829*a070cf53SStephan Aßmus if (year < 1582) { 830*a070cf53SStephan Aßmus if (year < 0) 831*a070cf53SStephan Aßmus year++; 832*a070cf53SStephan Aßmus return (year % 4) == 0; 833*a070cf53SStephan Aßmus } 834*a070cf53SStephan Aßmus return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0); 835*a070cf53SStephan Aßmus } 836*a070cf53SStephan Aßmus 837*a070cf53SStephan Aßmus 838*a070cf53SStephan Aßmus /*! 839*a070cf53SStephan Aßmus Returns the number of days in the year of the current date. If the date is 840*a070cf53SStephan Aßmus valid it will return 365 or 366, otherwise B_ERROR; 841*a070cf53SStephan Aßmus */ 842*a070cf53SStephan Aßmus int32 843*a070cf53SStephan Aßmus BDate::DaysInYear() const 844*a070cf53SStephan Aßmus { 845*a070cf53SStephan Aßmus if (!IsValid()) 846*a070cf53SStephan Aßmus return int32(B_ERROR); 847*a070cf53SStephan Aßmus 848*a070cf53SStephan Aßmus return IsLeapYear(fYear) ? 366 : 365; 849*a070cf53SStephan Aßmus } 850*a070cf53SStephan Aßmus 851*a070cf53SStephan Aßmus 852*a070cf53SStephan Aßmus /*! 853*a070cf53SStephan Aßmus Returns the number of days in the month of the current date. If the date is 854*a070cf53SStephan Aßmus valid it will return 28 up to 31, otherwise B_ERROR; 855*a070cf53SStephan Aßmus */ 856*a070cf53SStephan Aßmus int32 857*a070cf53SStephan Aßmus BDate::DaysInMonth() const 858*a070cf53SStephan Aßmus { 859*a070cf53SStephan Aßmus if (!IsValid()) 860*a070cf53SStephan Aßmus return int32(B_ERROR); 861*a070cf53SStephan Aßmus 862*a070cf53SStephan Aßmus return _DaysInMonth(fYear, fMonth); 863*a070cf53SStephan Aßmus } 864*a070cf53SStephan Aßmus 865*a070cf53SStephan Aßmus 866*a070cf53SStephan Aßmus /*! 867*a070cf53SStephan Aßmus Returns the short day name in case of an valid day, otherwise an empty 868*a070cf53SStephan Aßmus string. The passed \c day must be in the range of 1 to 7 while 1 stands for 869*a070cf53SStephan Aßmus monday. 870*a070cf53SStephan Aßmus */ 871*a070cf53SStephan Aßmus BString 872*a070cf53SStephan Aßmus BDate::ShortDayName(int32 day) const 873*a070cf53SStephan Aßmus { 874*a070cf53SStephan Aßmus if (day < 1 || day > 7) 875*a070cf53SStephan Aßmus return BString(); 876*a070cf53SStephan Aßmus 877*a070cf53SStephan Aßmus tm tm_struct; 878*a070cf53SStephan Aßmus memset(&tm_struct, 0, sizeof(tm)); 879*a070cf53SStephan Aßmus tm_struct.tm_wday = day == 7 ? 0 : day; 880*a070cf53SStephan Aßmus 881*a070cf53SStephan Aßmus char buffer[256]; 882*a070cf53SStephan Aßmus strftime(buffer, sizeof(buffer), "%a", &tm_struct); 883*a070cf53SStephan Aßmus 884*a070cf53SStephan Aßmus return BString(buffer); 885*a070cf53SStephan Aßmus } 886*a070cf53SStephan Aßmus 887*a070cf53SStephan Aßmus 888*a070cf53SStephan Aßmus /*! 889*a070cf53SStephan Aßmus Returns the short month name in case of an valid month, otherwise an empty 890*a070cf53SStephan Aßmus string. The passed \c month must be in the range of 1 to 12. 891*a070cf53SStephan Aßmus */ 892*a070cf53SStephan Aßmus BString 893*a070cf53SStephan Aßmus BDate::ShortMonthName(int32 month) const 894*a070cf53SStephan Aßmus { 895*a070cf53SStephan Aßmus if (month < 1 || month > 12) 896*a070cf53SStephan Aßmus return BString(); 897*a070cf53SStephan Aßmus 898*a070cf53SStephan Aßmus tm tm_struct; 899*a070cf53SStephan Aßmus memset(&tm_struct, 0, sizeof(tm)); 900*a070cf53SStephan Aßmus tm_struct.tm_mon = month - 1; 901*a070cf53SStephan Aßmus 902*a070cf53SStephan Aßmus char buffer[256]; 903*a070cf53SStephan Aßmus strftime(buffer, sizeof(buffer), "%b", &tm_struct); 904*a070cf53SStephan Aßmus 905*a070cf53SStephan Aßmus return BString(buffer); 906*a070cf53SStephan Aßmus } 907*a070cf53SStephan Aßmus 908*a070cf53SStephan Aßmus 909*a070cf53SStephan Aßmus /*! 910*a070cf53SStephan Aßmus Returns the long day name in case of an valid day, otherwise an empty 911*a070cf53SStephan Aßmus string. The passed \c day must be in the range of 1 to 7 while 1 stands for 912*a070cf53SStephan Aßmus monday. 913*a070cf53SStephan Aßmus */ 914*a070cf53SStephan Aßmus BString 915*a070cf53SStephan Aßmus BDate::LongDayName(int32 day) const 916*a070cf53SStephan Aßmus { 917*a070cf53SStephan Aßmus if (day < 1 || day > 7) 918*a070cf53SStephan Aßmus return BString(); 919*a070cf53SStephan Aßmus 920*a070cf53SStephan Aßmus tm tm_struct; 921*a070cf53SStephan Aßmus memset(&tm_struct, 0, sizeof(tm)); 922*a070cf53SStephan Aßmus tm_struct.tm_wday = day == 7 ? 0 : day; 923*a070cf53SStephan Aßmus 924*a070cf53SStephan Aßmus char buffer[256]; 925*a070cf53SStephan Aßmus strftime(buffer, sizeof(buffer), "%A", &tm_struct); 926*a070cf53SStephan Aßmus 927*a070cf53SStephan Aßmus return BString(buffer); 928*a070cf53SStephan Aßmus } 929*a070cf53SStephan Aßmus 930*a070cf53SStephan Aßmus 931*a070cf53SStephan Aßmus /*! 932*a070cf53SStephan Aßmus Returns the long month name in case of an valid month, otherwise an empty 933*a070cf53SStephan Aßmus string. The passed \c month must be in the range of 1 to 12. 934*a070cf53SStephan Aßmus */ 935*a070cf53SStephan Aßmus BString 936*a070cf53SStephan Aßmus BDate::LongMonthName(int32 month) const 937*a070cf53SStephan Aßmus { 938*a070cf53SStephan Aßmus if (month < 1 || month > 12) 939*a070cf53SStephan Aßmus return BString(); 940*a070cf53SStephan Aßmus 941*a070cf53SStephan Aßmus tm tm_struct; 942*a070cf53SStephan Aßmus memset(&tm_struct, 0, sizeof(tm)); 943*a070cf53SStephan Aßmus tm_struct.tm_mon = month - 1; 944*a070cf53SStephan Aßmus 945*a070cf53SStephan Aßmus char buffer[256]; 946*a070cf53SStephan Aßmus strftime(buffer, sizeof(buffer), "%B", &tm_struct); 947*a070cf53SStephan Aßmus 948*a070cf53SStephan Aßmus return BString(buffer); 949*a070cf53SStephan Aßmus } 950*a070cf53SStephan Aßmus 951*a070cf53SStephan Aßmus 952*a070cf53SStephan Aßmus /*! 953*a070cf53SStephan Aßmus Converts the date to Julian day. If your date is invalid, the function will 954*a070cf53SStephan Aßmus return B_ERROR. 955*a070cf53SStephan Aßmus */ 956*a070cf53SStephan Aßmus int32 957*a070cf53SStephan Aßmus BDate::DateToJulianDay() const 958*a070cf53SStephan Aßmus { 959*a070cf53SStephan Aßmus return _DateToJulianDay(fYear, fMonth, fDay); 960*a070cf53SStephan Aßmus } 961*a070cf53SStephan Aßmus 962*a070cf53SStephan Aßmus 963*a070cf53SStephan Aßmus /* 964*a070cf53SStephan Aßmus Converts the passed \c julianDay to an BDate. If the \c julianDay is negativ, 965*a070cf53SStephan Aßmus the function will return an invalid date. Because of the switch from Julian 966*a070cf53SStephan Aßmus calendar to Gregorian calendar the 4.10.1582 is followed by the 15.10.1582. 967*a070cf53SStephan Aßmus */ 968*a070cf53SStephan Aßmus BDate 969*a070cf53SStephan Aßmus BDate::JulianDayToDate(int32 julianDay) 970*a070cf53SStephan Aßmus { 971*a070cf53SStephan Aßmus BDate date; 972*a070cf53SStephan Aßmus const int32 kGregorianCalendarStart = 2299161; 973*a070cf53SStephan Aßmus if (julianDay >= kGregorianCalendarStart) { 974*a070cf53SStephan Aßmus // http://en.wikipedia.org/wiki/Julian_day#Gregorian_calendar_from_Julian_day_number 975*a070cf53SStephan Aßmus int32 j = julianDay + 32044; 976*a070cf53SStephan Aßmus int32 dg = j % 146097; 977*a070cf53SStephan Aßmus int32 c = (dg / 36524 + 1) * 3 / 4; 978*a070cf53SStephan Aßmus int32 dc = dg - c * 36524; 979*a070cf53SStephan Aßmus int32 db = dc % 1461; 980*a070cf53SStephan Aßmus int32 a = (db / 365 + 1) * 3 / 4; 981*a070cf53SStephan Aßmus int32 da = db - a * 365; 982*a070cf53SStephan Aßmus int32 m = (da * 5 + 308) / 153 - 2; 983*a070cf53SStephan Aßmus date.fYear = ((j / 146097) * 400 + c * 100 + (dc / 1461) * 4 + a) - 4800 + 984*a070cf53SStephan Aßmus (m + 2) / 12; 985*a070cf53SStephan Aßmus date.fMonth = (m + 2) % 12 + 1; 986*a070cf53SStephan Aßmus date.fDay = int32((da - (m + 4) * 153 / 5 + 122) + 1.5); 987*a070cf53SStephan Aßmus } else if (julianDay >= 0) { 988*a070cf53SStephan Aßmus // http://en.wikipedia.org/wiki/Julian_day#Calculation 989*a070cf53SStephan Aßmus julianDay += 32082; 990*a070cf53SStephan Aßmus int32 d = (4 * julianDay + 3) / 1461; 991*a070cf53SStephan Aßmus int32 e = julianDay - (1461 * d) / 4; 992*a070cf53SStephan Aßmus int32 m = ((5 * e) + 2) / 153; 993*a070cf53SStephan Aßmus date.fDay = e - (153 * m + 2) / 5 + 1; 994*a070cf53SStephan Aßmus date.fMonth = m + 3 - 12 * (m / 10); 995*a070cf53SStephan Aßmus int32 year = d - 4800 + (m / 10); 996*a070cf53SStephan Aßmus if (year <= 0) 997*a070cf53SStephan Aßmus year--; 998*a070cf53SStephan Aßmus date.fYear = year; 999*a070cf53SStephan Aßmus } 1000*a070cf53SStephan Aßmus return date; 1001*a070cf53SStephan Aßmus } 1002*a070cf53SStephan Aßmus 1003*a070cf53SStephan Aßmus 1004*a070cf53SStephan Aßmus /*! 1005*a070cf53SStephan Aßmus Returns true if this date is different from \c date, otherwise false. 1006*a070cf53SStephan Aßmus */ 1007*a070cf53SStephan Aßmus bool 1008*a070cf53SStephan Aßmus BDate::operator!=(const BDate& date) const 1009*a070cf53SStephan Aßmus { 1010*a070cf53SStephan Aßmus return DateToJulianDay() != date.DateToJulianDay(); 1011*a070cf53SStephan Aßmus } 1012*a070cf53SStephan Aßmus 1013*a070cf53SStephan Aßmus 1014*a070cf53SStephan Aßmus /*! 1015*a070cf53SStephan Aßmus Returns true if this date is equal to \c date, otherwise false. 1016*a070cf53SStephan Aßmus */ 1017*a070cf53SStephan Aßmus bool 1018*a070cf53SStephan Aßmus BDate::operator==(const BDate& date) const 1019*a070cf53SStephan Aßmus { 1020*a070cf53SStephan Aßmus return DateToJulianDay() == date.DateToJulianDay(); 1021*a070cf53SStephan Aßmus } 1022*a070cf53SStephan Aßmus 1023*a070cf53SStephan Aßmus 1024*a070cf53SStephan Aßmus /*! 1025*a070cf53SStephan Aßmus Returns true if this date is earlier than \c date, otherwise false. 1026*a070cf53SStephan Aßmus */ 1027*a070cf53SStephan Aßmus bool 1028*a070cf53SStephan Aßmus BDate::operator<(const BDate& date) const 1029*a070cf53SStephan Aßmus { 1030*a070cf53SStephan Aßmus return DateToJulianDay() < date.DateToJulianDay(); 1031*a070cf53SStephan Aßmus } 1032*a070cf53SStephan Aßmus 1033*a070cf53SStephan Aßmus 1034*a070cf53SStephan Aßmus /*! 1035*a070cf53SStephan Aßmus Returns true if this date is earlier than or equal to \c date, otherwise false. 1036*a070cf53SStephan Aßmus */ 1037*a070cf53SStephan Aßmus bool 1038*a070cf53SStephan Aßmus BDate::operator<=(const BDate& date) const 1039*a070cf53SStephan Aßmus { 1040*a070cf53SStephan Aßmus return DateToJulianDay() <= date.DateToJulianDay(); 1041*a070cf53SStephan Aßmus } 1042*a070cf53SStephan Aßmus 1043*a070cf53SStephan Aßmus 1044*a070cf53SStephan Aßmus /*! 1045*a070cf53SStephan Aßmus Returns true if this date is later than \c date, otherwise false. 1046*a070cf53SStephan Aßmus */ 1047*a070cf53SStephan Aßmus bool 1048*a070cf53SStephan Aßmus BDate::operator>(const BDate& date) const 1049*a070cf53SStephan Aßmus { 1050*a070cf53SStephan Aßmus return DateToJulianDay() > date.DateToJulianDay(); 1051*a070cf53SStephan Aßmus } 1052*a070cf53SStephan Aßmus 1053*a070cf53SStephan Aßmus 1054*a070cf53SStephan Aßmus /*! 1055*a070cf53SStephan Aßmus Returns true if this date is later than or equal to \c date, otherwise false. 1056*a070cf53SStephan Aßmus */ 1057*a070cf53SStephan Aßmus bool 1058*a070cf53SStephan Aßmus BDate::operator>=(const BDate& date) const 1059*a070cf53SStephan Aßmus { 1060*a070cf53SStephan Aßmus return DateToJulianDay() >= date.DateToJulianDay(); 1061*a070cf53SStephan Aßmus } 1062*a070cf53SStephan Aßmus 1063*a070cf53SStephan Aßmus 1064*a070cf53SStephan Aßmus bool 1065*a070cf53SStephan Aßmus BDate::_SetDate(int32 year, int32 month, int32 day) 1066*a070cf53SStephan Aßmus { 1067*a070cf53SStephan Aßmus fDay = -1; 1068*a070cf53SStephan Aßmus fYear = 0; 1069*a070cf53SStephan Aßmus fMonth = -1; 1070*a070cf53SStephan Aßmus 1071*a070cf53SStephan Aßmus bool valid = IsValid(year, month, day); 1072*a070cf53SStephan Aßmus if (valid) { 1073*a070cf53SStephan Aßmus fDay = day; 1074*a070cf53SStephan Aßmus fYear = year; 1075*a070cf53SStephan Aßmus fMonth = month; 1076*a070cf53SStephan Aßmus } 1077*a070cf53SStephan Aßmus 1078*a070cf53SStephan Aßmus return valid; 1079*a070cf53SStephan Aßmus } 1080*a070cf53SStephan Aßmus 1081*a070cf53SStephan Aßmus 1082*a070cf53SStephan Aßmus int32 1083*a070cf53SStephan Aßmus BDate::_DaysInMonth(int32 year, int32 month) const 1084*a070cf53SStephan Aßmus { 1085*a070cf53SStephan Aßmus if (month == 2 && IsLeapYear(year)) 1086*a070cf53SStephan Aßmus return 29; 1087*a070cf53SStephan Aßmus 1088*a070cf53SStephan Aßmus const int32 daysInMonth[12] = 1089*a070cf53SStephan Aßmus {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 1090*a070cf53SStephan Aßmus 1091*a070cf53SStephan Aßmus return daysInMonth[month -1]; 1092*a070cf53SStephan Aßmus } 1093*a070cf53SStephan Aßmus 1094*a070cf53SStephan Aßmus 1095*a070cf53SStephan Aßmus int32 1096*a070cf53SStephan Aßmus BDate::_DateToJulianDay(int32 _year, int32 month, int32 day) const 1097*a070cf53SStephan Aßmus { 1098*a070cf53SStephan Aßmus if (IsValid(_year, month, day)) { 1099*a070cf53SStephan Aßmus int32 year = _year; 1100*a070cf53SStephan Aßmus if (year < 0) year++; 1101*a070cf53SStephan Aßmus 1102*a070cf53SStephan Aßmus int32 a = (14 - month) / 12; 1103*a070cf53SStephan Aßmus int32 y = year + 4800 - a; 1104*a070cf53SStephan Aßmus int32 m = month + (12 * a) - 3; 1105*a070cf53SStephan Aßmus 1106*a070cf53SStephan Aßmus // http://en.wikipedia.org/wiki/Julian_day#Calculation 1107*a070cf53SStephan Aßmus if (year > 1582 1108*a070cf53SStephan Aßmus || (year == 1582 && month > 10) 1109*a070cf53SStephan Aßmus || (year == 1582 && month == 10 && day >= 15)) { 1110*a070cf53SStephan Aßmus return day + (((153 * m) + 2) / 5) + (365 * y) + (y / 4) - 1111*a070cf53SStephan Aßmus (y / 100) + (y / 400) - 32045; 1112*a070cf53SStephan Aßmus } else if (year < 1582 1113*a070cf53SStephan Aßmus || (year == 1582 && month < 10) 1114*a070cf53SStephan Aßmus || (year == 1582 && month == 10 && day <= 4)) { 1115*a070cf53SStephan Aßmus return day + (((153 * m) + 2) / 5) + (365 * y) + (y / 4) - 32083; 1116*a070cf53SStephan Aßmus } 1117*a070cf53SStephan Aßmus } 1118*a070cf53SStephan Aßmus 1119*a070cf53SStephan Aßmus // http://en.wikipedia.org/wiki/Gregorian_calendar: 1120*a070cf53SStephan Aßmus // The last day of the Julian calendar was Thursday October 4, 1582 1121*a070cf53SStephan Aßmus // and this was followed by the first day of the Gregorian calendar, 1122*a070cf53SStephan Aßmus // Friday October 15, 1582 (the cycle of weekdays was not affected). 1123*a070cf53SStephan Aßmus return int32(B_ERROR); 1124*a070cf53SStephan Aßmus } 1125*a070cf53SStephan Aßmus 1126*a070cf53SStephan Aßmus 1127*a070cf53SStephan Aßmus // #pragma mark - BDateTime 1128*a070cf53SStephan Aßmus 1129*a070cf53SStephan Aßmus 1130*a070cf53SStephan Aßmus /*! 1131*a070cf53SStephan Aßmus Constructs a new BDateTime object. IsValid() will return false. 1132*a070cf53SStephan Aßmus */ 1133*a070cf53SStephan Aßmus BDateTime::BDateTime() 1134*a070cf53SStephan Aßmus : fDate(), 1135*a070cf53SStephan Aßmus fTime() 1136*a070cf53SStephan Aßmus { 1137*a070cf53SStephan Aßmus } 1138*a070cf53SStephan Aßmus 1139*a070cf53SStephan Aßmus 1140*a070cf53SStephan Aßmus /*! 1141*a070cf53SStephan Aßmus Constructs a BDateTime object with \c date and \c time. The return value 1142*a070cf53SStephan Aßmus of IsValid() depends on the validity of the passed objects. 1143*a070cf53SStephan Aßmus */ 1144*a070cf53SStephan Aßmus BDateTime::BDateTime(const BDate& date, const BTime& time) 1145*a070cf53SStephan Aßmus : fDate(date), 1146*a070cf53SStephan Aßmus fTime(time) 1147*a070cf53SStephan Aßmus { 1148*a070cf53SStephan Aßmus } 1149*a070cf53SStephan Aßmus 1150*a070cf53SStephan Aßmus 1151*a070cf53SStephan Aßmus /*! 1152*a070cf53SStephan Aßmus Constructs a new BDateTime object. IsValid() will return false. 1153*a070cf53SStephan Aßmus */ 1154*a070cf53SStephan Aßmus BDateTime::BDateTime(const BMessage* archive) 1155*a070cf53SStephan Aßmus : fDate(archive), 1156*a070cf53SStephan Aßmus fTime(archive) 1157*a070cf53SStephan Aßmus { 1158*a070cf53SStephan Aßmus } 1159*a070cf53SStephan Aßmus 1160*a070cf53SStephan Aßmus 1161*a070cf53SStephan Aßmus /*! 1162*a070cf53SStephan Aßmus Empty destructor. 1163*a070cf53SStephan Aßmus */ 1164*a070cf53SStephan Aßmus BDateTime::~BDateTime() 1165*a070cf53SStephan Aßmus { 1166*a070cf53SStephan Aßmus } 1167*a070cf53SStephan Aßmus 1168*a070cf53SStephan Aßmus 1169*a070cf53SStephan Aßmus /*! 1170*a070cf53SStephan Aßmus Archives the BDateTime object into the provided BMessage object. 1171*a070cf53SStephan Aßmus @returns \c B_OK if all went well. 1172*a070cf53SStephan Aßmus \c B_BAD_VALUE, if the message is \c NULL. 1173*a070cf53SStephan Aßmus \c other error codes, depending on failure to append 1174*a070cf53SStephan Aßmus fields to the message. 1175*a070cf53SStephan Aßmus */ 1176*a070cf53SStephan Aßmus status_t 1177*a070cf53SStephan Aßmus BDateTime::Archive(BMessage* into) const 1178*a070cf53SStephan Aßmus { 1179*a070cf53SStephan Aßmus status_t ret = fDate.Archive(into); 1180*a070cf53SStephan Aßmus if (ret == B_OK) 1181*a070cf53SStephan Aßmus ret = fTime.Archive(into); 1182*a070cf53SStephan Aßmus return ret; 1183*a070cf53SStephan Aßmus } 1184*a070cf53SStephan Aßmus 1185*a070cf53SStephan Aßmus 1186*a070cf53SStephan Aßmus /*! 1187*a070cf53SStephan Aßmus Returns true if the date time is valid, otherwise false. 1188*a070cf53SStephan Aßmus */ 1189*a070cf53SStephan Aßmus bool 1190*a070cf53SStephan Aßmus BDateTime::IsValid() const 1191*a070cf53SStephan Aßmus { 1192*a070cf53SStephan Aßmus return fDate.IsValid() && fTime.IsValid(); 1193*a070cf53SStephan Aßmus } 1194*a070cf53SStephan Aßmus 1195*a070cf53SStephan Aßmus 1196*a070cf53SStephan Aßmus /*! 1197*a070cf53SStephan Aßmus Returns the current date and time as reported by the system depending on the 1198*a070cf53SStephan Aßmus given time_type \c type. 1199*a070cf53SStephan Aßmus */ 1200*a070cf53SStephan Aßmus BDateTime 1201*a070cf53SStephan Aßmus BDateTime::CurrentDateTime(time_type type) 1202*a070cf53SStephan Aßmus { 1203*a070cf53SStephan Aßmus return BDateTime(BDate::CurrentDate(type), BTime::CurrentTime(type)); 1204*a070cf53SStephan Aßmus } 1205*a070cf53SStephan Aßmus 1206*a070cf53SStephan Aßmus 1207*a070cf53SStephan Aßmus /*! 1208*a070cf53SStephan Aßmus Sets the current date and time of this object to \c date and \c time. 1209*a070cf53SStephan Aßmus */ 1210*a070cf53SStephan Aßmus void 1211*a070cf53SStephan Aßmus BDateTime::SetDateTime(const BDate& date, const BTime& time) 1212*a070cf53SStephan Aßmus { 1213*a070cf53SStephan Aßmus fDate = date; 1214*a070cf53SStephan Aßmus fTime = time; 1215*a070cf53SStephan Aßmus } 1216*a070cf53SStephan Aßmus 1217*a070cf53SStephan Aßmus 1218*a070cf53SStephan Aßmus /*! 1219*a070cf53SStephan Aßmus Returns the current date of this object. 1220*a070cf53SStephan Aßmus */ 1221*a070cf53SStephan Aßmus BDate 1222*a070cf53SStephan Aßmus BDateTime::Date() const 1223*a070cf53SStephan Aßmus { 1224*a070cf53SStephan Aßmus return fDate; 1225*a070cf53SStephan Aßmus } 1226*a070cf53SStephan Aßmus 1227*a070cf53SStephan Aßmus 1228*a070cf53SStephan Aßmus /*! 1229*a070cf53SStephan Aßmus Set the current date of this object to \c date. 1230*a070cf53SStephan Aßmus */ 1231*a070cf53SStephan Aßmus void 1232*a070cf53SStephan Aßmus BDateTime::SetDate(const BDate& date) 1233*a070cf53SStephan Aßmus { 1234*a070cf53SStephan Aßmus fDate = date; 1235*a070cf53SStephan Aßmus } 1236*a070cf53SStephan Aßmus 1237*a070cf53SStephan Aßmus 1238*a070cf53SStephan Aßmus /*! 1239*a070cf53SStephan Aßmus Returns the current time of this object. 1240*a070cf53SStephan Aßmus */ 1241*a070cf53SStephan Aßmus BTime 1242*a070cf53SStephan Aßmus BDateTime::Time() const 1243*a070cf53SStephan Aßmus { 1244*a070cf53SStephan Aßmus return fTime; 1245*a070cf53SStephan Aßmus } 1246*a070cf53SStephan Aßmus 1247*a070cf53SStephan Aßmus 1248*a070cf53SStephan Aßmus /*! 1249*a070cf53SStephan Aßmus Sets the current time of this object to \c time. 1250*a070cf53SStephan Aßmus */ 1251*a070cf53SStephan Aßmus void 1252*a070cf53SStephan Aßmus BDateTime::SetTime(const BTime& time) 1253*a070cf53SStephan Aßmus { 1254*a070cf53SStephan Aßmus fTime = time; 1255*a070cf53SStephan Aßmus } 1256*a070cf53SStephan Aßmus 1257*a070cf53SStephan Aßmus 1258*a070cf53SStephan Aßmus /*! 1259*a070cf53SStephan Aßmus Returns the current date and time converted to seconds since 1260*a070cf53SStephan Aßmus 1.1.1970 - 00:00:00. If the current date is before 1.1.1970 the function 1261*a070cf53SStephan Aßmus returns -1; 1262*a070cf53SStephan Aßmus */ 1263*a070cf53SStephan Aßmus int32 1264*a070cf53SStephan Aßmus BDateTime::Time_t() const 1265*a070cf53SStephan Aßmus { 1266*a070cf53SStephan Aßmus BDate date(1970, 1, 1); 1267*a070cf53SStephan Aßmus if (date.Difference(fDate) < 0) 1268*a070cf53SStephan Aßmus return -1; 1269*a070cf53SStephan Aßmus 1270*a070cf53SStephan Aßmus tm tm_struct; 1271*a070cf53SStephan Aßmus 1272*a070cf53SStephan Aßmus tm_struct.tm_hour = fTime.Hour(); 1273*a070cf53SStephan Aßmus tm_struct.tm_min = fTime.Minute(); 1274*a070cf53SStephan Aßmus tm_struct.tm_sec = fTime.Second(); 1275*a070cf53SStephan Aßmus 1276*a070cf53SStephan Aßmus tm_struct.tm_year = fDate.Year() - 1900; 1277*a070cf53SStephan Aßmus tm_struct.tm_mon = fDate.Month() - 1; 1278*a070cf53SStephan Aßmus tm_struct.tm_mday = fDate.Day(); 1279*a070cf53SStephan Aßmus 1280*a070cf53SStephan Aßmus // set less 0 as we wan't use it 1281*a070cf53SStephan Aßmus tm_struct.tm_isdst = -1; 1282*a070cf53SStephan Aßmus 1283*a070cf53SStephan Aßmus // return secs_since_jan1_1970 or -1 on error 1284*a070cf53SStephan Aßmus return int32(mktime(&tm_struct)); 1285*a070cf53SStephan Aßmus } 1286*a070cf53SStephan Aßmus 1287*a070cf53SStephan Aßmus 1288*a070cf53SStephan Aßmus /*! 1289*a070cf53SStephan Aßmus Sets the current date and time converted from seconds since 1290*a070cf53SStephan Aßmus 1.1.1970 - 00:00:00. 1291*a070cf53SStephan Aßmus */ 1292*a070cf53SStephan Aßmus void 1293*a070cf53SStephan Aßmus BDateTime::SetTime_t(uint32 seconds) 1294*a070cf53SStephan Aßmus { 1295*a070cf53SStephan Aßmus BTime time; 1296*a070cf53SStephan Aßmus time.AddSeconds(seconds % kSecondsPerDay); 1297*a070cf53SStephan Aßmus fTime.SetTime(time); 1298*a070cf53SStephan Aßmus 1299*a070cf53SStephan Aßmus BDate date(1970, 1, 1); 1300*a070cf53SStephan Aßmus date.AddDays(seconds / kSecondsPerDay); 1301*a070cf53SStephan Aßmus fDate.SetDate(date); 1302*a070cf53SStephan Aßmus } 1303*a070cf53SStephan Aßmus 1304*a070cf53SStephan Aßmus 1305*a070cf53SStephan Aßmus /*! 1306*a070cf53SStephan Aßmus Returns true if this datetime is different from \c dateTime, otherwise false. 1307*a070cf53SStephan Aßmus */ 1308*a070cf53SStephan Aßmus bool 1309*a070cf53SStephan Aßmus BDateTime::operator!=(const BDateTime& dateTime) const 1310*a070cf53SStephan Aßmus { 1311*a070cf53SStephan Aßmus return fTime != dateTime.fTime && fDate != dateTime.fDate; 1312*a070cf53SStephan Aßmus } 1313*a070cf53SStephan Aßmus 1314*a070cf53SStephan Aßmus 1315*a070cf53SStephan Aßmus /*! 1316*a070cf53SStephan Aßmus Returns true if this datetime is equal to \c dateTime, otherwise false. 1317*a070cf53SStephan Aßmus */ 1318*a070cf53SStephan Aßmus bool 1319*a070cf53SStephan Aßmus BDateTime::operator==(const BDateTime& dateTime) const 1320*a070cf53SStephan Aßmus { 1321*a070cf53SStephan Aßmus return fTime == dateTime.fTime && fDate == dateTime.fDate; 1322*a070cf53SStephan Aßmus } 1323*a070cf53SStephan Aßmus 1324*a070cf53SStephan Aßmus 1325*a070cf53SStephan Aßmus /*! 1326*a070cf53SStephan Aßmus Returns true if this datetime is earlier than \c dateTime, otherwise false. 1327*a070cf53SStephan Aßmus */ 1328*a070cf53SStephan Aßmus bool 1329*a070cf53SStephan Aßmus BDateTime::operator<(const BDateTime& dateTime) const 1330*a070cf53SStephan Aßmus { 1331*a070cf53SStephan Aßmus return fTime < dateTime.fTime && fDate < dateTime.fDate; 1332*a070cf53SStephan Aßmus } 1333*a070cf53SStephan Aßmus 1334*a070cf53SStephan Aßmus 1335*a070cf53SStephan Aßmus /*! 1336*a070cf53SStephan Aßmus Returns true if this datetime is earlier than or equal to \c dateTime, 1337*a070cf53SStephan Aßmus otherwise false. 1338*a070cf53SStephan Aßmus */ 1339*a070cf53SStephan Aßmus bool 1340*a070cf53SStephan Aßmus BDateTime::operator<=(const BDateTime& dateTime) const 1341*a070cf53SStephan Aßmus { 1342*a070cf53SStephan Aßmus return fTime <= dateTime.fTime && fDate <= dateTime.fDate; 1343*a070cf53SStephan Aßmus } 1344*a070cf53SStephan Aßmus 1345*a070cf53SStephan Aßmus 1346*a070cf53SStephan Aßmus /*! 1347*a070cf53SStephan Aßmus Returns true if this datetime is later than \c dateTime, otherwise false. 1348*a070cf53SStephan Aßmus */ 1349*a070cf53SStephan Aßmus bool 1350*a070cf53SStephan Aßmus BDateTime::operator>(const BDateTime& dateTime) const 1351*a070cf53SStephan Aßmus { 1352*a070cf53SStephan Aßmus return fTime > dateTime.fTime && fDate > dateTime.fDate; 1353*a070cf53SStephan Aßmus } 1354*a070cf53SStephan Aßmus 1355*a070cf53SStephan Aßmus 1356*a070cf53SStephan Aßmus /*! 1357*a070cf53SStephan Aßmus Returns true if this datetime is later than or equal to \c dateTime, 1358*a070cf53SStephan Aßmus otherwise false. 1359*a070cf53SStephan Aßmus */ 1360*a070cf53SStephan Aßmus bool 1361*a070cf53SStephan Aßmus BDateTime::operator>=(const BDateTime& dateTime) const 1362*a070cf53SStephan Aßmus { 1363*a070cf53SStephan Aßmus return fTime >= dateTime.fTime && fDate >= dateTime.fDate; 1364*a070cf53SStephan Aßmus } 1365*a070cf53SStephan Aßmus 1366*a070cf53SStephan Aßmus 1367*a070cf53SStephan Aßmus } //namespace BPrivate 1368