Vault
4.1
|
00001 /* 00002 Copyright c1997-2014 Trygve Isaacson. All rights reserved. 00003 This file is part of the Code Vault version 4.1 00004 http://www.bombaydigital.com/ 00005 License: MIT. See LICENSE.md in the Vault top level directory. 00006 */ 00007 00008 #ifndef vinstant_h 00009 #define vinstant_h 00010 00013 #include "vtypes.h" 00014 00015 #include "vstring.h" 00016 00017 class VCodePoint; 00018 class VInstant; 00019 class VDate; 00020 class VTimeOfDay; 00021 class VDateAndTime; 00022 class VInstantFormatter; 00023 00068 class VDuration { 00069 public: 00070 00071 static const VDuration& ZERO(); 00072 static const VDuration& MILLISECOND(); 00073 static const VDuration& SECOND(); 00074 static const VDuration& MINUTE(); 00075 static const VDuration& HOUR(); 00076 static const VDuration& DAY(); 00077 00078 static const VDuration& UNSPECIFIED(); 00079 static const VDuration& NEGATIVE_INFINITY(); 00080 static const VDuration& POSITIVE_INFINITY(); 00081 00083 VDuration() : mDurationMilliseconds(0) {} 00085 VDuration(const VDuration& d) : mDurationMilliseconds(d.mDurationMilliseconds) {} 00087 VDuration(const VInstant& sinceWhen); 00089 ~VDuration() {} 00090 00099 static VDuration createFromDurationString(const VString& s); 00100 00102 VDuration& operator=(const VDuration& d) { if (this != &d) mDurationMilliseconds = d.getDurationMilliseconds(); return *this; } 00104 VDuration& operator+=(const VDuration& forwardOffset); 00106 VDuration& operator-=(const VDuration& backwardOffset); 00108 VDuration& operator*=(Vs64 multiplier); 00110 VDuration& operator/=(int divisor); 00112 VDuration& operator%=(const VDuration& divisor); 00114 VDuration operator-() const; 00115 00117 Vs64 getDurationMilliseconds() const { return mDurationMilliseconds; } 00119 int getDurationSeconds() const { return static_cast<int>(mDurationMilliseconds / kMillisecondsPerSecond); } 00121 int getDurationMinutes() const { return static_cast<int>(mDurationMilliseconds / kMillisecondsPerMinute); } 00123 int getDurationHours() const { return static_cast<int>(mDurationMilliseconds / kMillisecondsPerHour); } 00125 int getDurationDays() const { return static_cast<int>(mDurationMilliseconds / kMillisecondsPerDay); } 00127 VString getDurationString() const; 00129 VString getDurationStringFractionalSeconds() const; 00130 00132 void setDurationMilliseconds(Vs64 durationMilliseconds) { mDurationMilliseconds = durationMilliseconds; } 00134 void setDurationSeconds(int durationSeconds) { mDurationMilliseconds = kMillisecondsPerSecond * static_cast<Vs64>(durationSeconds); } 00136 void setDurationMinutes(int durationMinutes) { mDurationMilliseconds = kMillisecondsPerMinute * static_cast<Vs64>(durationMinutes); } 00138 void setDurationHours(int durationHours) { mDurationMilliseconds = kMillisecondsPerHour * static_cast<Vs64>(durationHours); } 00140 void setDurationDays(int durationDays) { mDurationMilliseconds = kMillisecondsPerDay * static_cast<Vs64>(durationDays); } 00141 00174 void setDurationString(const VString& s); 00175 00176 friend inline bool operator==(const VDuration& lhs, const VDuration& rhs); 00177 friend inline bool operator!=(const VDuration& lhs, const VDuration& rhs); 00178 friend inline bool operator< (const VDuration& lhs, const VDuration& rhs); 00179 friend inline bool operator<=(const VDuration& lhs, const VDuration& rhs); 00180 friend inline bool operator>=(const VDuration& lhs, const VDuration& rhs); 00181 friend inline bool operator> (const VDuration& lhs, const VDuration& rhs); 00182 friend inline VDuration operator+(const VDuration& d1, const VDuration& d2); 00183 friend inline VDuration operator-(const VDuration& d1, const VDuration& d2); 00184 friend inline VDuration operator*(Vs64 multiplier, const VDuration& d1); 00185 friend inline VDuration operator*(const VDuration& d1, Vs64 multiplier); 00186 friend VDuration operator/(const VDuration& d, int divisor); 00187 friend VDuration operator%(const VDuration& d, const VDuration& divisor); 00188 00189 static inline VDuration min(const VDuration& d1, const VDuration& d2); 00190 static inline VDuration max(const VDuration& d1, const VDuration& d2); 00191 static inline VDuration abs(const VDuration& d); 00192 00198 bool isComparable() const { return (*this != VDuration::UNSPECIFIED()); } 00203 bool isSpecific() const { return (*this != VDuration::UNSPECIFIED()) && (*this != VDuration::NEGATIVE_INFINITY()) && (*this != VDuration::POSITIVE_INFINITY()); } 00209 static bool areValuesSpecific(const VDuration& d1, const VDuration& d2) { return d1.isSpecific() && d2.isSpecific(); } 00210 00211 private: 00212 00213 // These are called by the friend inline comparison operators for comparing non-simple durations. 00214 static VDuration _complexAdd(const VDuration& d1, const VDuration& d2); 00215 static VDuration _complexSubtract(const VDuration& d1, const VDuration& d2); 00216 static VDuration _complexMultiply(const VDuration& d, Vs64 multiplier); 00217 static VDuration _complexMin(const VDuration& d1, const VDuration& d2); 00218 static VDuration _complexMax(const VDuration& d1, const VDuration& d2); 00219 static VDuration _complexAbs(const VDuration& d); 00220 00221 // This is the private constructor used internally. 00222 explicit VDuration(Vs64 durationMilliseconds) : mDurationMilliseconds(durationMilliseconds) {} 00223 00224 Vs64 mDurationMilliseconds; 00225 00226 // These are used internally for conversion. 00227 static const Vs64 kMillisecondsPerSecond = CONST_S64(1000); 00228 static const Vs64 kMillisecondsPerMinute = CONST_S64(60000); 00229 static const Vs64 kMillisecondsPerHour = CONST_S64(3600000); 00230 static const Vs64 kMillisecondsPerDay = CONST_S64(86400000); 00231 }; 00232 00233 // Inline implementations of some of the above VDuration operators. 00234 // For non-specific values, some operators need to call more complicated functions to provide 00235 // sensible values. 00236 inline bool operator==(const VDuration& lhs, const VDuration& rhs) { return lhs.mDurationMilliseconds == rhs.mDurationMilliseconds; } 00237 inline bool operator!=(const VDuration& lhs, const VDuration& rhs) { return !operator==(lhs, rhs); } 00238 inline bool operator< (const VDuration& lhs, const VDuration& rhs) { return lhs.mDurationMilliseconds < rhs.mDurationMilliseconds; } 00239 inline bool operator<=(const VDuration& lhs, const VDuration& rhs) { return !operator>(lhs, rhs); } 00240 inline bool operator>=(const VDuration& lhs, const VDuration& rhs) { return !operator<(lhs, rhs); } 00241 inline bool operator> (const VDuration& lhs, const VDuration& rhs) { return operator<(rhs, lhs); } 00242 inline VDuration operator+(const VDuration& d1, const VDuration& d2) { if (VDuration::areValuesSpecific(d1, d2)) return VDuration(d1.mDurationMilliseconds + d2.mDurationMilliseconds); else return VDuration::_complexAdd(d1, d2); } 00243 inline VDuration operator-(const VDuration& d1, const VDuration& d2) { if (VDuration::areValuesSpecific(d1, d2)) return VDuration(d1.mDurationMilliseconds - d2.mDurationMilliseconds); else return VDuration::_complexSubtract(d1, d2); } 00244 inline VDuration operator*(Vs64 multiplier, const VDuration& d) { if (d.isSpecific()) return VDuration(d.mDurationMilliseconds * multiplier); else return VDuration::_complexMultiply(d, multiplier); } 00245 inline VDuration operator*(const VDuration& d, Vs64 multiplier) { if (d.isSpecific()) return VDuration(d.mDurationMilliseconds * multiplier); else return VDuration::_complexMultiply(d, multiplier); } 00246 inline VDuration VDuration::min(const VDuration& d1, const VDuration& d2) { if (VDuration::areValuesSpecific(d1, d2)) return (d1 < d2) ? d1 : d2; else return VDuration::_complexMin(d1, d2); } 00247 inline VDuration VDuration::max(const VDuration& d1, const VDuration& d2) { if (VDuration::areValuesSpecific(d1, d2)) return (d1 > d2) ? d1 : d2; else return VDuration::_complexMax(d1, d2); } 00248 inline VDuration VDuration::abs(const VDuration& d) { if (d.isSpecific()) return (d.mDurationMilliseconds < CONST_S64(0)) ? -d : d; else return VDuration::_complexAbs(d); } 00249 00254 typedef std::vector<VDuration> VDurationVector; 00255 00260 class VInstantStruct { 00261 public: 00262 VInstantStruct() : mYear(0), mMonth(1), mDay(1), mHour(0), mMinute(0), mSecond(0), mMillisecond(0), mDayOfWeek(0) {} 00263 VInstantStruct(const VDate& date, const VTimeOfDay& timeOfDay); 00264 00270 Vs64 getOffsetFromUTCStruct() const; 00277 Vs64 getOffsetFromLocalStruct() const; 00283 void setUTCStructFromOffset(Vs64 offset); 00289 void setLocalStructFromOffset(Vs64 offset); 00290 00295 void getTmStruct(struct tm& fields) const; 00301 void setFromTmStruct(const struct tm& fields, int millisecond); 00302 00303 int mYear; 00304 int mMonth; 00305 int mDay; 00306 int mHour; 00307 int mMinute; 00308 int mSecond; 00309 int mMillisecond; 00310 int mDayOfWeek; 00311 00312 private: 00313 00314 // These are the 3 platform-defined helper functions for converting between 00315 // offsets and UTC or local broken-down time struct. There isn't one for 00316 // "from UTC struct" because it is not per-platform; if timegm is available 00317 // we call it, otherwise we implement it directly. 00318 00325 static Vs64 _platform_offsetFromLocalStruct(const VInstantStruct& when); 00333 static void _platform_offsetToLocalStruct(Vs64 offset, VInstantStruct& when); 00341 static void _platform_offsetToUTCStruct(Vs64 offset, VInstantStruct& when); 00342 00353 static void _threadsafe_localtime(const time_t epochOffset, struct tm* resultStorage); 00364 static void _threadsafe_gmtime(const time_t epochOffset, struct tm* resultStorage); 00365 00366 }; 00367 00379 class IVRemoteTimeZoneConverter { 00380 public: 00381 00393 virtual void offsetToRTZStruct(Vs64 offset, const VString& timeZoneID, VInstantStruct& when) = 0; 00406 virtual Vs64 offsetFromRTZStruct(const VString& timeZoneID, const VInstantStruct& when) = 0; 00407 00408 protected: 00409 00410 IVRemoteTimeZoneConverter() {} 00411 virtual ~IVRemoteTimeZoneConverter() {} 00412 00413 }; 00414 00431 class VInstant { 00432 public: 00433 00435 static const VInstant& INFINITE_PAST(); 00437 static const VInstant& INFINITE_FUTURE(); 00439 static const VInstant& NEVER_OCCURRED(); 00440 00443 static const VString& UTC_TIME_ZONE_ID(); 00446 static const VString& LOCAL_TIME_ZONE_ID(); 00447 00455 static VInstant instantFromRawValue(Vs64 value) { return VInstant(value); } 00456 00464 static VInstant instantFromPosixTime(time_t value) { return VInstant(CONST_S64(1000) * static_cast<Vs64>(value)); } 00465 00469 VInstant(); 00473 VInstant(const VInstant& i) : mValue(i.mValue) {} 00477 ~VInstant() {} 00478 00483 VInstant& operator=(const VInstant& i); 00492 VInstant& operator+=(const VDuration& forwardOffsetDuration); 00501 VInstant& operator-=(const VDuration& backwardOffsetDuration); 00506 void setNow(); 00510 void setTrueNow(); 00516 VInstantStruct getUTCInstantFields() const; 00522 VInstantStruct getLocalInstantFields() const; 00523 00524 /* 00525 There are two flavors of string conversion -- UTC and local -- and each one has 00526 a modern form and a legacy form. 00527 00528 The modern form returns the string, and is supplied a VInstantFormatter to control 00529 the format; there are several preset formatters available in VInstantFormatter. 00530 If you omit the formatter you get the same format that the legacy API provided 00531 prior to Vault 4.0, for backward compatibility. 00532 00533 The legacy form puts the string into a read-write parameter and has optional 00534 parameters to control whether milliseconds are included and whether punctuation 00535 is stripped out to make the string safe to use as a file system node name. 00536 */ 00537 00538 // Modern APIs starting with Vault 4.0: 00539 00545 VString getUTCString() const; 00552 VString getUTCString(const VInstantFormatter& formatter) const; 00558 VString getLocalString() const; 00565 VString getLocalString(const VInstantFormatter& formatter) const; 00566 00567 // Legacy APIs: 00568 00578 void getUTCString(VString& s, bool fileNameSafe = false, bool wantMilliseconds = true) const; 00588 void getLocalString(VString& s, bool fileNameSafe = false, bool wantMilliseconds = true) const; 00589 00597 void setUTCString(const VString& s); 00605 void setLocalString(const VString& s); 00606 00612 bool isSpecific() const { return (*this != VInstant::NEVER_OCCURRED()) && (*this != VInstant::INFINITE_PAST()) && (*this != VInstant::INFINITE_FUTURE()); } 00618 bool isComparable() const { return (*this != VInstant::NEVER_OCCURRED()); } 00631 Vs64 getValue() const { return mValue; } 00644 void setValue(Vs64 value) { mValue = value; } 00650 VDate getLocalDate() const; 00661 VDate getDate(const VString& timeZoneID) const; 00668 VTimeOfDay getLocalTimeOfDay() const; 00679 VTimeOfDay getTimeOfDay(const VString& timeZoneID) const; 00685 VDateAndTime getLocalDateAndTime() const; 00693 VDateAndTime getDateAndTime(const VString& timeZoneID) const; 00699 void setLocalDateAndTime(const VDateAndTime& dt); 00707 void setDateAndTime(const VDateAndTime& dt, const VString& timeZoneID); 00717 void getValues(VDate& date, VTimeOfDay& timeOfDay, const VString& timeZoneID) const; 00727 void setValues(const VDate& date, const VTimeOfDay& timeOfDay, const VString& timeZoneID); 00734 Vs64 getLocalOffsetMilliseconds() const; 00735 00736 friend inline bool operator==(const VInstant& lhs, const VInstant& rhs); 00737 friend inline bool operator!=(const VInstant& lhs, const VInstant& rhs); 00738 friend inline bool operator< (const VInstant& lhs, const VInstant& rhs); 00739 friend inline bool operator<=(const VInstant& lhs, const VInstant& rhs); 00740 friend inline bool operator>=(const VInstant& lhs, const VInstant& rhs); 00741 friend inline bool operator> (const VInstant& lhs, const VInstant& rhs); 00742 friend inline VDuration operator-(const VInstant& i1, const VInstant& i2); 00743 friend inline VInstant operator+(const VInstant& i1, const VDuration& forwardDuration); 00744 friend inline VInstant operator-(const VInstant& i1, const VDuration& backwardDuration); 00745 00746 static inline VInstant min(const VInstant& i1, const VInstant& i2); 00747 static inline VInstant max(const VInstant& i1, const VInstant& i2); 00748 00757 static Vs64 snapshot(); 00765 static VDuration snapshotDelta(Vs64 snapshotValue); 00766 00774 static void setRemoteTimeZoneConverter(IVRemoteTimeZoneConverter* converter); 00781 static IVRemoteTimeZoneConverter* getRemoteTimeZoneConverter(); 00782 00783 // Time simulation features. Note that if "frozen time" is in effect, the 00784 // "clock offset" information is not used. 00795 static void incrementSimulatedClockOffset(const VDuration& delta); 00806 static void setSimulatedClockOffset(const VDuration& offset); 00818 static void setSimulatedClockValue(const VInstant& simulatedCurrentTime); 00828 static VDuration getSimulatedClockOffset(); 00834 static void freezeTime(const VInstant& frozenTimeValue); 00842 static void shiftFrozenTime(const VDuration& delta); 00849 static void unfreezeTime(); 00854 static bool isTimeFrozen(); 00855 00856 private: 00857 00858 // This is the private constructor used internally. 00859 explicit VInstant(Vs64 utcOffsetMilliseconds) : mValue(utcOffsetMilliseconds) {} 00860 00861 Vs64 mValue; 00862 00867 static bool canCompareValues(const VInstant& i1, const VInstant& i2) { return i1.isSpecific() && i2.isSpecific(); } 00871 static bool _complexGT(const VInstant& i1, const VInstant& i2); 00875 static bool _complexGTE(const VInstant& i1, const VInstant& i2); 00879 static bool _complexLT(const VInstant& i1, const VInstant& i2); 00883 static bool _complexLTE(const VInstant& i1, const VInstant& i2); 00884 00885 /* 00886 These are the core function interfaces that must be implemented on a 00887 per-platform basis. That is, they are platform-specific and are 00888 implemented in the vinstant_platform.* files. All other time 00889 conversion is performed via these calls. This allows us to isolate 00890 the platform and library quirks in those files rather than conditionally 00891 compile code in vinstant.cpp. 00892 00893 There are only two types used here. 00894 - The 64-bit millisecond "offset" from UTC 1970. This is also what VInstant 00895 uses an offset. We'll just refer to this as a UTC Epoch Offset. 00896 - The y/m/d/h/m/s "struct" in some time zone. We'll just refer to this 00897 as a "Time Struct". 00898 00899 It's all about converting between them. 00900 00901 There is one additional function, _platform_snapshot(), which is not about 00902 time conversion, but just about measuring short time durations with 00903 millisecond resolution. 00904 */ 00905 00911 static Vs64 _platform_now(); 00918 static Vs64 _platform_snapshot(); 00919 00920 static Vs64 gSimulatedClockOffset; 00921 static Vs64 gFrozenClockValue; 00922 static IVRemoteTimeZoneConverter* gRemoteTimeZoneConverter; 00923 00924 // Let VDate call the getTimeValue() bottleneck for getting the day of 00925 // week, but don't make it a public API since it's exposing the tm 00926 // structure which is dependent on time.h functionality. 00927 friend class VDate; 00928 friend class VInstantUnit; // Let unit test validate our internal APIs. 00929 }; 00930 00931 // Inline implementations of some of the above VInstant operators. 00932 inline bool operator==(const VInstant& lhs, const VInstant& rhs) { return lhs.mValue == rhs.mValue; } 00933 inline bool operator!=(const VInstant& lhs, const VInstant& rhs) { return !operator==(lhs, rhs); } 00934 inline bool operator< (const VInstant& lhs, const VInstant& rhs) { if (VInstant::canCompareValues(lhs, rhs)) return lhs.mValue < rhs.mValue; else return VInstant::_complexLT(lhs, rhs); } 00935 inline bool operator<=(const VInstant& lhs, const VInstant& rhs) { if (VInstant::canCompareValues(lhs, rhs)) return lhs.mValue <= rhs.mValue; else return VInstant::_complexLTE(lhs, rhs); } 00936 inline bool operator>=(const VInstant& lhs, const VInstant& rhs) { if (VInstant::canCompareValues(lhs, rhs)) return lhs.mValue >= rhs.mValue; else return VInstant::_complexGTE(lhs, rhs); } 00937 inline bool operator> (const VInstant& lhs, const VInstant& rhs) { if (VInstant::canCompareValues(lhs, rhs)) return lhs.mValue > rhs.mValue; else return VInstant::_complexGT(lhs, rhs); } 00938 inline VDuration operator-(const VInstant& i1, const VInstant& i2) { if (VInstant::canCompareValues(i1, i2)) return VDuration::MILLISECOND() * (i1.mValue - i2.mValue); else return VDuration(); } 00939 inline VInstant operator+(const VInstant& i1, const VDuration& forwardDuration) { VInstant result = i1; result += forwardDuration; return result; } 00940 inline VInstant operator-(const VInstant& i1, const VDuration& backwardDuration) { VInstant result = i1; result -= backwardDuration; return result; } 00941 inline VInstant VInstant::min(const VInstant& i1, const VInstant& i2) { return (i1 < i2) ? i1 : i2; } 00942 inline VInstant VInstant::max(const VInstant& i1, const VInstant& i2) { return (i1 > i2) ? i1 : i2; } 00943 00948 typedef std::vector<VInstant> VInstantVector; 00949 00956 class VDate { 00957 public: 00958 00959 static VDate createFromDateString(const VString& dateString, const VCodePoint& delimiter); 00960 00966 VDate(); 00973 VDate(const VString& timeZoneID); 00980 VDate(int year, int month, int day); 00984 virtual ~VDate() {} 00985 00990 int getYear() const; 00995 int getMonth() const; 01000 int getDay() const; 01006 int getDayOfWeek() const; 01013 void set(int year, int month, int day); 01018 void setYear(int year); 01023 void setMonth(int month); 01028 void setDay(int day); 01029 01030 // These static functions can be extended in the future to 01031 // return values based on the locale. 01032 01038 static const VCodePoint& getLocalDateSeparator() { return kLocalDateSeparator; } 01039 01040 enum { 01041 kYMD, 01042 kYDM, 01043 kMYD, 01044 kMDY, 01045 kDYM, 01046 kDMY 01047 }; 01048 01054 static int getLocalDateOrder() { return kMDY; } 01055 01056 enum { 01057 kSunday = 0, 01058 kMonday, 01059 kTuesday, 01060 kWednesday, 01061 kThursday, 01062 kFriday, 01063 kSaturday 01064 }; 01065 01066 friend inline bool operator==(const VDate& lhs, const VDate& rhs); 01067 friend inline bool operator!=(const VDate& lhs, const VDate& rhs); 01068 friend inline bool operator< (const VDate& lhs, const VDate& rhs); 01069 friend inline bool operator<=(const VDate& lhs, const VDate& rhs); 01070 friend inline bool operator>=(const VDate& lhs, const VDate& rhs); 01071 friend inline bool operator> (const VDate& lhs, const VDate& rhs); 01072 01073 private: 01074 01076 void _assertInvariant() const; 01077 01078 int mYear; 01079 int mMonth; 01080 int mDay; 01081 01082 static const VCodePoint kLocalDateSeparator; 01083 }; 01084 01085 inline bool operator==(const VDate& lhs, const VDate& rhs) { return (lhs.mYear == rhs.mYear) && (lhs.mMonth == rhs.mMonth) && (lhs.mDay == rhs.mDay); } 01086 inline bool operator!=(const VDate& lhs, const VDate& rhs) { return !operator==(lhs, rhs); } 01087 inline bool operator< (const VDate& lhs, const VDate& rhs) { 01088 if (lhs.mYear < rhs.mYear) return true; 01089 if (lhs.mYear > rhs.mYear) return false; 01090 if (lhs.mMonth < rhs.mMonth) return true; 01091 if (lhs.mMonth > rhs.mMonth) return false; 01092 return (lhs.mDay < rhs.mDay); 01093 } 01094 inline bool operator<=(const VDate& lhs, const VDate& rhs) { return !operator>(lhs, rhs); } 01095 inline bool operator>=(const VDate& lhs, const VDate& rhs) { return !operator<(lhs, rhs); } 01096 inline bool operator> (const VDate& lhs, const VDate& rhs) { return operator<(rhs, lhs); } 01097 01102 class VTimeOfDay { 01103 public: 01104 01109 VTimeOfDay(); 01116 VTimeOfDay(const VString& timeZoneID); 01124 VTimeOfDay(int hour, int minute, int second, int millisecond); 01128 virtual ~VTimeOfDay() {} 01129 01134 int getHour() const; 01139 int getMinute() const; 01144 int getSecond() const; 01149 int getMillisecond() const; 01157 void set(int hour, int minute, int second, int millisecond); 01162 void setHour(int hour); 01167 void setMinute(int minute); 01172 void setSecond(int second); 01177 void setMillisecond(int millisecond); 01181 void setToStartOfDay(); 01182 01183 // These static functions can be extended in the future to 01184 // return values based on the locale. 01185 01191 static const VCodePoint& getLocalTimeSeparator() { return kLocalTimeSeparator; } 01192 01193 friend inline bool operator==(const VTimeOfDay& t1, const VTimeOfDay& t2); 01194 01195 private: 01196 01198 void _assertInvariant() const; 01199 01200 int mHour; 01201 int mMinute; 01202 int mSecond; 01203 int mMillisecond; 01204 01205 static const VCodePoint kLocalTimeSeparator; 01206 }; 01207 01208 inline bool operator==(const VTimeOfDay& t1, const VTimeOfDay& t2) { return (t1.mHour == t2.mHour) && (t1.mMinute == t2.mMinute) && (t1.mSecond == t2.mSecond) && (t1.mMillisecond == t2.mMillisecond); } 01209 01213 class VDateAndTime { 01214 public: 01215 01216 VDateAndTime() : mDate(), mTimeOfDay() {} 01217 VDateAndTime(const VString& timeZoneID); 01218 VDateAndTime(int inYear, int inMonth, int inDay, int inHour, int inMinute, int inSecond, int inMillisecond) : 01219 mDate(inYear, inMonth, inDay), mTimeOfDay(inHour, inMinute, inSecond, inMillisecond) {} 01220 ~VDateAndTime() {} 01221 01222 // Use these accessors to call the date and time of day sub-objects directly. 01223 const VDate& getDate() const { return mDate; } 01224 const VTimeOfDay& getTimeOfDay() const { return mTimeOfDay; } 01225 01226 int getYear() const { return mDate.getYear(); } 01227 int getMonth() const { return mDate.getMonth(); } 01228 int getDay() const { return mDate.getDay(); } 01229 int getDayOfWeek() const { return mDate.getDayOfWeek(); } 01230 int getHour() const { return mTimeOfDay.getHour(); } 01231 int getMinute() const { return mTimeOfDay.getMinute(); } 01232 int getSecond() const { return mTimeOfDay.getSecond(); } 01233 int getMillisecond() const { return mTimeOfDay.getMillisecond(); } 01234 01235 void set(int inYear, int inMonth, int inDay, int inHour, int inMinute, int inSecond, int inMillisecond) { 01236 mDate.set(inYear, inMonth, inDay); mTimeOfDay.set(inHour, inMinute, inSecond, inMillisecond); 01237 } 01238 01239 void setYear(int year) { mDate.setYear(year); } 01240 void setMonth(int month) { mDate.setMonth(month); } 01241 void setDay(int day) { mDate.setDay(day); } 01242 void setHour(int hour) { mTimeOfDay.setHour(hour); } 01243 void setMinute(int minute) { mTimeOfDay.setMinute(minute); } 01244 void setSecond(int second) { mTimeOfDay.setSecond(second); } 01245 void setMillisecond(int millisecond) { mTimeOfDay.setMillisecond(millisecond); } 01246 void setToStartOfDay() { mTimeOfDay.setToStartOfDay(); } 01247 01248 friend inline bool operator==(const VDateAndTime& dt1, const VDateAndTime& dt2); 01249 01250 private: 01251 01252 VDate mDate; 01253 VTimeOfDay mTimeOfDay; 01254 }; 01255 01256 inline bool operator==(const VDateAndTime& dt1, const VDateAndTime& dt2) { return (dt1.mDate == dt2.mDate) && (dt1.mTimeOfDay == dt2.mTimeOfDay); } 01257 01258 // VInstantFormatterLocaleInfo ----------------------------------------------- 01259 01269 class VInstantFormatterLocaleInfo { 01270 public: 01271 01279 static const VInstantFormatterLocaleInfo& getLocaleInfo(const VString& localeName); 01280 01285 VInstantFormatterLocaleInfo(); 01286 ~VInstantFormatterLocaleInfo() {} 01287 01288 // The instance variables are public since they are just data, which you can 01289 // build if you are setting up your own locale object. 01290 01291 VString CE_MARKER; 01292 VString AM_MARKER; 01293 VString PM_MARKER; 01294 VStringVector MONTH_NAMES_SHORT; 01295 VStringVector MONTH_NAMES_LONG; 01296 VStringVector DAY_NAMES_SHORT; 01297 VStringVector DAY_NAMES_LONG; 01298 }; 01299 01300 // VInstantFormatter --------------------------------------------------------- 01301 01317 class VInstantFormatter { 01318 public: 01319 01323 VInstantFormatter(); 01328 VInstantFormatter(const VInstantFormatterLocaleInfo& localeInfo); 01333 VInstantFormatter(const VString& formatSpecifier); 01339 VInstantFormatter(const VString& formatSpecifier, const VInstantFormatterLocaleInfo& localeInfo); 01340 01341 ~VInstantFormatter() {} 01342 01350 VString formatLocalString(const VInstant& when) const; 01357 VString formatUTCString(const VInstant& when) const; 01358 01359 // Getter, for debugging use. 01360 VString getFormatSpecifier() const { return mFormatSpecifier; } 01361 01362 private: 01363 01369 VString _format(const VInstantStruct& when, int utcOffsetMilliseconds) const; 01370 void _flushPendingFieldSpecifier(const VInstantStruct& when, int utcOffsetMilliseconds, VString& fieldSpecifier/*will be set to empty on return*/, VString& resultToAppendTo) const; 01371 01372 void _flushFixedLengthTextValue(const VString& value, VString& resultToAppendTo) const; 01373 void _flushVariableLengthTextValue(const VString& shortValue, const VString& longValue, int fieldLength, VString& resultToAppendTo) const; 01374 void _flushNumberValue(int value, int fieldLength, VString& resultToAppendTo) const; 01375 void _flushYearValue(int year, int fieldLength, VString& resultToAppendTo) const; 01376 void _flushMonthValue(int month, int fieldLength, VString& resultToAppendTo) const; 01377 void _flushDayNameValue(int dayOfWeek/*0=sun ... 6=sat*/, int fieldLength, VString& resultToAppendTo) const; 01378 void _flushDayNumberValue(int dayOfWeek/*0=sun ... 6=sat*/, int fieldLength, VString& resultToAppendTo) const; 01379 void _flushTimeZoneValue(int utcOffsetMilliseconds, const VString& fieldSpecifier, VString& resultToAppendTo) const; 01380 01381 VString mFormatSpecifier; 01382 01383 // Pseudo-constants: Potentially localized values, not static, because we allow setting per VInstantFormatter. 01384 const VInstantFormatterLocaleInfo& mLocaleInfo; 01385 }; 01386 01387 #endif /* vinstant_h */