📄 cimdatetime.cpp
字号:
{ '2', '8', }, { '2', '9', }, { '3', '0', }, { '3', '1', }, { '3', '2', }, { '3', '3', }, { '3', '4', }, { '3', '5', }, { '3', '6', }, { '3', '7', }, { '3', '8', }, { '3', '9', }, { '4', '0', }, { '4', '1', }, { '4', '2', }, { '4', '3', }, { '4', '4', }, { '4', '5', }, { '4', '6', }, { '4', '7', }, { '4', '8', }, { '4', '9', }, { '5', '0', }, { '5', '1', }, { '5', '2', }, { '5', '3', }, { '5', '4', }, { '5', '5', }, { '5', '6', }, { '5', '7', }, { '5', '8', }, { '5', '9', }, { '6', '0', }, { '6', '1', }, { '6', '2', }, { '6', '3', }, { '6', '4', }, { '6', '5', }, { '6', '6', }, { '6', '7', }, { '6', '8', }, { '6', '9', }, { '7', '0', }, { '7', '1', }, { '7', '2', }, { '7', '3', }, { '7', '4', }, { '7', '5', }, { '7', '6', }, { '7', '7', }, { '7', '8', }, { '7', '9', }, { '8', '0', }, { '8', '1', }, { '8', '2', }, { '8', '3', }, { '8', '4', }, { '8', '5', }, { '8', '6', }, { '8', '7', }, { '8', '8', }, { '8', '9', }, { '9', '0', }, { '9', '1', }, { '9', '2', }, { '9', '3', }, { '9', '4', }, { '9', '5', }, { '9', '6', }, { '9', '7', }, { '9', '8', }, { '9', '9', },};/** Convert integer x to a zero-padded char16 string. Legal for x less than 100000000.*/static inline void _intToChar16String(Uint32 x, Uint16*& str, size_t numDigits){ if (numDigits == 2) { str[0] = _intToStrTable[x][0]; str[1] = _intToStrTable[x][1]; str += 2; return; } while (numDigits--) { Uint32 d = _tens[numDigits]; Uint32 n = x / d; x %= d; *str++ = n + '0'; }}static void _toChar16Str(const CIMDateTimeRep* rep, Char16* data_){ Uint16* data = (Uint16*)data_; if (rep->sign == ':') { // DDDDDDDDHHMMSS.MMMMMM:000 Uint64 usec = rep->usec; Uint32 microseconds = Uint32(usec % SECOND); Uint32 seconds = Uint32((usec / SECOND) % 60); Uint32 minutes = Uint32((usec / MINUTE) % 60); Uint32 hours = Uint32((usec / HOUR) % 24); Uint32 days = Uint32((usec / DAY)); _intToChar16String(days, data, 8); _intToChar16String(hours, data, 2); _intToChar16String(minutes, data, 2); _intToChar16String(seconds, data, 2); *data++ = '.'; _intToChar16String(microseconds, data, 6); data[0] = ':'; data[1] = '0'; data[2] = '0'; data[3] = '0'; } else { // YYYYMMDDHHMMSS.MMMMMMSUTC Uint64 usec = rep->usec; Uint32 microseconds = Uint32(usec % SECOND); Uint32 seconds = Uint32((usec / SECOND) % 60); Uint32 minutes = Uint32((usec / MINUTE) % 60); Uint32 hours = Uint32((usec / HOUR) % 24); Uint32 days = Uint32((usec / DAY)); Uint32 jd = Uint32(days + JULIAN_ONE_BCE); Uint32 year; Uint32 month; Uint32 day; _fromJulianDay(jd, year, month, day); _intToChar16String(year, data, 4); _intToChar16String(month, data, 2); _intToChar16String(day, data, 2); _intToChar16String(hours, data, 2); _intToChar16String(minutes, data, 2); _intToChar16String(seconds, data, 2); *data++ = '.'; _intToChar16String(microseconds, data, 6); *data++ = rep->sign; _intToChar16String(rep->utcOffset, data, 3); } // Fill buffer with '*' chars (if any). { Uint16* first = (Uint16*)data_ + 20; Uint16* last = (Uint16*)data_ + 20 - rep->numWildcards; if (rep->numWildcards > 6) last--; for (; first != last; first--) { if (*first != '.') *first = '*'; } }}/** Compares the two CIMDateTime representations. The return value is one of the following. 0 : x is equal to y < 0 : x is less than y > 0 : x is greater than y This function throws TypeMismatchException if x and y are not of the same type (time stamps or intervals). Algorithm: If both representations have zero numWildcards members, then the comparison is simply _toMicroSeconds(x) - _toMicroSeconds(y). If either has a non-zero numWildcards member, then they are converted to to canonical string format and compared lexographically with _matchTimeStampStrings(). If so, then time stamps must be normalized (usec must be adjusted for the sign and utcOffset).*/static int _compare(const CIMDateTimeRep* x, const CIMDateTimeRep* y){ bool xIsInterval = x->sign == ':'; bool yIsInterval = y->sign == ':'; if (xIsInterval != yIsInterval) { MessageLoaderParms parms( "Common.CIMDateTime.INVALID_OPERATION_COMP_DIF", "Trying to compare CIMDateTime objects of differing types"); throw TypeMismatchException(parms); } if (x->numWildcards == 0 && y->numWildcards == 0) { Uint64 xm = _toMicroSeconds(x); Uint64 ym = _toMicroSeconds(y); if (xm < ym) return -1; else if (xm > ym) return 1; return 0; } else { if (!xIsInterval) { // Normalize before comparing. CIMDateTimeRep x1 = *x; _normalize(&x1); CIMDateTimeRep y1 = *y; _normalize(&y1); char s1[26]; char s2[26]; _toCStr(&x1, s1); _toCStr(&y1, s2); return _matchTimeStampStrings(s1, s2); } else { char s1[26]; char s2[26]; _toCStr(x, s1); _toCStr(y, s2); return _matchTimeStampStrings(s1, s2); } }}//==============================================================================//// CIMDateTime////==============================================================================const Uint32 CIMDateTime::WILDCARD = Uint32(-1);CIMDateTime::CIMDateTime(){ _rep = new CIMDateTimeRep; memset(_rep, 0, sizeof(CIMDateTimeRep)); _rep->sign = ':';}CIMDateTime::CIMDateTime(const CIMDateTime& x){ _rep = new CIMDateTimeRep; memcpy(_rep, x._rep, sizeof(CIMDateTimeRep));}CIMDateTime::CIMDateTime(const String& str){ _rep = new CIMDateTimeRep; set(str);}CIMDateTime::CIMDateTime(Uint64 usec, Boolean isInterval){ if (!isInterval && usec >= TEN_THOUSAND_YEARS) { MessageLoaderParms parms( "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION", "Cannot create a CIMDateTime time stamp beyond the year 10,000"); throw DateTimeOutOfRangeException(parms); } if (isInterval && usec >= HUNDRED_MILLION_DAYS) { MessageLoaderParms parms( "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION", "Cannot create a CIMDateTime interval greater than 100 million " "days"); throw DateTimeOutOfRangeException(parms); } _rep = new CIMDateTimeRep; _rep->usec = usec; _rep->utcOffset = 0; _rep->sign = isInterval ? ':' : '+'; _rep->numWildcards = 0;}CIMDateTime::CIMDateTime( Uint32 year, Uint32 month, Uint32 day, Uint32 hours, Uint32 minutes, Uint32 seconds, Uint32 microseconds, Uint32 numSignificantMicrosecondDigits, Sint32 utcOffset){ _rep = new CIMDateTimeRep; setTimeStamp(year, month, day, hours, minutes, seconds, microseconds, numSignificantMicrosecondDigits, utcOffset);}CIMDateTime::CIMDateTime( Uint32 days, Uint32 hours, Uint32 minutes, Uint32 seconds, Uint32 microseconds, Uint32 numSignificantMicrosecondDigits){ _rep = new CIMDateTimeRep; setInterval(days, hours, minutes, seconds, microseconds, numSignificantMicrosecondDigits);}CIMDateTime::CIMDateTime(CIMDateTimeRep* rep) : _rep(rep){}CIMDateTime::~CIMDateTime(){ delete _rep;}CIMDateTime& CIMDateTime::operator=(const CIMDateTime& x){ if (this != &x) memcpy(_rep, x._rep, sizeof(CIMDateTimeRep)); return *this;}void CIMDateTime::clear(){ memset(_rep, 0, sizeof(CIMDateTimeRep)); _rep->sign = ':';}void CIMDateTime::set(const String& str){ clear(); if (str.size() != 25) throw InvalidDateTimeFormatException(); const Uint16* s = (const Uint16*)str.getChar16Data(); Uint16 sign = s[21]; if (sign == ':') { bool priorWildcards = false; // It's an interval of the form "DDDDDDDDHHMMSS.MMMMMM:000" // Parse days: Uint32 days = _parseComponent(s, 8, priorWildcards); Uint32 hours = _parseComponent(s, 2, priorWildcards); Uint32 minutes = _parseComponent(s, 2, priorWildcards); Uint32 seconds = _parseComponent(s, 2, priorWildcards); // Skip over dot: if (*s++ != '.') throw InvalidDateTimeFormatException(); // Parse microseconds: Uint16 numSignificantMicrosecondDigits; Uint32 microseconds = _parseMicroseconds( s, priorWildcards, numSignificantMicrosecondDigits); // Skip over ':'. s++; // Expect "000". if (!(s[0] == '0' && s[1] == '0' && s[2] == '0')) throw InvalidDateTimeFormatException(); // Set representation: setInterval( days, hours, minutes, seconds, microseconds, numSignificantMicrosecondDigits); } else if (sign == '-' || sign == '+') { bool priorWildcards = false; // It's a time stamp of the form "YYYYMMDDHHMMSS.MMMMMMSUTC" // Parse year, month, day, hours, minutes, seconds: Uint32 year = _parseComponent(s, 4, priorWildcards); Uint32 month = _parseComponent(s, 2, priorWildcards); Uint32 day = _parseComponent(s, 2, priorWildcards); Uint32 hours = _parseComponent(s, 2, priorWildcards); Uint32 minutes = _parseComponent(s, 2, priorWildcards); Uint32 seconds = _parseComponent(s, 2, priorWildcards); // Skip over dot: if (*s++ != '.') throw InvalidDateTimeFormatException(); // Parse microseconds: Uint16 numSignificantMicrosecondDigits; Uint32 microseconds = _parseMicroseconds( s, priorWildcards, numSignificantMicrosecondDigits); // Skip over sign: s++; // Parse UTF offset. Uint32 utcOffset; if (!_strToUint32(s, 3, utcOffset)) throw InvalidDateTimeFormatException(); // Set representation: setTimeStamp( year, month, day, hours, minutes, seconds, microseconds, numSignificantMicrosecondDigits, sign == '+' ? utcOffset : -Sint16(utcOffset)); } else { throw InvalidDateTimeFormatException(); }}void CIMDateTime::setTimeStamp( Uint32 year, Uint32 month, Uint32 day, Uint32 hours, Uint32 minutes, Uint32 seconds, Uint32 microseconds, Uint32 numSignificantMicrosecondDigits, Sint32 utcOffset){ clear(); Uint32 numWildcards = 0; // Check Year: if (year == WILDCARD) { year = 0; numWildcards = 20; } else if (year > 9999) { MessageLoaderParms parms( "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION", "year is greater than 9999"); throw DateTimeOutOfRangeException(parms); } // Check Month: if (month == WILDCARD) { month = 1; if (!numWildcards) numWildcards = 16; } else if (month < 1 || month > 12) { MessageLoaderParms parms( "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION", "illegal month number"); throw DateTimeOutOfRangeException(parms); } // Check day: if (day == WILDCARD) { day = 1; if (!numWildcards) numWildcards = 14; } else if (day < 1 || day > _getDaysPerMonth(year, month)) { MessageLoaderParms parms( "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION", "illegal day number"); throw DateTimeOutOfRangeException(parms); } // Check hours: if (hours == WILDCARD) { hours = 0; if (!numWildcards) numWildcards = 12; } else if (hours > 23) { MessageLoaderParms parms( "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION", "illegal hours number "); throw DateTimeOutOfRangeException(parms); } // Check minutes: if (minutes == WILDCARD) { minutes = 0; if (!numWildcards) numWildcards = 10; } else if (minutes > 59) { MessageLoaderParms parms( "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION", "illegal minutes number "); throw DateTimeOutOfRangeException(parms); } // Check seconds: if (seconds == WILDCARD) { seconds = 0; if (!numWildcards) numWildcards = 8; } else if (seconds > 59) { MessageLoaderParms parms( "Common.Exception.DATETIME_OUT_OF_RANGE_EXCEPTION",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -