[Libreoffice-commits] core.git: 7 commits - editeng/source include/editeng include/sax include/svl sax/qa sax/source sd/source sfx2/inc sfx2/source svl/Library_svl.mk svl/source svtools/source sw/source xmloff/inc xmloff/source

Michael Stahl mstahl at redhat.com
Tue Dec 10 06:31:50 PST 2013


 editeng/source/items/flditem.cxx    |   14 +-
 editeng/source/uno/unofield.cxx     |    2 
 include/editeng/flditem.hxx         |    6 -
 include/sax/tools/converter.hxx     |   10 +
 include/svl/dateitem.hxx            |   76 -------------
 sax/qa/cppunit/test_converter.cxx   |  138 +++++++++++++++++++++++
 sax/source/tools/converter.cxx      |  209 ++++++++++++++++++++++++++----------
 sd/source/filter/eppt/pptx-text.cxx |    4 
 sd/source/ui/dlg/dlgassim.hxx       |    1 
 sfx2/inc/pch/precompiled_sfx.hxx    |    1 
 sfx2/source/appl/appdata.cxx        |    1 
 svl/Library_svl.mk                  |    1 
 svl/source/items/dateitem.cxx       |  191 --------------------------------
 svtools/source/contnr/treelist.cxx  |    2 
 sw/source/core/doc/docfld.cxx       |    3 
 sw/source/filter/html/htmlfld.cxx   |    5 
 xmloff/inc/txtflde.hxx              |    6 +
 xmloff/source/text/txtflde.cxx      |   22 +++
 xmloff/source/text/txtfldi.cxx      |    4 
 19 files changed, 350 insertions(+), 346 deletions(-)

New commits:
commit cc407e50e8a1a74f9d1ed29d444dce9bd2e9167a
Author: Michael Stahl <mstahl at redhat.com>
Date:   Tue Dec 10 15:14:00 2013 +0100

    sax, xmloff: fix ODF import/export of text:time/text:time-value
    
    The value written for an Impress time field is something like
    text:time-value="0000-00-00T23:28:07" (in LO 3.5+) or
    text:time-value="0-00-00T23:28:07" (in OOo 3.3) which contains an
    invalid all-zero date.  Such values are actually rejected by the
    ODF import since commit ae3e2f170045a1525f67e9f3e9b7e03d94f2b56b.
    
    Actually there was no real support to read the RelaxNG type
    timeOrDateTime before.
    
    So fix that by:
    - adding convertTimeOrDateTime/parseTimeOrDateTime functions to
      sax::Converter
    - recognizing and ignoring the 2 invalid all-zero values written by
      LO 3.5 and historic OOo respectively
    - writing a bare "time" in text:time-value if the DateTime struct
      contains zero Date members
      (Older OOo versions and AOO cannot actually read that, but everything
      they _can_ read is invalid ODF...)
    
    Change-Id: I754076caee74a5163ed3f972af0f23796aa14f9f

diff --git a/include/sax/tools/converter.hxx b/include/sax/tools/converter.hxx
index 86671ce..77fc138 100644
--- a/include/sax/tools/converter.hxx
+++ b/include/sax/tools/converter.hxx
@@ -166,11 +166,21 @@ public:
                                  sal_Int16 const* pTimeZoneOffset,
                                    bool bAddTimeIf0AM = false );
 
+    /** convert util::DateTime to ISO "time" or "dateTime" string */
+    static void convertTimeOrDateTime(OUStringBuffer& rBuffer,
+                            const com::sun::star::util::DateTime& rDateTime,
+                            sal_Int16 const* pTimeZoneOffset);
+
     /** convert ISO "date" or "dateTime" string to util::DateTime */
     static bool parseDateTime( com::sun::star::util::DateTime& rDateTime,
                                  boost::optional<sal_Int16> * pTimeZoneOffset,
                                  const OUString& rString );
 
+    /** convert ISO "time" or "dateTime" string to util::DateTime */
+    static bool parseTimeOrDateTime(com::sun::star::util::DateTime& rDateTime,
+                                 boost::optional<sal_Int16> * pTimeZoneOffset,
+                                 const OUString& rString);
+
     /** convert ISO "date" or "dateTime" string to util::DateTime or
         util::Date */
     static bool parseDateOrDateTime(
diff --git a/sax/qa/cppunit/test_converter.cxx b/sax/qa/cppunit/test_converter.cxx
index 28eefd9..7145e5e 100644
--- a/sax/qa/cppunit/test_converter.cxx
+++ b/sax/qa/cppunit/test_converter.cxx
@@ -53,6 +53,7 @@ public:
 
     void testDuration();
     void testDateTime();
+    void testTime();
     void testDouble();
     void testMeasure();
     void testBool();
@@ -64,6 +65,7 @@ public:
     CPPUNIT_TEST_SUITE(ConverterTest);
     CPPUNIT_TEST(testDuration);
     CPPUNIT_TEST(testDateTime);
+    CPPUNIT_TEST(testTime);
     CPPUNIT_TEST(testDouble);
     CPPUNIT_TEST(testMeasure);
     CPPUNIT_TEST(testBool);
@@ -240,7 +242,7 @@ void ConverterTest::testDateTime()
     doTestDateTimeF( "0001-13-01T00:00:00" ); // invalid: M > 12
     doTestDateTimeF( "0001-01-32T00:00:00" ); // invalid: D > 31
     doTestDateTimeF( "0001-01-01T25:00:00" ); // invalid: H > 24
-    doTestDateTimeF( "0001-01-01T00:60:00" ); // invalid: H > 59
+    doTestDateTimeF( "0001-01-01T00:60:00" ); // invalid: M > 59
     doTestDateTimeF( "0001-01-01T00:00:60" ); // invalid: S > 59
     doTestDateTimeF( "0001-01-01T24:01:00" ); // invalid: H=24, but M != 0
     doTestDateTimeF( "0001-01-01T24:00:01" ); // invalid: H=24, but S != 0
@@ -251,9 +253,143 @@ void ConverterTest::testDateTime()
     doTestDateTimeF( "0001-01-02T00:00:00-14:01" ); // invalid: TZ < -14:00
     doTestDateTimeF( "2100-02-29T00:00:00-00:00" ); // invalid: no leap year
     doTestDateTimeF( "1900-02-29T00:00:00-00:00" ); // invalid: no leap year
+    doTestDateTimeF( "00:00:00" ); // invalid: no date
+    doTestDateTimeF( "T00:00:00" ); // invalid: no date
     SAL_INFO("sax.cppunit","\nSAX CONVERTER TEST END");
 }
 
+static void doTestTime(util::DateTime const & rdt, char const*const pis,
+        char const*const i_pos = 0)
+{
+    char const*const pos((i_pos) ? i_pos : pis);
+    OUString is(OUString::createFromAscii(pis));
+    util::DateTime odt;
+    SAL_INFO("sax.cppunit","about to convert '" << is << "'");
+    bool bSuccess( Converter::parseTimeOrDateTime(odt, 0, is) );
+    SAL_INFO("sax.cppunit","Y:" << odt.Year << " M:" << odt.Month << " D:" << odt.Day << "  H:" << odt.Hours << " M:" << odt.Minutes << " S:" << odt.Seconds << " nS:" << odt.NanoSeconds << " UTC: " << (bool)odt.IsUTC);
+    CPPUNIT_ASSERT(bSuccess);
+    CPPUNIT_ASSERT(eqDateTime(rdt, odt));
+    OUStringBuffer buf;
+    Converter::convertTimeOrDateTime(buf, odt, 0);
+    SAL_INFO("sax.cppunit","" << buf.toString());
+    CPPUNIT_ASSERT_EQUAL(OUString::createFromAscii(pos),
+                         buf.makeStringAndClear());
+}
+
+static void doTestTimeF(char const*const pis)
+{
+    util::DateTime odt;
+    bool bSuccess = Converter::parseTimeOrDateTime(odt, 0,
+            OUString::createFromAscii(pis));
+    SAL_INFO("sax.cppunit","Y:" << odt.Year << " M:" << odt.Month << " D:" << odt.Day << "  H:" << odt.Hours << "H M:" << odt.Minutes << " S:" << odt.Seconds << " nS:" << odt.NanoSeconds);
+    CPPUNIT_ASSERT(!bSuccess);
+}
+
+void ConverterTest::testTime() // time or dateTime + horrible backcompat mess
+{
+    doTestTime( util::DateTime(0, 0, 0, 0, 1, 1, 1, false),
+            "0001-01-01T00:00:00" );
+    doTestTime( util::DateTime(0, 0, 0, 0, 1, 1, 1, false),
+            "0001-01-01T00:00:00" );
+    doTestTime( util::DateTime(0, 0, 0, 0, 1, 1, 1, true),
+            "0001-01-01T00:00:00Z" );
+    doTestTime( util::DateTime(0, 0, 0, 0, 1, 1, -1, false),
+            "-0001-01-01T00:00:00");
+    doTestTime( util::DateTime(0, 0, 0, 0, 1, 1, -1, true),
+            "-0001-01-01T01:00:00+01:00", "-0001-01-01T00:00:00Z");
+    doTestTime( util::DateTime(0, 0, 0, 0, 1, 1, -324, false),
+            "-0324-01-01T00:00:00" );
+    doTestTime( util::DateTime(0, 0, 0, 0, 1, 1, 1, true),
+            "0001-01-01T00:00:00-00:00", "0001-01-01T00:00:00Z" );
+    doTestTime( util::DateTime(0, 0, 0, 0, 1, 1, 1, true),
+            "0001-01-01T00:00:00+00:00", "0001-01-01T00:00:00Z" );
+    doTestTime( util::DateTime(0, 0, 0, 12, 2, 1, 1, true),
+            "0001-01-02T00:00:00-12:00", "0001-01-02T12:00:00Z" );
+    doTestTime( util::DateTime(0, 0, 0, 12, 1, 1, 1, true),
+            "0001-01-02T00:00:00+12:00", "0001-01-01T12:00:00Z"  );
+    doTestTime( util::DateTime(990000000, 59, 59, 23, 31, 12, 9999, false),
+            "9999-12-31T23:59:59.99",  "9999-12-31T23:59:59.990000000" );
+    doTestTime( util::DateTime(990000000, 59, 59, 23, 31, 12, 9999, true),
+            "9999-12-31T23:59:59.99Z", "9999-12-31T23:59:59.990000000Z" );
+    doTestTime( util::DateTime(999999999, 59, 59, 23, 31, 12, 9999, false),
+            "9999-12-31T23:59:59.9999999999999999999999999999999999999",
+            "9999-12-31T23:59:59.999999999" );
+    doTestTime( util::DateTime(999999999, 59, 59, 23, 31, 12, 9999, true),
+            "9999-12-31T23:59:59.9999999999999999999999999999999999999Z",
+            "9999-12-31T23:59:59.999999999Z" );
+    doTestTime( util::DateTime(0, 0, 0, 0, 29, 2, 2000, true), // leap year
+            "2000-02-29T00:00:00-00:00", "2000-02-29T00:00:00Z" );
+    doTestTime( util::DateTime(0, 0, 0, 0, 29, 2, 1600, true), // leap year
+            "1600-02-29T00:00:00-00:00", "1600-02-29T00:00:00Z" );
+    doTestTime( util::DateTime(0, 0, 0, 24, 1, 1, 333, false)
+                /*(0, 0, 0, 0, 2, 1, 333)*/,
+            "0333-01-01T24:00:00"/*, "0333-01-02T00:00:00"*/ );
+    // While W3C XMLSchema specifies a minimum of 4 year digits we are lenient
+    // in what we accept.
+    doTestTime( util::DateTime(0, 0, 0, 0, 1, 1, 1, false),
+            "1-01-01T00:00:00", "0001-01-01T00:00:00" );
+
+    doTestTime( util::DateTime(0, 0, 0, 0, 0, 0, 0, false), "00:00:00" );
+    doTestTime( util::DateTime(0, 0, 0, 24, 0, 0, 0, false), "24:00:00" );
+    doTestTime( util::DateTime(0, 0, 59, 0, 0, 0, 0, false), "00:59:00" );
+    doTestTime( util::DateTime(0, 1, 2, 4, 0, 0, 0, true), "04:02:01Z" );
+    doTestTime( util::DateTime(0, 1, 2, 4, 0, 0, 0, true),
+            "05:02:01+01:00", "04:02:01Z" );
+    doTestTime( util::DateTime(0, 11, 12, 9, 0, 0, 0, true),
+            "05:12:11-04:00", "09:12:11Z" );
+    doTestTime( util::DateTime(990000000, 59, 59, 23, 0, 0, 0, false),
+            "23:59:59.99",  "23:59:59.990000000" );
+    doTestTime( util::DateTime(990000000, 59, 59, 23, 0, 0, 0, true),
+            "23:59:59.99Z",  "23:59:59.990000000Z" );
+    // backwards compatible: recognize invalid 0000-00-00 date (LO 3.5)
+    doTestTime( util::DateTime(0, 1, 0, 0, 0, 0, 0, false),
+            "0000-00-00T00:00:01", "00:00:01" );
+    // backwards compatible: recognize invalid 0-00-00 date (OOo)
+    doTestTime( util::DateTime(0, 0, 1, 0, 0, 0, 0, false),
+            "0-00-00T00:01:00", "00:01:00" );
+
+    doTestTimeF( "+0001-01-01T00:00:00" ); // invalid: ^+
+    doTestTimeF( "0001-1-01T00:00:00" ); // invalid: < 2 M
+    doTestTimeF( "0001-01-1T00:00:00" ); // invalid: < 2 D
+    doTestTimeF( "0001-01-01T0:00:00" ); // invalid: < 2 H
+    doTestTimeF( "0001-01-01T00:0:00" ); // invalid: < 2 M
+    doTestTimeF( "0001-01-01T00:00:0" ); // invalid: < 2 S
+    doTestTimeF( "0001-01-01T00:00:00." ); // invalid: .$
+    doTestTimeF( "0001-01-01T00:00:00+1:00" ); // invalid: < 2 TZ H
+    doTestTimeF( "0001-01-01T00:00:00+00:1" ); // invalid: < 2 TZ M
+    doTestTimeF( "0001-13-01T00:00:00" ); // invalid: M > 12
+    doTestTimeF( "0001-01-32T00:00:00" ); // invalid: D > 31
+    doTestTimeF( "0001-01-01T25:00:00" ); // invalid: H > 24
+    doTestTimeF( "0001-01-01T00:60:00" ); // invalid: M > 59
+    doTestTimeF( "0001-01-01T00:00:60" ); // invalid: S > 59
+    doTestTimeF( "0001-01-01T24:01:00" ); // invalid: H=24, but M != 0
+    doTestTimeF( "0001-01-01T24:00:01" ); // invalid: H=24, but S != 0
+    doTestTimeF( "0001-01-01T24:00:00.1" ); // invalid: H=24, but H != 0
+    doTestTimeF( "0001-01-02T00:00:00+15:00" ); // invalid: TZ > +14:00
+    doTestTimeF( "0001-01-02T00:00:00+14:01" ); // invalid: TZ > +14:00
+    doTestTimeF( "0001-01-02T00:00:00-15:00" ); // invalid: TZ < -14:00
+    doTestTimeF( "0001-01-02T00:00:00-14:01" ); // invalid: TZ < -14:00
+    doTestTimeF( "2100-02-29T00:00:00-00:00" ); // invalid: no leap year
+    doTestTimeF( "1900-02-29T00:00:00-00:00" ); // invalid: no leap year
+    doTestTimeF( "T00:00:00" ); // invalid: T
+    doTestTimeF( "0:00:00" ); // invalid: < 2 H
+    doTestTimeF( "00:0:00" ); // invalid: < 2 M
+    doTestTimeF( "00:00:0" ); // invalid: < 2 S
+    doTestTimeF( "00:00:00." ); // invalid: .$
+    doTestTimeF( "00:00:00+1:00" ); // invalid: < 2 TZ H
+    doTestTimeF( "00:00:00+00:1" ); // invalid: < 2 TZ M
+    doTestTimeF( "25:00:00" ); // invalid: H > 24
+    doTestTimeF( "00:60:00" ); // invalid: M > 59
+    doTestTimeF( "00:00:60" ); // invalid: S > 59
+    doTestTimeF( "24:01:00" ); // invalid: H=24, but M != 0
+    doTestTimeF( "24:00:01" ); // invalid: H=24, but S != 0
+    doTestTimeF( "24:00:00.1" ); // invalid: H=24, but H != 0
+    doTestTimeF( "00:00:00+15:00" ); // invalid: TZ > +14:00
+    doTestTimeF( "00:00:00+14:01" ); // invalid: TZ > +14:00
+    doTestTimeF( "00:00:00-15:00" ); // invalid: TZ < -14:00
+    doTestTimeF( "00:00:00-14:01" ); // invalid: TZ < -14:00
+}
+
 void doTestDouble(char const*const pis, double const rd,
         sal_Int16 const nSourceUnit, sal_Int16 const nTargetUnit)
 {
diff --git a/sax/source/tools/converter.cxx b/sax/source/tools/converter.cxx
index c77e02a..b5c9934 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 */
diff --git a/xmloff/inc/txtflde.hxx b/xmloff/inc/txtflde.hxx
index 6d5b387..6728690 100644
--- a/xmloff/inc/txtflde.hxx
+++ b/xmloff/inc/txtflde.hxx
@@ -366,6 +366,12 @@ protected:
         sal_Bool bIsDate,           /// export as date (rather than date/time)?
         sal_uInt16 nPrefix = XML_NAMESPACE_TEXT);   /// attribute name prefix
 
+    /// export time or dateTime
+    void ProcessTimeOrDateTime(
+        enum ::xmloff::token::XMLTokenEnum eXMLName,    /// attribute token
+        const ::com::sun::star::util::DateTime& rTime,  /// date/time value
+        sal_uInt16 nPrefix = XML_NAMESPACE_TEXT);   /// attribute name prefix
+
     /// export all attributes for bibliography data fields
     void ProcessBibliographyData(
         const ::com::sun::star::uno::Reference <
diff --git a/xmloff/source/text/txtflde.cxx b/xmloff/source/text/txtflde.cxx
index e52160f..0d43008 100644
--- a/xmloff/source/text/txtflde.cxx
+++ b/xmloff/source/text/txtflde.cxx
@@ -1261,17 +1261,17 @@ void XMLTextFieldExport::ExportFieldHelper(
         if (xPropSetInfo->hasPropertyByName(sPropertyDateTimeValue))
         {
             // no value -> current time
-            ProcessDateTime(XML_TIME_VALUE,
+            ProcessTimeOrDateTime(XML_TIME_VALUE,
                             GetDateTimeProperty(sPropertyDateTimeValue,
                                                 rPropSet),
-                            sal_False );
+                            XML_NAMESPACE_TEXT);
         }
         if (xPropSetInfo->hasPropertyByName(sPropertyDateTime))
         {
             // no value -> current time
-            ProcessDateTime(XML_TIME_VALUE,
+            ProcessTimeOrDateTime(XML_TIME_VALUE,
                             GetDateTimeProperty(sPropertyDateTime,rPropSet),
-                            sal_False );
+                            XML_NAMESPACE_TEXT);
         }
         if (xPropSetInfo->hasPropertyByName(sPropertyIsFixed))
         {
@@ -2674,6 +2674,20 @@ void XMLTextFieldExport::ProcessDateTime(enum XMLTokenEnum eName,
     }
 }
 
+/// export a time or dateTime
+void XMLTextFieldExport::ProcessTimeOrDateTime(enum XMLTokenEnum eName,
+                                         const util::DateTime& rTime,
+                                         sal_uInt16 nPrefix)
+{
+    OUStringBuffer aBuffer;
+
+    // date/time value
+    ::sax::Converter::convertTimeOrDateTime(aBuffer, rTime, 0);
+
+    // output attribute
+    ProcessString(eName, aBuffer.makeStringAndClear(), sal_True, nPrefix);
+}
+
 
 SvXMLEnumMapEntry const aBibliographyDataTypeMap[] =
 {
diff --git a/xmloff/source/text/txtfldi.cxx b/xmloff/source/text/txtfldi.cxx
index 90553d6..bea669e 100644
--- a/xmloff/source/text/txtfldi.cxx
+++ b/xmloff/source/text/txtfldi.cxx
@@ -1095,6 +1095,7 @@ void XMLTimeFieldImportContext::ProcessAttribute(
     {
         case XML_TOK_TEXTFIELD_TIME_VALUE:
         {
+            // FIXME double appears unused?
             double fTmp;
             if (GetImport().GetMM100UnitConverter().
                 convertDateTime(fTmp, sAttrValue))
@@ -1103,7 +1104,8 @@ void XMLTimeFieldImportContext::ProcessAttribute(
                 bTimeOK = sal_True;
             }
 
-            if (::sax::Converter::parseDateTime(aDateTimeValue, 0, sAttrValue))
+            if (::sax::Converter::parseTimeOrDateTime(aDateTimeValue, 0,
+                        sAttrValue))
             {
                 bTimeOK = sal_True;
             }
commit 1235e694c21f6e3e000e24a176123c386ea91df1
Author: Michael Stahl <mstahl at redhat.com>
Date:   Tue Dec 10 12:35:32 2013 +0100

    fdo#70278: editeng: fix Time fields in Impress
    
    Apparenty an uninitialized SvxTimeField is created instead of the
    SvxExtTimeField that is needed to preserve the value and format.
    
    (regression from ee5fc5d25fe102c30daf7d181b8181d40b85a4f3)
    
    Change-Id: I36b16af0c143e8b5451a1925806756492dc2334e

diff --git a/editeng/source/items/flditem.cxx b/editeng/source/items/flditem.cxx
index 972d8f5..bf8f649 100644
--- a/editeng/source/items/flditem.cxx
+++ b/editeng/source/items/flditem.cxx
@@ -78,7 +78,7 @@ SvxFieldData* SvxFieldData::Create(const uno::Reference<text::XTextContent>& xTe
                         return pData;
                     }
 
-                    if (nFieldType != text::textfield::Type::TIME && nFieldType != text::textfield::Type::DATE)
+                    if (nFieldType != text::textfield::Type::TIME)
                     {
                         util::DateTime aDateTime = xPropSet->getPropertyValue(UNO_TC_PROP_DATE_TIME).get<util::DateTime>();
                         Time aTime(aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds, aDateTime.NanoSeconds);
commit be3a6f7c4d89748bb09d5d389c7ca7bd0a09e5da
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Dec 9 23:23:08 2013 +0100

    svl: remove SfxDateTimeItem, which is actually unused
    
    ... since 2f44516d6c3fce6ebe372214ce4bfa11875bd3d1
    
    Change-Id: I25905a69464a43e12fcbb4770c8b0e171ab3271b

diff --git a/include/svl/dateitem.hxx b/include/svl/dateitem.hxx
deleted file mode 100644
index 1a3a7c2..0000000
--- a/include/svl/dateitem.hxx
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-#ifndef INCLUDED_SVL_DATEITEM_HXX
-#define INCLUDED_SVL_DATEITEM_HXX
-
-#include <tools/rtti.hxx>
-#include <tools/datetime.hxx>
-
-#include <svl/poolitem.hxx>
-
-class SvStream;
-
-DBG_NAMEEX(SfxDateTimeItem)
-
-// class SfxDateTimeItem -------------------------------------------------
-
-class SfxDateTimeItem : public SfxPoolItem
-{
-private:
-    DateTime                aDateTime;
-
-public:
-                            TYPEINFO();
-
-                            SfxDateTimeItem( sal_uInt16 nWhich,
-                                             const DateTime& rDT );
-                            SfxDateTimeItem( const SfxDateTimeItem& rCpy );
-
-                            ~SfxDateTimeItem() {
-                                DBG_DTOR(SfxDateTimeItem, 0); }
-
-    virtual int             operator==( const SfxPoolItem& ) const;
-    using SfxPoolItem::Compare;
-    virtual int             Compare( const SfxPoolItem &rWith ) const;
-    virtual SfxPoolItem*    Create( SvStream&, sal_uInt16 nItemVersion ) const;
-    virtual SvStream&       Store( SvStream&, sal_uInt16 nItemVersion ) const;
-    virtual SfxPoolItem*    Clone( SfxItemPool* pPool = 0 ) const;
-
-    virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
-                                    SfxMapUnit eCoreMetric,
-                                    SfxMapUnit ePresMetric,
-                                    OUString &rText,
-                                    const IntlWrapper * pIntlWrapper = 0 )
-        const;
-
-    const DateTime&         GetDateTime() const { return aDateTime; }
-    void                    SetDateTime( const DateTime& rDT ) {
-                                DBG_ASSERT( GetRefCount() == 0,
-                                            "SetDateTime() with pooled item" );
-                                aDateTime = rDT; }
-
-    virtual bool PutValue  ( const com::sun::star::uno::Any& rVal,
-                             sal_uInt8 nMemberId = 0 );
-    virtual bool QueryValue( com::sun::star::uno::Any& rVal,
-                             sal_uInt8 nMemberId = 0 ) const;
-};
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/dlg/dlgassim.hxx b/sd/source/ui/dlg/dlgassim.hxx
index f9918e7..a62d476 100644
--- a/sd/source/ui/dlg/dlgassim.hxx
+++ b/sd/source/ui/dlg/dlgassim.hxx
@@ -17,7 +17,6 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include <svl/dateitem.hxx>
 #include "drawdoc.hxx"
 #include <svx/svdotext.hxx>
 #include <svtools/treelistbox.hxx>
diff --git a/sfx2/inc/pch/precompiled_sfx.hxx b/sfx2/inc/pch/precompiled_sfx.hxx
index 8a145d6..e11f7a5 100644
--- a/sfx2/inc/pch/precompiled_sfx.hxx
+++ b/sfx2/inc/pch/precompiled_sfx.hxx
@@ -647,7 +647,6 @@
 #include <svl/aeitem.hxx>
 #include <svl/ctloptions.hxx>
 #include <svl/ctypeitm.hxx>
-#include <svl/dateitem.hxx>
 #include <svl/documentlockfile.hxx>
 #include <svl/eitem.hxx>
 #include <svl/flagitem.hxx>
diff --git a/sfx2/source/appl/appdata.cxx b/sfx2/source/appl/appdata.cxx
index ccc9eb1..49b4825 100644
--- a/sfx2/source/appl/appdata.cxx
+++ b/sfx2/source/appl/appdata.cxx
@@ -24,7 +24,6 @@
 
 #include <vcl/menu.hxx>
 #include <vcl/msgbox.hxx>
-#include <svl/dateitem.hxx>
 #include <vcl/wrkwin.hxx>
 #include <comphelper/processfactory.hxx>
 
diff --git a/svl/Library_svl.mk b/svl/Library_svl.mk
index d6d83b5..3732561 100644
--- a/svl/Library_svl.mk
+++ b/svl/Library_svl.mk
@@ -69,7 +69,6 @@ $(eval $(call gb_Library_add_exception_objects,svl,\
     svl/source/items/cntwall \
     svl/source/items/ctypeitm \
     svl/source/items/custritm \
-    svl/source/items/dateitem \
     svl/source/items/flagitem \
     svl/source/items/globalnameitem \
     svl/source/items/grabbagitem \
diff --git a/svl/source/items/dateitem.cxx b/svl/source/items/dateitem.cxx
deleted file mode 100644
index a734b35..0000000
--- a/svl/source/items/dateitem.cxx
+++ /dev/null
@@ -1,191 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include <svl/dateitem.hxx>
-
-#include <unotools/intlwrapper.hxx>
-#include <comphelper/processfactory.hxx>
-
-#include <tools/stream.hxx>
-#include <tools/debug.hxx>
-#include <tools/datetime.hxx>
-#include <com/sun/star/uno/Any.hxx>
-#include <com/sun/star/util/DateTime.hpp>
-#include <com/sun/star/lang/Locale.hpp>
-
-
-// STATIC DATA -----------------------------------------------------------
-
-DBG_NAME(SfxDateTimeItem)
-
-
-// -----------------------------------------------------------------------
-
-TYPEINIT1(SfxDateTimeItem, SfxPoolItem);
-
-// -----------------------------------------------------------------------
-
-SfxDateTimeItem::SfxDateTimeItem( sal_uInt16 which, const DateTime& rDT ) :
-    SfxPoolItem( which ),
-    aDateTime( rDT )
-
-{
-    DBG_CTOR(SfxDateTimeItem, 0);
-}
-
-// -----------------------------------------------------------------------
-
-SfxDateTimeItem::SfxDateTimeItem( const SfxDateTimeItem& rItem ) :
-    SfxPoolItem( rItem ),
-    aDateTime( rItem.aDateTime )
-{
-    DBG_CTOR(SfxDateTimeItem, 0);
-}
-
-// -----------------------------------------------------------------------
-
-int SfxDateTimeItem::operator==( const SfxPoolItem& rItem ) const
-{
-    DBG_CHKTHIS(SfxDateTimeItem, 0);
-    DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" );
-    return ( ( (SfxDateTimeItem&)rItem ).aDateTime == aDateTime );
-}
-
-// -----------------------------------------------------------------------
-
-int SfxDateTimeItem::Compare( const SfxPoolItem& rItem ) const
-{
-    DBG_CHKTHIS(SfxDateTimeItem, 0);
-    DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" );
-
-    // da X.Compare( Y ) am String einem Compare( Y, X ) entspricht,
-    // vergleichen wir hier Y mit X
-    if ( ( (const SfxDateTimeItem&)rItem ).aDateTime < aDateTime )
-        return -1;
-    else if ( ( (const SfxDateTimeItem&)rItem ).aDateTime == aDateTime )
-        return 0;
-    else
-        return 1;
-}
-
-// -----------------------------------------------------------------------
-
-SfxPoolItem* SfxDateTimeItem::Create( SvStream& rStream, sal_uInt16 ) const
-{
-    DBG_CHKTHIS(SfxDateTimeItem, 0);
-    sal_uInt32 nDate = 0;
-    sal_Int64 nTime = 0;
-    rStream >> nDate;
-    rStream.ReadInt64(nTime);
-    DateTime aDT(nDate, nTime);
-    return new SfxDateTimeItem( Which(), aDT );
-}
-
-// -----------------------------------------------------------------------
-
-SvStream& SfxDateTimeItem::Store( SvStream& rStream, sal_uInt16 ) const
-{
-    DBG_CHKTHIS(SfxDateTimeItem, 0);
-    rStream << aDateTime.GetDate();
-    rStream.WriteInt64(aDateTime.GetTime());
-    return rStream;
-}
-
-// -----------------------------------------------------------------------
-
-SfxPoolItem* SfxDateTimeItem::Clone( SfxItemPool* ) const
-{
-    DBG_CHKTHIS(SfxDateTimeItem, 0);
-    return new SfxDateTimeItem( *this );
-}
-
-// -----------------------------------------------------------------------
-
-SfxItemPresentation SfxDateTimeItem::GetPresentation
-(
-    SfxItemPresentation     /*ePresentation*/,
-    SfxMapUnit              /*eCoreMetric*/,
-    SfxMapUnit              /*ePresentationMetric*/,
-    OUString&               rText,
-    const IntlWrapper *   pIntlWrapper
-)   const
-{
-    DBG_CHKTHIS(SfxDateTimeItem, 0);
-    if (aDateTime.IsValidDate())
-        if (pIntlWrapper)
-        {
-            rText = pIntlWrapper->getLocaleData()->getDate(aDateTime) +
-                    ", " +
-                    pIntlWrapper->getLocaleData()->getTime(aDateTime);
-        }
-        else
-        {
-            DBG_WARNING("SfxDateTimeItem::GetPresentation():"
-                         " Using default en_US IntlWrapper");
-            const IntlWrapper aIntlWrapper( LanguageTag( LANGUAGE_ENGLISH_US) );
-            rText = aIntlWrapper.getLocaleData()->getDate(aDateTime) +
-                    ", " +
-                    aIntlWrapper.getLocaleData()->getTime(aDateTime);
-        }
-    else
-        rText = OUString();
-    return SFX_ITEM_PRESENTATION_NAMELESS;
-}
-
-// virtual
-bool SfxDateTimeItem::PutValue( const com::sun::star::uno::Any& rVal,
-                                   sal_uInt8 nMemberId )
-{
-    nMemberId &= ~CONVERT_TWIPS;
-    com::sun::star::util::DateTime aValue;
-    if ( rVal >>= aValue )
-    {
-        aDateTime = DateTime( Date( aValue.Day,
-                                      aValue.Month,
-                                      aValue.Year ),
-                              Time( aValue.Hours,
-                                      aValue.Minutes,
-                                      aValue.Seconds,
-                                      aValue.NanoSeconds ) );
-        return true;
-    }
-
-    OSL_FAIL( "SfxDateTimeItem::PutValue - Wrong type!" );
-    return false;
-}
-
-// virtual
-bool SfxDateTimeItem::QueryValue( com::sun::star::uno::Any& rVal,
-                                   sal_uInt8 nMemberId ) const
-{
-    nMemberId &= ~CONVERT_TWIPS;
-    com::sun::star::util::DateTime aValue( aDateTime.GetNanoSec(),
-                                           aDateTime.GetSec(),
-                                              aDateTime.GetMin(),
-                                           aDateTime.GetHour(),
-                                           aDateTime.GetDay(),
-                                           aDateTime.GetMonth(),
-                                           aDateTime.GetYear(),
-                                           false);
-    rVal <<= aValue;
-    return true;
-}
-
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 7b9c61c7f20a679c5316a288c2ec2ffbf04b4200
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Dec 9 23:07:44 2013 +0100

    editeng: fix more 32-bit Time breakage
    
    SfxDateTimeItem and SvxExtTimeField need to use 64-bit integer to store
    Time as well.  These classes also have binary serialization
    Load()/Save() methods but they are unlikely to be used in a persistent
    way, just for the clipboard.
    
    The problem is easy to reproduce in Impress: Insert->Field->Time(fixed)
    
    (regression from 9830fd36dbdb72c79703b0c61efc027fba793c5a)
    
    Change-Id: I5946c5b94dd5a509805b6dc40461bbd910caffc4

diff --git a/editeng/source/items/flditem.cxx b/editeng/source/items/flditem.cxx
index 8eb506a..972d8f5 100644
--- a/editeng/source/items/flditem.cxx
+++ b/editeng/source/items/flditem.cxx
@@ -756,8 +756,8 @@ SV_IMPL_PERSIST1( SvxExtTimeField, SvxFieldData );
 //----------------------------------------------------------------------------
 
 SvxExtTimeField::SvxExtTimeField()
+    : m_nFixTime( Time(Time::SYSTEM).GetTime() )
 {
-    nFixTime = Time( Time::SYSTEM ).GetTime();
     eType = SVXTIMETYPE_VAR;
     eFormat = SVXTIMEFORMAT_STANDARD;
 }
@@ -765,8 +765,8 @@ SvxExtTimeField::SvxExtTimeField()
 //----------------------------------------------------------------------------
 
 SvxExtTimeField::SvxExtTimeField( const Time& rTime, SvxTimeType eT, SvxTimeFormat eF )
+    : m_nFixTime( rTime.GetTime() )
 {
-    nFixTime = rTime.GetTime();
     eType = eT;
     eFormat = eF;
 }
@@ -786,7 +786,7 @@ int SvxExtTimeField::operator==( const SvxFieldData& rOther ) const
         return sal_False;
 
     const SvxExtTimeField& rOtherFld = (const SvxExtTimeField&) rOther;
-    return ( ( nFixTime == rOtherFld.nFixTime ) &&
+    return ((m_nFixTime == rOtherFld.m_nFixTime) &&
                 ( eType == rOtherFld.eType ) &&
                 ( eFormat == rOtherFld.eFormat ) );
 }
@@ -797,7 +797,7 @@ void SvxExtTimeField::Load( SvPersistStream & rStm )
 {
     sal_uInt16 nType, nFormat;
 
-    rStm >> nFixTime;
+    rStm.ReadInt64(m_nFixTime);
     rStm >> nType;
     rStm >> nFormat;
 
@@ -809,7 +809,7 @@ void SvxExtTimeField::Load( SvPersistStream & rStm )
 
 void SvxExtTimeField::Save( SvPersistStream & rStm )
 {
-    rStm << nFixTime;
+    rStm.WriteInt64(m_nFixTime);
     rStm << (sal_uInt16) eType;
     rStm << (sal_uInt16) eFormat;
 }
@@ -820,7 +820,7 @@ OUString SvxExtTimeField::GetFormatted( SvNumberFormatter& rFormatter, LanguageT
 {
     Time aTime( Time::EMPTY );
     if ( eType == SVXTIMETYPE_FIX )
-        aTime.SetTime( nFixTime );
+        aTime.SetTime(m_nFixTime);
     else
         aTime = Time( Time::SYSTEM ); // current time
     return GetFormatted( aTime, eFormat, rFormatter, eLang );
diff --git a/editeng/source/uno/unofield.cxx b/editeng/source/uno/unofield.cxx
index 6ed8733..6c818e2 100644
--- a/editeng/source/uno/unofield.cxx
+++ b/editeng/source/uno/unofield.cxx
@@ -196,7 +196,7 @@ inline Date setDate( util::DateTime& rDate )
     return Date( rDate.Day, rDate.Month, rDate.Year );
 }
 
-static util::DateTime getTime( long nTime )
+static util::DateTime getTime(sal_Int64 const nTime)
 {
     util::DateTime aTime;
     memset( &aTime, 0, sizeof( util::DateTime ) );
diff --git a/include/editeng/flditem.hxx b/include/editeng/flditem.hxx
index 5b27563..34ff0b9 100644
--- a/include/editeng/flditem.hxx
+++ b/include/editeng/flditem.hxx
@@ -257,7 +257,7 @@ enum SvxTimeFormat {    SVXTIMEFORMAT_APPDEFAULT = 0,   // Set as in App
 class EDITENG_DLLPUBLIC SvxExtTimeField : public SvxFieldData
 {
 private:
-    sal_uInt32              nFixTime;
+    sal_Int64               m_nFixTime;
     SvxTimeType             eType;
     SvxTimeFormat           eFormat;
 
@@ -268,8 +268,8 @@ public:
                                 SvxTimeType eType = SVXTIMETYPE_VAR,
                                 SvxTimeFormat eFormat = SVXTIMEFORMAT_STANDARD );
 
-    sal_uInt32              GetFixTime() const { return nFixTime; }
-    void                    SetFixTime( const Time& rTime ) { nFixTime = rTime.GetTime(); }
+    sal_Int64               GetFixTime() const { return m_nFixTime; }
+    void SetFixTime( const Time& rTime ) { m_nFixTime = rTime.GetTime(); }
 
     SvxTimeType             GetType() const { return eType; }
     void                    SetType( SvxTimeType eTp ) { eType = eTp; }
diff --git a/svl/source/items/dateitem.cxx b/svl/source/items/dateitem.cxx
index ca4c750..a734b35 100644
--- a/svl/source/items/dateitem.cxx
+++ b/svl/source/items/dateitem.cxx
@@ -90,9 +90,9 @@ SfxPoolItem* SfxDateTimeItem::Create( SvStream& rStream, sal_uInt16 ) const
 {
     DBG_CHKTHIS(SfxDateTimeItem, 0);
     sal_uInt32 nDate = 0;
-    sal_Int32 nTime = 0;
+    sal_Int64 nTime = 0;
     rStream >> nDate;
-    rStream >> nTime;
+    rStream.ReadInt64(nTime);
     DateTime aDT(nDate, nTime);
     return new SfxDateTimeItem( Which(), aDT );
 }
@@ -103,7 +103,7 @@ SvStream& SfxDateTimeItem::Store( SvStream& rStream, sal_uInt16 ) const
 {
     DBG_CHKTHIS(SfxDateTimeItem, 0);
     rStream << aDateTime.GetDate();
-    rStream << static_cast<sal_Int32>(aDateTime.GetTime());
+    rStream.WriteInt64(aDateTime.GetTime());
     return rStream;
 }
 
commit 17dab5bf8efb3fd676e6854474b199b681d0dc28
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Dec 9 21:45:16 2013 +0100

    fdo#70198: sw: don't truncate Time values on 32bit platforms
    
    SwDoc::SetFixFields() uses sal_uLong to store Time.GetTime() which needs
    64 bits.
    
    Also fix same problem on Time fields in HTML import.
    
    (regression from 9830fd36dbdb72c79703b0c61efc027fba793c5a)
    
    Change-Id: I5d0388cbc364e1f9dfb60ff9e83c7d2f101c69d8

diff --git a/sw/source/core/doc/docfld.cxx b/sw/source/core/doc/docfld.cxx
index 372f3df..c630109 100644
--- a/sw/source/core/doc/docfld.cxx
+++ b/sw/source/core/doc/docfld.cxx
@@ -1986,7 +1986,8 @@ void SwDoc::SetFixFields( bool bOnlyTimeDate, const DateTime* pNewDateTime )
 {
     sal_Bool bIsModified = IsModified();
 
-    sal_uLong nDate, nTime;
+    sal_Int32 nDate;
+    sal_Int64 nTime;
     if( pNewDateTime )
     {
         nDate = pNewDateTime->GetDate();
diff --git a/sw/source/filter/html/htmlfld.cxx b/sw/source/filter/html/htmlfld.cxx
index 00c7a43..57015ee 100644
--- a/sw/source/filter/html/htmlfld.cxx
+++ b/sw/source/filter/html/htmlfld.cxx
@@ -327,7 +327,8 @@ void SwHTMLParser::NewField()
     case RES_TIMEFLD:
         {
             sal_uLong nNumFmt = 0;
-            sal_uLong nTime = Time( Time::SYSTEM ).GetTime(), nDate = Date( Date::SYSTEM ).GetDate();
+            sal_Int64 nTime = Time( Time::SYSTEM ).GetTime();
+            sal_Int32 nDate = Date( Date::SYSTEM ).GetDate();
             sal_uInt16 nSub = 0;
             sal_Bool bValidFmt = sal_False;
             HTMLNumFmtTblEntry * pFmtTbl;
@@ -337,7 +338,7 @@ void SwHTMLParser::NewField()
                 nSub = DATEFLD;
                 pFmtTbl = aHTMLDateFldFmtTable;
                 if( !aValue.isEmpty() )
-                    nDate = (sal_uLong)aValue.toInt32();
+                    nDate = aValue.toInt32();
             }
             else
             {
commit 34140139840a181157690038fe845f5b33866b10
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Dec 9 23:01:11 2013 +0100

    sd: PPT export: fix assert on 0-length text portions
    
    Not sure if such are legit, but this should fix the crash.
    
    Change-Id: Idf8a3a67ddae464533d431f1a6a2ebea6d6c2213

diff --git a/sd/source/filter/eppt/pptx-text.cxx b/sd/source/filter/eppt/pptx-text.cxx
index 1efc779..0a45ad0 100644
--- a/sd/source/filter/eppt/pptx-text.cxx
+++ b/sd/source/filter/eppt/pptx-text.cxx
@@ -129,7 +129,9 @@ PortionObj::PortionObj( ::com::sun::star::uno::Reference< ::com::sun::star::text
         {
             // For i39516 - a closing parenthesis that ends an RTL string is displayed backwards by PPT
             // Solution: add a Unicode Right-to-Left Mark, following the method described in i18024
-            if ( bLast && aString[ aString.getLength() - 1 ] == ')' && rFontCollection.GetScriptDirection( aString ) == com::sun::star::i18n::ScriptDirection::RIGHT_TO_LEFT )
+            if (bLast && !aString.isEmpty()
+                && aString[aString.getLength() - 1] == ')'
+                && rFontCollection.GetScriptDirection(aString) == com::sun::star::i18n::ScriptDirection::RIGHT_TO_LEFT)
             {
                 mnTextSize++;
                 bRTL_endingParen = sal_True;
commit 6692eeca9a3ba7a9ba461564172275fbb78992e9
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Dec 9 18:27:40 2013 +0100

    svtools: don't dereference invalid iterator
    
    Can be reproduced by opening Data Sources in Writer and closing
    document.
    
    Change-Id: I703ceffee3a1896acd06076d8b77085e8785acd3

diff --git a/svtools/source/contnr/treelist.cxx b/svtools/source/contnr/treelist.cxx
index 4cac34b..3ef468d 100644
--- a/svtools/source/contnr/treelist.cxx
+++ b/svtools/source/contnr/treelist.cxx
@@ -1465,6 +1465,8 @@ sal_Bool SvListView::IsExpanded( SvTreeListEntry* pEntry ) const
     DBG_ASSERT(pEntry,"IsExpanded:No Entry");
     SvDataTable::const_iterator itr = maDataTable.find(pEntry);
     DBG_ASSERT(itr != maDataTable.end(),"Entry not in Table");
+    if (itr == maDataTable.end())
+        return false;
     return itr->second->IsExpanded();
 }
 


More information about the Libreoffice-commits mailing list