diff --git a/Core/DateTime.cpp b/Core/DateTime.cpp index fdfa8401..cf0ce9b2 100644 --- a/Core/DateTime.cpp +++ b/Core/DateTime.cpp @@ -39,33 +39,7 @@ DateTime& DateTime::Parse(uint seconds) st.Hour = time % 24; time /= 24; - uint day = time; - - // 基本年的一天不一定是星期天,需要偏移BASE_YEAR_DAYOFWEEK_SHIFT - st.DayOfWeek = (day + BASE_YEAR_DAYOFWEEK_SHIFT) % 7; - st.Year = (ushort)(day / 365 + BASE_YEAR); - - // 按最小每年365天估算,如果不满当年总天数,年份减一 - int ytd = YEARS_TO_DAYS(st.Year); - if (ytd > day) - { - st.Year--; - ytd = YEARS_TO_DAYS(st.Year); - } - - // 减去年份的天数 - day -= ytd; - - // 按最大每月31天估算,如果超过当月总天数,月份加一 - st.Month = (ushort)(day / 31 + 1); - int mtd = MONTH_TO_DAYS(st.Year, st.Month + 1); - if (day >= mtd) st.Month++; - - // 计算月份表示的天数 - mtd = MONTH_TO_DAYS(st.Year, st.Month); - - // 今年总天数减去月份天数,得到该月第几天 - st.Day = (ushort)(day - mtd + 1); + if(time) ParseDays(time); Ms = 0; @@ -80,27 +54,41 @@ DateTime& DateTime::ParseMs(UInt64 ms) return *this; } -/*DateTime& DateTime::ParseUs(UInt64 us) +DateTime& DateTime::ParseDays(uint days) { - Parse(us / 1000000ULL); - uint n = us % 1000000ULL; - Ms = n / 1000; - Us = n % 1000; + // 基本年的一天不一定是星期天,需要偏移BASE_YEAR_DAYOFWEEK_SHIFT + //DayOfWeek = (days + BASE_YEAR_DAYOFWEEK_SHIFT) % 7; + Year = (ushort)(days / 365); + if(Year < 136) Year += BASE_YEAR; + + // 按最小每年365天估算,如果不满当年总天数,年份减一 + int ytd = YEARS_TO_DAYS(Year); + if (ytd > days) + { + Year--; + ytd = YEARS_TO_DAYS(Year); + } + + // 减去年份的天数 + days -= ytd; + + // 按最大每月31天估算,如果超过当月总天数,月份加一 + Month = (ushort)(days / 31 + 1); + int mtd = MONTH_TO_DAYS(Year, Month + 1); + if (days >= mtd) Month++; + + // 计算月份表示的天数 + mtd = MONTH_TO_DAYS(Year, Month); + + // 今年总天数减去月份天数,得到该月第几天 + Day = (ushort)(days - mtd + 1); return *this; -}*/ +} DateTime::DateTime() { - //Buffer(&Year, &Ms - &Year + sizeof(Ms)).Clear(); - Year = BASE_YEAR; - Month = 1; - Day = 1; - DayOfWeek = BASE_YEAR_DAYOFWEEK_SHIFT; - Hour = 0; - Minute = 0; - Second = 0; - Ms = 0; + Init(); } DateTime::DateTime(ushort year, byte month, byte day) @@ -112,9 +100,6 @@ DateTime::DateTime(ushort year, byte month, byte day) Minute = 0; Second = 0; Ms = 0; - - uint days = YEARS_TO_DAYS(Year) + MONTH_TO_DAYS(Year, Month) + Day - 1; - DayOfWeek = (days + BASE_YEAR_DAYOFWEEK_SHIFT) % 7; } DateTime::DateTime(uint seconds) @@ -125,6 +110,37 @@ DateTime::DateTime(uint seconds) Parse(seconds); } +DateTime::DateTime(const DateTime& value) +{ + *this = value; +} + +DateTime::DateTime(DateTime&& value) +{ + // 拷贝对方数据,把对方初始化为默认值 + auto bs = ToArray(); + bs = value.ToArray(); + // 对方反正不用了,就不要浪费时间做初始化啦,反正没有需要释放的资源 + //value.Init(); +} + +void DateTime::Init() +{ + //Buffer(&Year, &Ms - &Year + sizeof(Ms)).Clear(); + Year = BASE_YEAR; + Month = 1; + Day = 1; + Hour = 0; + Minute = 0; + Second = 0; + Ms = 0; +} + +Buffer DateTime::ToArray() +{ + return Buffer(&Year, &Ms - &Year + sizeof(Ms)); +} + // 重载等号运算符 DateTime& DateTime::operator=(uint seconds) { @@ -133,31 +149,179 @@ DateTime& DateTime::operator=(uint seconds) return *this; } -uint DateTime::TotalSeconds() +DateTime& DateTime::operator=(const DateTime& value) { - uint s = 0; - s += YEARS_TO_DAYS(Year) + MONTH_TO_DAYS(Year, Month) + Day - 1; - s = s * 24 + Hour; + // 避免自己拷贝自己 + if(this != &value) + { + // 拷贝对方数据 + auto bs = ToArray(); + bs = ((DateTime&)value).ToArray(); + } + + return *this; +} + +uint DateTime::TotalDays() const +{ + return YEARS_TO_DAYS(Year) + MONTH_TO_DAYS(Year, Month) + Day - 1; +} + +uint DateTime::TotalSeconds() const +{ + uint s = TotalDays() * 24 + Hour; s = s * 60 + Minute; s = s * 60 + Second; return s; } -UInt64 DateTime::TotalMs() +UInt64 DateTime::TotalMs() const { UInt64 sec = (UInt64)TotalSeconds(); return sec * 1000UL + (UInt64)Ms; } -/*UInt64 DateTime::TotalUs() +// 获取星期 +byte DateTime::DayOfWeek() const { - UInt64 sec = (UInt64)TotalSeconds(); - uint us = (uint)Ms * 1000 + Us; + uint days = YEARS_TO_DAYS(Year) + MONTH_TO_DAYS(Year, Month) + Day - 1; + return (days + BASE_YEAR_DAYOFWEEK_SHIFT) % 7; +} - return sec * 1000 + us; -}*/ +// 取时间日期的日期部分 +DateTime DateTime::Date() const +{ + return DateTime(Year, Month, Day); +} + +DateTime DateTime::AddYears(int value) const +{ + auto dt = *this; + dt.Year += value; + + return dt; +} + +DateTime DateTime::AddMonths(int value) const +{ + value += Month; + int ys = value / 12; + int ms = value % 12; + + // 可能上下溢出,需要修正 + if(ms <= 0) + { + ys--; + ms += 12; + } + + auto dt = *this; + dt.Year += ys; + dt.Month = ms; + + return dt; +} + +DateTime DateTime::AddDays(int value) const +{ + DateTime dt; + dt.ParseDays(TotalDays() + value); + + return dt; +} + +DateTime DateTime::AddHours(int value) const +{ + /*value += Hour; + int days = value / 24; + int hour = value % 24; + + // 可能上下溢出,需要修正 + if(hour < 0) + { + days--; + hour += 24; + } + + auto dt = AddDays(days); + dt.Hour = hour; + + return dt;*/ + + return AddSeconds(value * 3600); +} + +DateTime DateTime::AddMinutes(int value) const +{ + /*value += Minute; + int hours = value / 60; + int mins = value % 60; + + // 可能上下溢出,需要修正 + if(mins < 0) + { + hours--; + mins += 60; + } + + auto dt = AddHours(hours); + dt.Minute = mins; + + return dt;*/ + + return AddSeconds(value * 60); +} + +DateTime DateTime::AddSeconds(int value) const +{ + DateTime dt; + dt.Parse(TotalSeconds() + value); + + return dt; +} + +DateTime DateTime::AddMilliseconds(Int64 value) const +{ + DateTime dt; + dt.ParseMs(TotalMs() + value); + + return dt; +} + +int DateTime::CompareTo(const DateTime& value) const +{ + int n = (int)Year - value.Year; + if(n) return n; + + n = (int)Month - value.Month; + if(n) return n; + + n = (int)Day - value.Day; + if(n) return n; + + n = (int)Hour - value.Hour; + if(n) return n; + + n = (int)Minute - value.Minute; + if(n) return n; + + n = (int)Second - value.Second; + if(n) return n; + + n = (int)Ms - value.Ms; + if(n) return n; + + return 0; +} + +bool operator== (const DateTime& left, const DateTime& right) { return left.CompareTo(right) == 0; } +bool operator!= (const DateTime& left, const DateTime& right) { return left.CompareTo(right) != 0; } +bool operator> (const DateTime& left, const DateTime& right) { return left.CompareTo(right) > 0; } +bool operator< (const DateTime& left, const DateTime& right) { return left.CompareTo(right) < 0; } +bool operator>= (const DateTime& left, const DateTime& right) { return left.CompareTo(right) >= 0; } +bool operator<= (const DateTime& left, const DateTime& right) { return left.CompareTo(right) <= 0; } String& DateTime::ToStr(String& str) const { diff --git a/Core/DateTime.h b/Core/DateTime.h index 2a2eaab5..b917d076 100644 --- a/Core/DateTime.h +++ b/Core/DateTime.h @@ -1,33 +1,59 @@ #ifndef __DateTime_H__ #define __DateTime_H__ -// 系统时钟 +#include "Buffer.h" + +// 时间日期 class DateTime : public Object { public: - ushort Year; - byte Month; - byte DayOfWeek; - byte Day; - byte Hour; - byte Minute; - byte Second; - ushort Ms; - //ushort Us; + ushort Year; + byte Month; + byte Day; + byte Hour; + byte Minute; + byte Second; + ushort Ms; DateTime(); DateTime(ushort year, byte month, byte day); DateTime(uint seconds); + DateTime(const DateTime& value); + DateTime(DateTime&& value); // 重载等号运算符 DateTime& operator=(uint seconds); + DateTime& operator=(const DateTime& value); DateTime& Parse(uint seconds); DateTime& ParseMs(UInt64 ms); - //DateTime& ParseUs(UInt64 us); - uint TotalSeconds(); - UInt64 TotalMs(); - //UInt64 TotalUs(); + DateTime& ParseDays(uint days); + + uint TotalDays() const; + uint TotalSeconds() const; + UInt64 TotalMs() const; + + // 获取星期 + byte DayOfWeek() const; + // 取时间日期的日期部分 + DateTime Date() const; + + DateTime AddYears(int value) const; + DateTime AddMonths(int value) const; + DateTime AddDays(int value) const; + DateTime AddHours(int value) const; + DateTime AddMinutes(int value) const; + DateTime AddSeconds(int value) const; + DateTime AddMilliseconds(Int64 value) const; + + // 时间比较 + int CompareTo(const DateTime& value) const; + friend bool operator== (const DateTime& left, const DateTime& right); + friend bool operator!= (const DateTime& left, const DateTime& right); + friend bool operator> (const DateTime& left, const DateTime& right); + friend bool operator< (const DateTime& left, const DateTime& right); + friend bool operator>= (const DateTime& left, const DateTime& right); + friend bool operator<= (const DateTime& left, const DateTime& right); virtual String& ToStr(String& str) const; @@ -44,6 +70,10 @@ public: // 当前时间 static DateTime Now(); + +private: + void Init(); + Buffer ToArray(); }; #endif diff --git a/Sys.h b/Sys.h index 0c86ca8d..80372314 100644 --- a/Sys.h +++ b/Sys.h @@ -70,7 +70,7 @@ extern struct HandlerRemap StrBoot; #define IN_ROM_SECTION(p) ( (int)p < 0x20000000 ) // 系统类 -class TSys : Object +class TSys { public: COM MessagePort;// 消息口,默认0表示USART1 diff --git a/Test/DateTimeTest.cpp b/Test/DateTimeTest.cpp index ecd2d664..8719c98a 100644 --- a/Test/DateTimeTest.cpp +++ b/Test/DateTimeTest.cpp @@ -7,17 +7,17 @@ static void TestCtor() DateTime dt; assert(dt.Year == 1970 && dt.Month == 1 && dt.Day == 1, "DateTime()"); - assert(dt.DayOfWeek == 4, "DateTime()"); + assert(dt.DayOfWeek() == 4, "DateTime()"); assert(dt.Hour == 0 && dt.Minute == 0 && dt.Second == 0 && dt.Ms == 0, "DateTime()"); DateTime dt2(2016, 5, 18); assert(dt2.Year == 2016 && dt2.Month == 5 && dt2.Day == 18, "DateTime(ushort year, byte month, byte day)"); - assert(dt2.DayOfWeek == 3, "DateTime(ushort year, byte month, byte day)"); + assert(dt2.DayOfWeek() == 3, "DateTime(ushort year, byte month, byte day)"); assert(dt2.Hour == 0 && dt2.Minute == 0 && dt2.Second == 0 && dt2.Ms == 0, "DateTime(ushort year, byte month, byte day)"); DateTime dt3(1463443233); assert(dt3.Year == 2016 && dt3.Month == 5 && dt3.Day == 17, "DateTime(uint seconds)"); - assert(dt3.DayOfWeek == 2, "DateTime(uint seconds)"); + assert(dt3.DayOfWeek() == 2, "DateTime(uint seconds)"); assert(dt3.Hour == 0 && dt3.Minute == 0 && dt3.Second == 33 && dt3.Ms == 00, "DateTime(uint seconds)"); } @@ -28,7 +28,7 @@ static void ParseMs() DateTime dt3; dt3 = 1463443233; assert(dt3.Year == 2016 && dt3.Month == 5 && dt3.Day == 17, "DateTime(uint seconds)"); - assert(dt3.DayOfWeek == 2, "DateTime(uint seconds)"); + assert(dt3.DayOfWeek() == 2, "DateTime(uint seconds)"); assert(dt3.Hour == 0 && dt3.Minute == 0 && dt3.Second == 33 && dt3.Ms == 00, "DateTime(uint seconds)"); }