You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by ca...@apache.org on 2005/07/25 16:06:15 UTC
svn commit: r225128 - in /xerces/c/trunk/src/xercesc/util: XMLDateTime.cpp
XMLDateTime.hpp
Author: cargilld
Date: Mon Jul 25 07:06:12 2005
New Revision: 225128
URL: http://svn.apache.org/viewcvs?rev=225128&view=rev
Log:
Fix various schema date time problems.
Modified:
xerces/c/trunk/src/xercesc/util/XMLDateTime.cpp
xerces/c/trunk/src/xercesc/util/XMLDateTime.hpp
Modified: xerces/c/trunk/src/xercesc/util/XMLDateTime.cpp
URL: http://svn.apache.org/viewcvs/xerces/c/trunk/src/xercesc/util/XMLDateTime.cpp?rev=225128&r1=225127&r2=225128&view=diff
==============================================================================
--- xerces/c/trunk/src/xercesc/util/XMLDateTime.cpp (original)
+++ xerces/c/trunk/src/xercesc/util/XMLDateTime.cpp Mon Jul 25 07:06:12 2005
@@ -229,6 +229,10 @@
int temp = DATETIMES[index][Month] + fDuration->fValue[Month];
fNewDate->fValue[Month] = modulo(temp, 1, 13);
int carry = fQuotient(temp, 1, 13);
+ if (fNewDate->fValue[Month] < 0) {
+ fNewDate->fValue[Month]+= 12;
+ carry--;
+ }
//add years (may be modified additionaly below)
fNewDate->fValue[CentYear] = DATETIMES[index][CentYear] + fDuration->fValue[CentYear] + carry;
@@ -237,17 +241,29 @@
temp = DATETIMES[index][Second] + fDuration->fValue[Second];
carry = fQuotient (temp, 60);
fNewDate->fValue[Second] = mod(temp, 60, carry);
-
+ if (fNewDate->fValue[Second] < 0) {
+ fNewDate->fValue[Second]+= 60;
+ carry--;
+ }
+
//add minutes
temp = DATETIMES[index][Minute] + fDuration->fValue[Minute] + carry;
carry = fQuotient(temp, 60);
fNewDate->fValue[Minute] = mod(temp, 60, carry);
+ if (fNewDate->fValue[Minute] < 0) {
+ fNewDate->fValue[Minute]+= 60;
+ carry--;
+ }
//add hours
temp = DATETIMES[index][Hour] + fDuration->fValue[Hour] + carry;
carry = fQuotient(temp, 24);
fNewDate->fValue[Hour] = mod(temp, 24, carry);
-
+ if (fNewDate->fValue[Hour] < 0) {
+ fNewDate->fValue[Hour]+= 24;
+ carry--;
+ }
+
fNewDate->fValue[Day] = DATETIMES[index][Day] + fDuration->fValue[Day] + carry;
while ( true )
@@ -270,7 +286,12 @@
temp = fNewDate->fValue[Month] + carry;
fNewDate->fValue[Month] = modulo(temp, 1, 13);
- fNewDate->fValue[CentYear] += fQuotient(temp, 1, 13);
+ if (fNewDate->fValue[Month] < 0) {
+ fNewDate->fValue[Month]+= 12;
+ carry--;
+ }
+ else
+ fNewDate->fValue[CentYear] += fQuotient(temp, 1, 13);
}
//fNewDate->fValue[utc] = UTC_STD_CHAR;
@@ -1176,16 +1197,26 @@
return;
int negate = (fValue[utc] == UTC_POS)? -1: 1;
+ int temp;
+ int carry;
// add mins
- int temp = fValue[Minute] + negate * fTimeZone[mm];
- int carry = fQuotient(temp, 60);
+ temp = fValue[Minute] + negate * fTimeZone[mm];
+ carry = fQuotient(temp, 60);
fValue[Minute] = mod(temp, 60, carry);
-
+ if (temp < 0) {
+ fValue[Minute] = temp + 60;
+ carry--;
+ }
+
//add hours
temp = fValue[Hour] + negate * fTimeZone[hh] + carry;
carry = fQuotient(temp, 24);
fValue[Hour] = mod(temp, 24, carry);
+ if (temp < 0) {
+ fValue[Hour] = temp + 24;
+ carry--;
+ }
fValue[Day] += carry;
@@ -1209,6 +1240,10 @@
temp = fValue[Month] + carry;
fValue[Month] = modulo(temp, 1, 13);
+ if (fValue[Month] <=0) {
+ fValue[Month]+= 12;
+ fValue[CentYear]--;
+ }
fValue[CentYear] += fQuotient(temp, 1, 13);
}
@@ -1447,15 +1482,16 @@
XMLCh *miliStartPtr, *miliEndPtr;
searchMiliSeconds(miliStartPtr, miliEndPtr);
int miliSecondsLen = miliEndPtr - miliStartPtr;
+ int utcSize = (fValue[utc] == UTC_UNKNOWN) ? 0 : 1;
MemoryManager* toUse = memMgr? memMgr : fMemoryManager;
- XMLCh* retBuf = (XMLCh*) toUse->allocate( (21 + miliSecondsLen + 2) * sizeof(XMLCh));
+ XMLCh* retBuf = (XMLCh*) toUse->allocate( (21 + miliSecondsLen + utcSize + 1) * sizeof(XMLCh));
XMLCh* retPtr = retBuf;
// (-?) cc+yy-mm-dd'T'hh:mm:ss'Z' ('.'s+)?
// 2+ 8 1 8 1
//
- int additionalLen = fillYearString(retPtr, CentYear);
+ int additionalLen = fillYearString(retPtr, fValue[CentYear]);
if(additionalLen != 0)
{
// very bad luck; have to resize the buffer...
@@ -1466,21 +1502,21 @@
retBuf = tmpBuf;
}
*retPtr++ = DATE_SEPARATOR;
- fillString(retPtr, Month, 2);
+ fillString(retPtr, fValue[Month], 2);
*retPtr++ = DATE_SEPARATOR;
- fillString(retPtr, Day, 2);
+ fillString(retPtr, fValue[Day], 2);
*retPtr++ = DATETIME_SEPARATOR;
- fillString(retPtr, Hour, 2);
+ fillString(retPtr, fValue[Hour], 2);
if (fValue[Hour] == 24)
{
*(retPtr - 2) = chDigit_0;
*(retPtr - 1) = chDigit_0;
}
*retPtr++ = TIME_SEPARATOR;
- fillString(retPtr, Minute, 2);
+ fillString(retPtr, fValue[Minute], 2);
*retPtr++ = TIME_SEPARATOR;
- fillString(retPtr, Second, 2);
+ fillString(retPtr, fValue[Second], 2);
if (miliSecondsLen)
{
@@ -1489,13 +1525,164 @@
retPtr += miliSecondsLen;
}
- *retPtr++ = UTC_STD_CHAR;
+ if (utcSize)
+ *retPtr++ = UTC_STD_CHAR;
*retPtr = chNull;
return retBuf;
}
/***
+ * E2-41
+ *
+ * 3.2.9.2 Canonical representation
+ *
+ * Given a member of the date value space, the date
+ * portion of the canonical representation (the entire
+ * representation for nontimezoned values, and all but
+ * the timezone representation for timezoned values)
+ * is always the date portion of the dateTime canonical
+ * representation of the interval midpoint (the
+ * dateTime representation, truncated on the right
+ * to eliminate 'T' and all following characters).
+ * For timezoned values, append the canonical
+ * representation of the recoverable timezone.
+ *
+ ***/
+XMLCh* XMLDateTime::getDateCanonicalRepresentation(MemoryManager* const memMgr) const
+{
+ /*
+ * Case Date Actual Value Canonical Value
+ * 1 yyyy-mm-dd yyyy-mm-dd yyyy-mm-dd
+ * 2 yyyy-mm-ddZ yyyy-mm-ddT00:00Z yyyy-mm-ddZ
+ * 3 yyyy-mm-dd+00:00 yyyy-mm-ddT00:00Z yyyy-mm-ddZ
+ * 4 yyyy-mm-dd+00:01 YYYY-MM-DCT23:59Z yyyy-mm-dd+00:01
+ * 5 yyyy-mm-dd+12:00 YYYY-MM-DCT12:00Z yyyy-mm-dd+12:00
+ * 6 yyyy-mm-dd+12:01 YYYY-MM-DCT11:59Z YYYY-MM-DC-11:59
+ * 7 yyyy-mm-dd+14:00 YYYY-MM-DCT10:00Z YYYY-MM-DC-10:00
+ * 8 yyyy-mm-dd-00:00 yyyy-mm-ddT00:00Z yyyy-mm-ddZ
+ * 9 yyyy-mm-dd-00:01 yyyy-mm-ddT00:01Z yyyy-mm-dd-00:01
+ * 11 yyyy-mm-dd-11:59 yyyy-mm-ddT11:59Z YYYY-MM-DD-11:59
+ * 10 yyyy-mm-dd-12:00 yyyy-mm-ddT12:00Z YYYY-MM-DD+12:00
+ * 12 yyyy-mm-dd-14:00 yyyy-mm-ddT14:00Z YYYY-MM-DD+10:00
+ */
+ int utcSize = (fValue[utc] == UTC_UNKNOWN) ? 0 : 1;
+ // YYYY-MM-DD + chNull
+ // 1234567890 + 1
+ int memLength = 10 + 1 + utcSize;
+
+ if (fTimeZone[hh] != 0 || fTimeZone[mm] != 0) {
+ // YYYY-MM-DD+HH:MM (utcSize will be 1 so drop that)
+ // 1234567890123456
+ memLength += 5; // 6 - 1 for utcSize
+ }
+
+ MemoryManager* toUse = memMgr? memMgr : fMemoryManager;
+ XMLCh* retBuf = (XMLCh*) toUse->allocate( (memLength) * sizeof(XMLCh));
+ XMLCh* retPtr = retBuf;
+
+ if (fValue[Hour] < 12) {
+
+ int additionalLen = fillYearString(retPtr, fValue[CentYear]);
+ if (additionalLen != 0) {
+ // very bad luck; have to resize the buffer...
+ XMLCh *tmpBuf = (XMLCh*) toUse->allocate( (additionalLen + memLength ) * sizeof(XMLCh));
+ XMLString::moveChars(tmpBuf, retBuf, 4+additionalLen);
+ retPtr = tmpBuf+(retPtr-retBuf);
+ toUse->deallocate(retBuf);
+ retBuf = tmpBuf;
+ }
+ *retPtr++ = DATE_SEPARATOR;
+ fillString(retPtr, fValue[Month], 2);
+ *retPtr++ = DATE_SEPARATOR;
+ fillString(retPtr, fValue[Day], 2);
+
+ if (utcSize) {
+ if (fTimeZone[hh] != 0 || fTimeZone[mm] != 0) {
+ *retPtr++ = UTC_NEG_CHAR;
+ fillString(retPtr, fValue[Hour], 2);
+ *retPtr++ = TIME_SEPARATOR;
+ fillString(retPtr, fValue[Minute], 2);
+ }
+ else {
+ *retPtr++ = UTC_STD_CHAR;
+ }
+ }
+ *retPtr = chNull;
+ }
+ else {
+ /*
+ * Need to reconvert things to get a recoverable time zone between
+ * +12:00 and -11:59
+ */
+ int carry;
+ int minute;
+ int hour;
+ int day;
+ int month;
+ int year;
+ if (fValue[Minute] == 0) {
+ minute = 0;
+ carry = 0;
+ }
+ else {
+ minute = 60 - fValue[Minute];
+ carry = 1;
+ }
+ hour = 24 - fValue[Hour] - carry;
+ day = fValue[Day] + 1;
+ month = fValue[Month];
+ year = fValue[CentYear];
+
+ while (1) {
+ int temp = maxDayInMonthFor(year, month);
+ if (day < 1) {
+ day += maxDayInMonthFor(year, month - 1);
+ carry = -1;
+ }
+ else if (day > temp) {
+ day -= temp;
+ carry = 1;
+ }
+ else {
+ break;
+ }
+
+ temp = month + carry;
+ month = modulo(temp, 1, 13);
+ if (month <= 0) {
+ month+= 12;
+ year--;
+ }
+ else
+ year += fQuotient(temp, 1, 13);
+ }
+
+ int additionalLen = fillYearString(retPtr, year);
+ if (additionalLen != 0) {
+ // very bad luck; have to resize the buffer...
+ XMLCh *tmpBuf = (XMLCh*) toUse->allocate( (additionalLen + memLength ) * sizeof(XMLCh));
+ XMLString::moveChars(tmpBuf, retBuf, 4+additionalLen);
+ retPtr = tmpBuf+(retPtr-retBuf);
+ toUse->deallocate(retBuf);
+ retBuf = tmpBuf;
+ }
+ *retPtr++ = DATE_SEPARATOR;
+ fillString(retPtr, month, 2);
+ *retPtr++ = DATE_SEPARATOR;
+ fillString(retPtr, day, 2);
+
+ *retPtr++ = UTC_POS_CHAR;
+ fillString(retPtr, hour, 2);
+ *retPtr++ = TIME_SEPARATOR;
+ fillString(retPtr, minute, 2);
+ *retPtr = chNull;
+ }
+ return retBuf;
+}
+
+
+/***
* 3.2.8 time
*
* . either the time zone must be omitted or,
@@ -1509,25 +1696,26 @@
XMLCh *miliStartPtr, *miliEndPtr;
searchMiliSeconds(miliStartPtr, miliEndPtr);
int miliSecondsLen = miliEndPtr - miliStartPtr;
-
+ int utcSize = (fValue[utc] == UTC_UNKNOWN) ? 0 : 1;
+
MemoryManager* toUse = memMgr? memMgr : fMemoryManager;
- XMLCh* retBuf = (XMLCh*) toUse->allocate( (10 + miliSecondsLen + 2) * sizeof(XMLCh));
+ XMLCh* retBuf = (XMLCh*) toUse->allocate( (10 + miliSecondsLen + utcSize + 1) * sizeof(XMLCh));
XMLCh* retPtr = retBuf;
// 'hh:mm:ss'Z' ('.'s+)?
// 8 1
//
- fillString(retPtr, Hour, 2);
+ fillString(retPtr, fValue[Hour], 2);
if (fValue[Hour] == 24)
{
*(retPtr - 2) = chDigit_0;
*(retPtr - 1) = chDigit_0;
}
*retPtr++ = TIME_SEPARATOR;
- fillString(retPtr, Minute, 2);
+ fillString(retPtr, fValue[Minute], 2);
*retPtr++ = TIME_SEPARATOR;
- fillString(retPtr, Second, 2);
+ fillString(retPtr, fValue[Second], 2);
if (miliSecondsLen)
{
@@ -1536,17 +1724,18 @@
retPtr += miliSecondsLen;
}
- *retPtr++ = UTC_STD_CHAR;
+ if (utcSize)
+ *retPtr++ = UTC_STD_CHAR;
*retPtr = chNull;
return retBuf;
}
-void XMLDateTime::fillString(XMLCh*& ptr, valueIndex ind, int expLen) const
+void XMLDateTime::fillString(XMLCh*& ptr, int value, int expLen) const
{
XMLCh strBuffer[16];
assert(expLen < 16);
- XMLString::binToText(fValue[ind], strBuffer, expLen, 10, fMemoryManager);
+ XMLString::binToText(value, strBuffer, expLen, 10, fMemoryManager);
int actualLen = XMLString::stringLen(strBuffer);
int i;
//append leading zeros
@@ -1562,11 +1751,11 @@
}
-int XMLDateTime::fillYearString(XMLCh*& ptr, valueIndex ind) const
+int XMLDateTime::fillYearString(XMLCh*& ptr, int value) const
{
XMLCh strBuffer[16];
// let's hope we get no years of 15 digits...
- XMLString::binToText(fValue[ind], strBuffer, 15, 10, fMemoryManager);
+ XMLString::binToText(value, strBuffer, 15, 10, fMemoryManager);
int actualLen = XMLString::stringLen(strBuffer);
// don't forget that years can be negative...
int negativeYear = 0;
Modified: xerces/c/trunk/src/xercesc/util/XMLDateTime.hpp
URL: http://svn.apache.org/viewcvs/xerces/c/trunk/src/xercesc/util/XMLDateTime.hpp?rev=225128&r1=225127&r2=225128&view=diff
==============================================================================
--- xerces/c/trunk/src/xercesc/util/XMLDateTime.hpp (original)
+++ xerces/c/trunk/src/xercesc/util/XMLDateTime.hpp Mon Jul 25 07:06:12 2005
@@ -100,6 +100,8 @@
XMLCh* getTimeCanonicalRepresentation(MemoryManager* const memMgr) const;
+ XMLCh* getDateCanonicalRepresentation(MemoryManager* const memMgr) const;
+
// -----------------------------------------------------------------------
// parsers
// -----------------------------------------------------------------------
@@ -228,9 +230,9 @@
void normalize();
- void fillString(XMLCh*& ptr, valueIndex ind, int expLen) const;
+ void fillString(XMLCh*& ptr, int value, int expLen) const;
- int fillYearString(XMLCh*& ptr, valueIndex ind) const;
+ int fillYearString(XMLCh*& ptr, int value) const;
void searchMiliSeconds(XMLCh*& miliStartPtr, XMLCh*& miliEndPtr) const;
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xerces.apache.org
For additional commands, e-mail: commits-help@xerces.apache.org