diff --git a/DateTime.cpp b/DateTime.cpp index 8db5fee..04e2b01 100644 --- a/DateTime.cpp +++ b/DateTime.cpp @@ -2,6 +2,8 @@ #include +#include + namespace ProDOS { /* @@ -20,9 +22,25 @@ namespace ProDOS { * +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ * */ -DateTime::DateTime() + + +/* + * ProDOS technote 28 + * + * The following definition allows the same range of years that the Apple IIgs + * Control Panel CDA currently does: + * + * o A seven-bit ProDOS year value is in the range 0 to 99 + * (100 through 127 are invalid) + * o Year values from 40 to 99 represent 1940 through 1999 + * o Year values from 0 to 39 represent 2000 through 2039 + */ + + +DateTime::DateTime() : + _yymmdd(0), _hhmm(0) { - DateTime(time(NULL)); + init(::time(NULL)); } DateTime::DateTime(uint32_t dtm) : @@ -35,21 +53,32 @@ DateTime::DateTime(unsigned yymmdd, unsigned hhmm) : { } -DateTime::DateTime(time_t time) +DateTime::DateTime(time_t time) : + _yymmdd(0), _hhmm(0) { - tm t; - - localtime_r(&time, &t); - - DateTime(t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min); - + init(time); } DateTime::DateTime(unsigned year, unsigned month, unsigned day, - unsigned hour, unsigned minute) + unsigned hour, unsigned minute) : + _yymmdd(0), _hhmm(0) { - + init(year, month, day, hour, minute); +} + +void DateTime::init(time_t time) +{ + tm t; + ::localtime_r(&time, &t); + init(t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min); +} + +void DateTime::init(unsigned year, unsigned month, unsigned day, unsigned hour, unsigned minute) +{ + + //printf("%d %d %d %d %d\n", year, month, day, hour, minute); + // 1940 is the earliest year, so clamp to 1940-01-01 00:00 if (year < 1940) { @@ -68,34 +97,19 @@ DateTime::DateTime(unsigned year, unsigned month, unsigned day, if (year >= 2000) year -= 2000; else year -= 1900; - _hhmm = minute | (hour << 8); _yymmdd = day | (month << 5) | (year << 9); } -/* - * ProDOS technote 28 - * - * The following definition allows the same range of years that the Apple IIgs - * Control Panel CDA currently does: - * - * o A seven-bit ProDOS year value is in the range 0 to 99 - * (100 through 127 are invalid) - * o Year values from 40 to 99 represent 1940 through 1999 - * o Year values from 0 to 39 represent 2000 through 2039 - */ - - unsigned DateTime::year() const { unsigned tmp = _yymmdd >> 9; - if (tmp == 0 || tmp > 100) return 0; + //if (tmp > 100) return 0; - if (tmp <= 39) tmp += 2000; - else tmp += 1900; + if (tmp <= 39) tmp += 100; - return tmp; + return tmp + 1900; } /* @@ -112,18 +126,17 @@ time_t DateTime::toUnix() const if (_yymmdd == 0) return 0; - bzero(&t, sizeof(tm)); + ::bzero(&t, sizeof(tm)); t.tm_min = minute(); - // tm_hour is 0-23, but is_dst -1 compensates - t.tm_hour = hour() - 1; + t.tm_hour = hour(); t.tm_isdst = -1; t.tm_mday = day(); t.tm_mon = month() - 1; t.tm_year = year() - 1900; - return mktime(&t); + return ::mktime(&t); // convert back via locatime & fudge for dst? } diff --git a/DateTime.h b/DateTime.h index 2e167e7..d7c295d 100644 --- a/DateTime.h +++ b/DateTime.h @@ -21,6 +21,11 @@ public: operator time_t() const; + operator uint32_t() const; + + unsigned date() const; + unsigned time() const; + unsigned minute() const; unsigned hour() const; unsigned day() const; @@ -28,40 +33,56 @@ public: unsigned year() const; private: + void init(time_t); + void init(unsigned, unsigned, unsigned, unsigned, unsigned); + unsigned _hhmm; unsigned _yymmdd; }; -DateTime::operator time_t() const +inline DateTime::operator time_t() const { return toUnix(); } +inline DateTime::operator uint32_t() const +{ + return (_yymmdd << 16) | _hhmm; +} -unsigned DateTime::minute() const +inline unsigned DateTime::date() const +{ + return _yymmdd; +} + +inline unsigned DateTime::time() const +{ + return _hhmm; +} + +inline unsigned DateTime::minute() const { return _hhmm & 0x3f; } -unsigned DateTime::hour() const +inline unsigned DateTime::hour() const { return (_hhmm >> 8) & 0x1f; } - -unsigned DateTime::day() const +inline unsigned DateTime::day() const { return _yymmdd & 0x1f; } -unsigned DateTime::month() const +inline unsigned DateTime::month() const { - return (_yymmdd >> 5) & 0x1f; + return (_yymmdd >> 5) & 0x0f; } /* -unsigned DateTime::year() const +inline unsigned DateTime::year() const { unsigned tmp = _yymmdd >> 9; if (tmp <= 39) tmp += 100;