mso-test: invalid datetime in props
This is using the test document from tdf119234-3.odt. When importing and exporting to DOCX, we generate an invalid entry in docprops/custom.xml because we dont know how to handle a DateTimeWithTimezone value.. Change-Id: I79981f8a09db432730a9b0c1cf186305b0055923 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193400 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Michael Stahl <michael.stahl@collabora.com> (cherry picked from commit 97cf170c20c7ff1e1b3820a769cd3167a57d0c46) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193600 Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk> Tested-by: Jenkins
This commit is contained in:
@@ -259,6 +259,12 @@ public:
|
||||
sal_Int16 const* pTimeZoneOffset,
|
||||
bool bAddTimeIf0AM = false );
|
||||
|
||||
/** convert util::DateTime to XMLSchema-2 "date" or "dateTime" string */
|
||||
static void convertDateTime( OStringBuffer& rBuffer,
|
||||
const css::util::DateTime& rDateTime,
|
||||
sal_Int16 const* pTimeZoneOffset,
|
||||
bool bAddTimeIf0AM = false );
|
||||
|
||||
/** convert util::DateTime to XMLSchema-2 "time" or "dateTime" string */
|
||||
static void convertTimeOrDateTime(OUStringBuffer& rBuffer,
|
||||
const css::util::DateTime& rDateTime);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <com/sun/star/embed/XRelationshipAccess.hpp>
|
||||
#include <com/sun/star/frame/XModel.hpp>
|
||||
#include <com/sun/star/text/XTextDocument.hpp>
|
||||
#include <com/sun/star/util/DateTimeWithTimezone.hpp>
|
||||
#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
|
||||
#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
|
||||
#include <com/sun/star/xml/sax/Writer.hpp>
|
||||
@@ -624,6 +625,31 @@ writeElement( const FSHelperPtr& pDoc, sal_Int32 nXmlElement, const util::DateTi
|
||||
pDoc->endElement( nXmlElement );
|
||||
}
|
||||
|
||||
static void
|
||||
writeElement( const FSHelperPtr& pDoc, sal_Int32 nXmlElement, const util::DateTimeWithTimezone& rTime )
|
||||
{
|
||||
if (rTime.Timezone == 0)
|
||||
{
|
||||
writeElement(pDoc, nXmlElement, rTime.DateTimeInTZ);
|
||||
return;
|
||||
}
|
||||
|
||||
if( rTime.DateTimeInTZ.Year == 0 )
|
||||
return;
|
||||
|
||||
if ( ( nXmlElement >> 16 ) != XML_dcterms )
|
||||
pDoc->startElement(nXmlElement);
|
||||
else
|
||||
pDoc->startElement(nXmlElement, FSNS(XML_xsi, XML_type), "dcterms:W3CDTF");
|
||||
|
||||
OStringBuffer aStr;
|
||||
sax::Converter::convertDateTime(aStr, rTime.DateTimeInTZ, &rTime.Timezone);
|
||||
|
||||
pDoc->write( aStr );
|
||||
|
||||
pDoc->endElement( nXmlElement );
|
||||
}
|
||||
|
||||
static void
|
||||
writeElement( const FSHelperPtr& pDoc, sal_Int32 nXmlElement, const Sequence< OUString >& aItems )
|
||||
{
|
||||
@@ -976,6 +1002,7 @@ writeCustomProperties( XmlFilterBase& rSelf, const Reference< XDocumentPropertie
|
||||
util::Date aDate;
|
||||
util::Duration aDuration;
|
||||
util::DateTime aDateTime;
|
||||
util::DateTimeWithTimezone aDateTimeTZ;
|
||||
if ( rProp.Value >>= num )
|
||||
{
|
||||
// i4 - 4-byte signed integer
|
||||
@@ -995,6 +1022,8 @@ writeCustomProperties( XmlFilterBase& rSelf, const Reference< XDocumentPropertie
|
||||
}
|
||||
else if ( rProp.Value >>= aDateTime )
|
||||
writeElement( pAppProps, FSNS( XML_vt, XML_filetime ), aDateTime );
|
||||
else if ( rProp.Value >>= aDateTimeTZ )
|
||||
writeElement( pAppProps, FSNS( XML_vt, XML_filetime ), aDateTimeTZ );
|
||||
else
|
||||
//no other options
|
||||
OSL_FAIL( "XMLFilterBase::writeCustomProperties unsupported value type!" );
|
||||
|
||||
@@ -1572,8 +1572,9 @@ bool Converter::convertDuration(util::Duration& rDuration,
|
||||
return convertDurationHelper(rDuration, o3tl::trim(rString));
|
||||
}
|
||||
|
||||
template<typename TStringBuffer>
|
||||
static void
|
||||
lcl_AppendTimezone(OUStringBuffer & i_rBuffer, int const nOffset)
|
||||
lcl_AppendTimezone(TStringBuffer & i_rBuffer, int const nOffset)
|
||||
{
|
||||
if (0 == nOffset)
|
||||
{
|
||||
@@ -1618,18 +1619,19 @@ void Converter::convertDate(
|
||||
convertDateTime(i_rBuffer, dt, pTimeZoneOffset);
|
||||
}
|
||||
|
||||
template<typename TStringBuffer, typename TString>
|
||||
static void convertTime(
|
||||
OUStringBuffer& i_rBuffer,
|
||||
TStringBuffer& i_rBuffer,
|
||||
const css::util::DateTime& i_rDateTime)
|
||||
{
|
||||
if (i_rDateTime.Hours < 10) {
|
||||
i_rBuffer.append('0');
|
||||
}
|
||||
i_rBuffer.append( OUString::number(static_cast<sal_Int32>(i_rDateTime.Hours)) + ":");
|
||||
i_rBuffer.append( TString::number(static_cast<sal_Int32>(i_rDateTime.Hours)) + ":");
|
||||
if (i_rDateTime.Minutes < 10) {
|
||||
i_rBuffer.append('0');
|
||||
}
|
||||
i_rBuffer.append( OUString::number(static_cast<sal_Int32>(i_rDateTime.Minutes) ) + ":");
|
||||
i_rBuffer.append( TString::number(static_cast<sal_Int32>(i_rDateTime.Minutes) ) + ":");
|
||||
if (i_rDateTime.Seconds < 10) {
|
||||
i_rBuffer.append('0');
|
||||
}
|
||||
@@ -1637,16 +1639,17 @@ static void convertTime(
|
||||
if (i_rDateTime.NanoSeconds > 0) {
|
||||
OSL_ENSURE(i_rDateTime.NanoSeconds < 1000000000,"NanoSeconds cannot be more than 999 999 999");
|
||||
i_rBuffer.append('.');
|
||||
std::ostringstream ostr;
|
||||
ostr.fill('0');
|
||||
ostr.width(9);
|
||||
ostr << i_rDateTime.NanoSeconds;
|
||||
i_rBuffer.appendAscii(ostr.str().c_str());
|
||||
// pad to 9 characters length
|
||||
auto sNanoStr = TString::number(i_rDateTime.NanoSeconds);
|
||||
for (int i=0; i < 9 - sNanoStr.length; i++)
|
||||
i_rBuffer.append('0');
|
||||
i_rBuffer.append(sNanoStr);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TStringBuffer>
|
||||
static void convertTimeZone(
|
||||
OUStringBuffer& i_rBuffer,
|
||||
TStringBuffer& i_rBuffer,
|
||||
const css::util::DateTime& i_rDateTime,
|
||||
sal_Int16 const* pTimeZoneOffset)
|
||||
{
|
||||
@@ -1669,7 +1672,7 @@ void Converter::convertTimeOrDateTime(
|
||||
i_rDateTime.Month < 1 || i_rDateTime.Month > 12 ||
|
||||
i_rDateTime.Day < 1 || i_rDateTime.Day > 31)
|
||||
{
|
||||
convertTime(i_rBuffer, i_rDateTime);
|
||||
convertTime<OUStringBuffer, OUString>(i_rBuffer, i_rDateTime);
|
||||
convertTimeZone(i_rBuffer, i_rDateTime, nullptr);
|
||||
}
|
||||
else
|
||||
@@ -1679,14 +1682,15 @@ void Converter::convertTimeOrDateTime(
|
||||
}
|
||||
|
||||
/** convert util::DateTime to ISO "date" or "dateTime" string */
|
||||
void Converter::convertDateTime(
|
||||
OUStringBuffer& i_rBuffer,
|
||||
template<typename TStringBuffer, typename TString, typename TStringChar>
|
||||
static void lcl_convertDateTime(
|
||||
TStringBuffer& i_rBuffer,
|
||||
const css::util::DateTime& i_rDateTime,
|
||||
sal_Int16 const*const pTimeZoneOffset,
|
||||
bool i_bAddTimeIf0AM )
|
||||
{
|
||||
const sal_Unicode dash('-');
|
||||
const sal_Unicode zero('0');
|
||||
const char dash('-');
|
||||
const char zero('0');
|
||||
|
||||
sal_Int32 const nYear(abs(i_rDateTime.Year));
|
||||
if (i_rDateTime.Year < 0) {
|
||||
@@ -1701,11 +1705,11 @@ void Converter::convertDateTime(
|
||||
if (nYear < 10) {
|
||||
i_rBuffer.append(zero);
|
||||
}
|
||||
i_rBuffer.append( OUString::number(nYear) + OUStringChar(dash) );
|
||||
i_rBuffer.append( TString::number(nYear) + TStringChar(dash) );
|
||||
if( i_rDateTime.Month < 10 ) {
|
||||
i_rBuffer.append(zero);
|
||||
}
|
||||
i_rBuffer.append( OUString::number(i_rDateTime.Month) + OUStringChar(dash) );
|
||||
i_rBuffer.append( TString::number(i_rDateTime.Month) + TStringChar(dash) );
|
||||
if( i_rDateTime.Day < 10 ) {
|
||||
i_rBuffer.append(zero);
|
||||
}
|
||||
@@ -1717,12 +1721,32 @@ void Converter::convertDateTime(
|
||||
i_bAddTimeIf0AM )
|
||||
{
|
||||
i_rBuffer.append('T');
|
||||
convertTime(i_rBuffer, i_rDateTime);
|
||||
convertTime<TStringBuffer, TString>(i_rBuffer, i_rDateTime);
|
||||
}
|
||||
|
||||
convertTimeZone(i_rBuffer, i_rDateTime, pTimeZoneOffset);
|
||||
}
|
||||
|
||||
/** convert util::DateTime to ISO "date" or "dateTime" string */
|
||||
void Converter::convertDateTime(
|
||||
OUStringBuffer& i_rBuffer,
|
||||
const css::util::DateTime& i_rDateTime,
|
||||
sal_Int16 const*const pTimeZoneOffset,
|
||||
bool i_bAddTimeIf0AM )
|
||||
{
|
||||
lcl_convertDateTime<OUStringBuffer, OUString, OUStringChar>(i_rBuffer, i_rDateTime, pTimeZoneOffset, i_bAddTimeIf0AM);
|
||||
}
|
||||
|
||||
/** convert util::DateTime to ISO "date" or "dateTime" string */
|
||||
void Converter::convertDateTime(
|
||||
OStringBuffer& i_rBuffer,
|
||||
const css::util::DateTime& i_rDateTime,
|
||||
sal_Int16 const*const pTimeZoneOffset,
|
||||
bool i_bAddTimeIf0AM )
|
||||
{
|
||||
lcl_convertDateTime<OStringBuffer, OString, OStringChar>(i_rBuffer, i_rDateTime, pTimeZoneOffset, i_bAddTimeIf0AM);
|
||||
}
|
||||
|
||||
/** convert ISO "date" or "dateTime" string to util::DateTime */
|
||||
bool Converter::parseDateTime( util::DateTime& rDateTime,
|
||||
std::u16string_view rString )
|
||||
|
||||
Reference in New Issue
Block a user