[Libreoffice-commits] core.git: oox/source

Lionel Elie Mamane lionel at mamane.lu
Fri Aug 9 01:48:03 PDT 2013


 oox/source/docprop/docprophandler.cxx |   56 ++++++++++++++++++++++++++--------
 1 file changed, 43 insertions(+), 13 deletions(-)

New commits:
commit 689e4849b797a47030dd8e2a84ae7c97bfc38d3a
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date:   Fri Jul 5 17:12:51 2013 +0200

    Fix timezone && fractional second handling of GetDateTimeFromW3CDTF
    
    1) The timezone correction was inverted.
    
       Imagine we are parsing "2004-03-02T14:18:20+02".
    
       Before correction, aOslDTime contains "2004-03-02 14:18:20".
       According to the comment, we want to convert that to UTC
       time, so we have to *subtract* 2 hours, not *add* two hours.
    
       From http://www.w3.org/TR/NOTE-datetime:
    
       A time zone offset of "+hh:mm" indicates (...) a local time zone
       which is "hh" hours and "mm" minutes *ahead* of UTC.
    
       So if it is 14:18:20 in the timezone two hours ahead of UTC,
       it is two hours *earlier* in UTC, namely 12:18:20,
       and we need to *subtract* two hours, not *add* two hours.
    
    2) Handling of fractions of a second was buggy:
    
       It reads only one digit after the dot. This could be a valid
       implementation decision to handle only deciseconds. However:
    
       1) It then multiplies that by 10^9 (10e8 == 10*10^8, not 10^8!),
          and sticks that in the NanoSeconds field... That is 10 times too big:
          0.3s == 3*10^8 ns
    
       2) If there were additional digits, it then looks for the timezone
          offset specificator (beginning with '+' or '-') at these additional
          digits; it does not skip them: nOptTime is set to 0+3+2, i.e. to 5.
    
    Change-Id: I4738dc069e37f29c8bbd9e689689a933027af840
    Reviewed-on: https://gerrit.libreoffice.org/4743
    Reviewed-by: Tor Lillqvist <tml at iki.fi>
    Tested-by: Tor Lillqvist <tml at iki.fi>

diff --git a/oox/source/docprop/docprophandler.cxx b/oox/source/docprop/docprophandler.cxx
index b604e9b..e9a35b2 100644
--- a/oox/source/docprop/docprophandler.cxx
+++ b/oox/source/docprop/docprophandler.cxx
@@ -95,46 +95,76 @@ void OOXMLDocPropHandler::AddCustomProperty( const uno::Any& aAny )
 util::DateTime OOXMLDocPropHandler::GetDateTimeFromW3CDTF( const OUString& aChars )
 {
     oslDateTime aOslDTime = { 0, 0, 0, 0, 0, 0, 0, 0 };
-    sal_Int32 nLen = aChars.getLength();
+    const sal_Int32 nLen = aChars.getLength();
     if ( nLen >= 4 )
     {
         aOslDTime.Year = (sal_Int16)aChars.copy( 0, 4 ).toInt32();
 
-        if ( nLen >= 7 && aChars.getStr()[4] == (sal_Unicode)'-' )
+        if ( nLen >= 7 && aChars[4] == (sal_Unicode)'-' )
         {
             aOslDTime.Month = (sal_uInt16)aChars.copy( 5, 2 ).toInt32();
 
-            if ( nLen >= 10 && aChars.getStr()[7] == (sal_Unicode)'-' )
+            if ( nLen >= 10 && aChars[7] == (sal_Unicode)'-' )
             {
                 aOslDTime.Day = (sal_uInt16)aChars.copy( 8, 2 ).toInt32();
 
-                if ( nLen >= 16 && aChars.getStr()[10] == (sal_Unicode)'T' && aChars.getStr()[13] == (sal_Unicode)':' )
+                if ( nLen >= 16 && aChars[10] == (sal_Unicode)'T' && aChars[13] == (sal_Unicode)':' )
                 {
                     aOslDTime.Hours = (sal_uInt16)aChars.copy( 11, 2 ).toInt32();
                     aOslDTime.Minutes = (sal_uInt16)aChars.copy( 14, 2 ).toInt32();
 
                     sal_Int32 nOptTime = 0;
-                    if ( nLen >= 19 && aChars.getStr()[16] == (sal_Unicode)':' )
+                    if ( nLen >= 19 && aChars[16] == (sal_Unicode)':' )
                     {
                         aOslDTime.Seconds = (sal_uInt16)aChars.copy( 17, 2 ).toInt32();
                         nOptTime += 3;
-                        if ( nLen >= 21 && aChars.getStr()[19] == (sal_Unicode)'.' )
+                        if ( nLen >= 20 && aChars[19] == (sal_Unicode)'.' )
                         {
-                            aOslDTime.NanoSeconds = (sal_uInt32)(aChars.copy( 20, 1 ).toInt32() * 10e8);
-                            nOptTime += 2;
+                            nOptTime += 1;
+                            sal_Int32 digitPos = 20;
+                            while (nLen > digitPos && digitPos < 29)
+                            {
+                                sal_Unicode c = aChars[digitPos];
+                                if ( c < '0' || c > '9')
+                                    break;
+                                aOslDTime.NanoSeconds *= 10;
+                                aOslDTime.NanoSeconds += c - '0';
+                                ++digitPos;
+                            }
+                            if ( digitPos < 29 )
+                            {
+                                // read less digits than 9
+                                // add correct exponent of 10
+                                nOptTime += digitPos - 20;
+                                for(; digitPos<29; ++digitPos)
+                                {
+                                    aOslDTime.NanoSeconds *= 10;
+                                }
+                            }
+                            else
+                            {
+                                //skip digits with more precision than we can handle
+                                while(nLen > digitPos)
+                                {
+                                    sal_Unicode c = aChars[digitPos];
+                                    if ( c < '0' || c > '9')
+                                        break;
+                                    ++digitPos;
+                                }
+                                nOptTime += digitPos - 20;
+                            }
                         }
                     }
 
                     sal_Int32 nModif = 0;
                     if ( nLen >= 16 + nOptTime + 6 )
                     {
-                        if ( ( aChars.getStr()[16 + nOptTime] == (sal_Unicode)'+' || aChars.getStr()[16 + nOptTime] == (sal_Unicode)'-' )
-                          && aChars.getStr()[16 + nOptTime + 3] == (sal_Unicode)':' )
-
+                        if ( ( aChars[16 + nOptTime] == (sal_Unicode)'+' || aChars[16 + nOptTime] == (sal_Unicode)'-' )
+                          && aChars[16 + nOptTime + 3] == (sal_Unicode)':' )
                         {
                             nModif = aChars.copy( 16 + nOptTime + 1, 2 ).toInt32() * 3600;
                             nModif += aChars.copy( 16 + nOptTime + 4, 2 ).toInt32() * 60;
-                            if ( aChars.getStr()[16 + nOptTime] == (sal_Unicode)'-' )
+                            if ( aChars[16 + nOptTime] == (sal_Unicode)'-' )
                                 nModif *= -1;
                         }
                     }
@@ -145,7 +175,7 @@ util::DateTime OOXMLDocPropHandler::GetDateTimeFromW3CDTF( const OUString& aChar
                         TimeValue aTmp;
                         if ( osl_getTimeValueFromDateTime( &aOslDTime, &aTmp ) )
                         {
-                            aTmp.Seconds += nModif;
+                            aTmp.Seconds -= nModif;
                             osl_getDateTimeFromTimeValue( &aTmp, &aOslDTime );
                         }
                     }


More information about the Libreoffice-commits mailing list