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