summaryrefslogtreecommitdiff
path: root/sax/source/tools/converter.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sax/source/tools/converter.cxx')
-rw-r--r--sax/source/tools/converter.cxx209
1 files changed, 155 insertions, 54 deletions
diff --git a/sax/source/tools/converter.cxx b/sax/source/tools/converter.cxx
index c77e02aa402b..b5c9934636f4 100644
--- a/sax/source/tools/converter.cxx
+++ b/sax/source/tools/converter.cxx
@@ -1234,6 +1234,69 @@ void Converter::convertDate(
convertDateTime(i_rBuffer, dt, pTimeZoneOffset, false);
}
+static void convertTime(
+ OUStringBuffer& i_rBuffer,
+ const com::sun::star::util::DateTime& i_rDateTime)
+{
+ if (i_rDateTime.Hours < 10) {
+ i_rBuffer.append(sal_Unicode('0'));
+ }
+ i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Hours) )
+ .append(sal_Unicode(':'));
+ if (i_rDateTime.Minutes < 10) {
+ i_rBuffer.append(sal_Unicode('0'));
+ }
+ i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Minutes) )
+ .append(sal_Unicode(':'));
+ if (i_rDateTime.Seconds < 10) {
+ i_rBuffer.append(sal_Unicode('0'));
+ }
+ i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Seconds) );
+ if (i_rDateTime.NanoSeconds > 0) {
+ OSL_ENSURE(i_rDateTime.NanoSeconds < 1000000000,"NanoSeconds cannot be more than 999 999 999");
+ i_rBuffer.append(sal_Unicode('.'));
+ std::ostringstream ostr;
+ ostr.fill('0');
+ ostr.width(9);
+ ostr << i_rDateTime.NanoSeconds;
+ i_rBuffer.append(OUString::createFromAscii(ostr.str().c_str()));
+ }
+}
+
+static void convertTimeZone(
+ OUStringBuffer& i_rBuffer,
+ const com::sun::star::util::DateTime& i_rDateTime,
+ sal_Int16 const* pTimeZoneOffset)
+{
+ if (pTimeZoneOffset)
+ {
+ lcl_AppendTimezone(i_rBuffer, *pTimeZoneOffset);
+ }
+ else if (i_rDateTime.IsUTC)
+ {
+ lcl_AppendTimezone(i_rBuffer, 0);
+ }
+}
+
+/** convert util::DateTime to ISO "time" or "dateTime" string */
+void Converter::convertTimeOrDateTime(
+ OUStringBuffer& i_rBuffer,
+ const com::sun::star::util::DateTime& i_rDateTime,
+ sal_Int16 const* pTimeZoneOffset)
+{
+ if (i_rDateTime.Year == 0 ||
+ i_rDateTime.Month < 1 || i_rDateTime.Month > 12 ||
+ i_rDateTime.Day < 1 || i_rDateTime.Day > 31)
+ {
+ convertTime(i_rBuffer, i_rDateTime);
+ convertTimeZone(i_rBuffer, i_rDateTime, pTimeZoneOffset);
+ }
+ else
+ {
+ convertDateTime(i_rBuffer, i_rDateTime, pTimeZoneOffset, true);
+ }
+}
+
/** convert util::DateTime to ISO "date" or "dateTime" string */
void Converter::convertDateTime(
OUStringBuffer& i_rBuffer,
@@ -1242,10 +1305,7 @@ void Converter::convertDateTime(
bool i_bAddTimeIf0AM )
{
const sal_Unicode dash('-');
- const sal_Unicode col (':');
- const sal_Unicode dot ('.');
const sal_Unicode zero('0');
- const sal_Unicode tee ('T');
sal_Int32 const nYear(abs(i_rDateTime.Year));
if (i_rDateTime.Year < 0) {
@@ -1275,41 +1335,11 @@ void Converter::convertDateTime(
i_rDateTime.Hours != 0 ||
i_bAddTimeIf0AM )
{
- i_rBuffer.append(tee);
- if( i_rDateTime.Hours < 10 ) {
- i_rBuffer.append(zero);
- }
- i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Hours) )
- .append(col);
- if( i_rDateTime.Minutes < 10 ) {
- i_rBuffer.append(zero);
- }
- i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Minutes) )
- .append(col);
- if( i_rDateTime.Seconds < 10 ) {
- i_rBuffer.append(zero);
- }
- i_rBuffer.append( static_cast<sal_Int32>(i_rDateTime.Seconds) );
- if( i_rDateTime.NanoSeconds > 0 ) {
- OSL_ENSURE(i_rDateTime.NanoSeconds < 1000000000,"NanoSeconds cannot be more than 999 999 999");
- i_rBuffer.append(dot);
- std::ostringstream ostr;
- ostr.fill('0');
- ostr.width(9);
- ostr << i_rDateTime.NanoSeconds;
- i_rBuffer.append(OUString::createFromAscii(ostr.str().c_str()));
- }
+ i_rBuffer.append(sal_Unicode('T'));
+ convertTime(i_rBuffer, i_rDateTime);
}
- if (pTimeZoneOffset)
- {
- lcl_AppendTimezone(i_rBuffer, *pTimeZoneOffset);
- }
- else if (i_rDateTime.IsUTC)
- {
- // append local time
- lcl_AppendTimezone(i_rBuffer, 0);
- }
+ convertTimeZone(i_rBuffer, i_rDateTime, pTimeZoneOffset);
}
/** convert ISO "date" or "dateTime" string to util::DateTime */
@@ -1362,11 +1392,17 @@ static void lcl_ConvertToUTC(
{
return;
}
+ sal_Int16 nDayAdd(0);
while (24 <= o_rHours)
{
o_rHours -= 24;
- ++o_rDay;
+ ++nDayAdd;
+ }
+ if (o_rDay == 0)
+ {
+ return; // handle time without date - don't adjust what isn't there
}
+ o_rDay += nDayAdd;
sal_Int16 const nDaysInMonth(lcl_MaxDaysPerMonth(o_rMonth, o_rYear));
if (o_rDay <= nDaysInMonth)
{
@@ -1397,6 +1433,10 @@ static void lcl_ConvertToUTC(
++nDaySubtract;
}
o_rHours -= nOffsetHours;
+ if (o_rDay == 0)
+ {
+ return; // handle time without date - don't adjust what isn't there
+ }
if (nDaySubtract < o_rDay)
{
o_rDay -= nDaySubtract;
@@ -1436,20 +1476,17 @@ readDateTimeComponent(const OUString & rString,
return true;
}
-
-
/** convert ISO "date" or "dateTime" string to util::DateTime or util::Date */
-bool Converter::parseDateOrDateTime(
- util::Date *const pDate, util::DateTime & rDateTime,
- bool & rbDateTime,
- boost::optional<sal_Int16> *const pTimeZoneOffset,
- const OUString & rString )
+static bool lcl_parseDate(
+ bool & isNegative,
+ sal_Int32 & nYear, sal_Int32 & nMonth, sal_Int32 & nDay,
+ bool & bHaveTime,
+ sal_Int32 & nPos,
+ const OUString & string,
+ bool const bIgnoreInvalidOrMissingDate)
{
bool bSuccess = true;
- bool isNegative(false);
- const OUString string = rString.trim().toAsciiUpperCase();
- sal_Int32 nPos(0);
if (string.getLength() > nPos)
{
if ('-' == string[nPos])
@@ -1459,13 +1496,15 @@ bool Converter::parseDateOrDateTime(
}
}
- sal_Int32 nYear(0);
{
// While W3C XMLSchema specifies years with a minimum of 4 digits, be
// leninent in what we accept for years < 1000. One digit is acceptable
// if the remainders match.
bSuccess = readDateTimeComponent(string, nPos, nYear, 1, false);
- bSuccess &= (0 < nYear);
+ if (!bIgnoreInvalidOrMissingDate)
+ {
+ bSuccess &= (0 < nYear);
+ }
bSuccess &= (nPos < string.getLength()); // not last token
}
if (bSuccess && ('-' != string[nPos])) // separator
@@ -1477,11 +1516,14 @@ bool Converter::parseDateOrDateTime(
++nPos;
}
- sal_Int32 nMonth(0);
if (bSuccess)
{
bSuccess = readDateTimeComponent(string, nPos, nMonth, 2, true);
- bSuccess &= (0 < nMonth) && (nMonth <= 12);
+ if (!bIgnoreInvalidOrMissingDate)
+ {
+ bSuccess &= (0 < nMonth);
+ }
+ bSuccess &= (nMonth <= 12);
bSuccess &= (nPos < string.getLength()); // not last token
}
if (bSuccess && ('-' != string[nPos])) // separator
@@ -1493,14 +1535,16 @@ bool Converter::parseDateOrDateTime(
++nPos;
}
- sal_Int32 nDay(0);
if (bSuccess)
{
bSuccess = readDateTimeComponent(string, nPos, nDay, 2, true);
- bSuccess &= (0 < nDay) && (nDay <= lcl_MaxDaysPerMonth(nMonth, nYear));
+ if (!bIgnoreInvalidOrMissingDate)
+ {
+ bSuccess &= (0 < nDay);
+ }
+ bSuccess &= (nDay <= lcl_MaxDaysPerMonth(nMonth, nYear));
}
- bool bHaveTime(false);
if (bSuccess && (nPos < string.getLength()))
{
if ('T' == string[nPos]) // time separator
@@ -1510,6 +1554,41 @@ bool Converter::parseDateOrDateTime(
}
}
+ return bSuccess;
+}
+
+/** convert ISO "date" or "dateTime" string to util::DateTime or util::Date */
+static bool lcl_parseDateTime(
+ util::Date *const pDate, util::DateTime & rDateTime,
+ bool & rbDateTime,
+ boost::optional<sal_Int16> *const pTimeZoneOffset,
+ const OUString & rString,
+ bool const bIgnoreInvalidOrMissingDate)
+{
+ bool bSuccess = true;
+
+ const OUString string = rString.trim().toAsciiUpperCase();
+
+ bool isNegative(false);
+ sal_Int32 nYear(0);
+ sal_Int32 nMonth(0);
+ sal_Int32 nDay(0);
+ sal_Int32 nPos(0);
+ bool bHaveTime(false);
+
+ if ( !bIgnoreInvalidOrMissingDate
+ || string.indexOf(':') == -1 // no time?
+ || (string.indexOf('-') != -1
+ && string.indexOf('-') < string.indexOf(':')))
+ {
+ bSuccess &= lcl_parseDate(isNegative, nYear, nMonth, nDay,
+ bHaveTime, nPos, string, bIgnoreInvalidOrMissingDate);
+ }
+ else
+ {
+ bHaveTime = true;
+ }
+
sal_Int32 nHours(0);
sal_Int32 nMinutes(0);
sal_Int32 nSeconds(0);
@@ -1708,6 +1787,28 @@ bool Converter::parseDateOrDateTime(
return bSuccess;
}
+/** convert ISO "time" or "dateTime" string to util::DateTime */
+bool Converter::parseTimeOrDateTime(
+ util::DateTime & rDateTime,
+ boost::optional<sal_Int16> * pTimeZoneOffset,
+ const OUString & rString)
+{
+ bool dummy;
+ return lcl_parseDateTime(
+ 0, rDateTime, dummy, pTimeZoneOffset, rString, true);
+}
+
+/** convert ISO "date" or "dateTime" string to util::DateTime or util::Date */
+bool Converter::parseDateOrDateTime(
+ util::Date *const pDate, util::DateTime & rDateTime,
+ bool & rbDateTime,
+ boost::optional<sal_Int16> *const pTimeZoneOffset,
+ const OUString & rString )
+{
+ return lcl_parseDateTime(
+ pDate, rDateTime, rbDateTime, pTimeZoneOffset, rString, false);
+}
+
/** gets the position of the first comma after npos in the string
rStr. Commas inside '"' pairs are not matched */