[Libreoffice-commits] core.git: include/svl svl/qa svl/source svx/source

Eike Rathke (via logerrit) logerrit at kemper.freedesktop.org
Tue Sep 21 19:01:27 UTC 2021


 include/svl/zforlist.hxx        |    3 ++-
 svl/qa/unit/svl.cxx             |    3 ++-
 svl/source/numbers/zforlist.cxx |   30 +++++++++++++++++++++++++++---
 svl/source/numbers/zforscan.cxx |   32 ++++++++++++++++++++++++++++++--
 svx/source/items/numfmtsh.cxx   |    3 ++-
 5 files changed, 63 insertions(+), 8 deletions(-)

New commits:
commit 508f5b7767210318f1a23efc6db928c87a5eca6f
Author:     Eike Rathke <erack at redhat.com>
AuthorDate: Tue Sep 21 19:26:51 2021 +0200
Commit:     Eike Rathke <erack at redhat.com>
CommitDate: Tue Sep 21 21:00:45 2021 +0200

    Add ISO 8601 date+time with milliseconds format
    
    NF_DATETIME_ISO_YYYYMMDDTHHMMSS000
    YYYY-MM-DD"T"HH:MM:SS,000
    
    using either ',' or '.' separator,
    '.' if Time100SecSep is '.'
    ',' else
    
    A prerequisite for tdf#88359 to not lose data when importing such,
    especially without "Detect special numbers" on.
    
    Change-Id: I02ab682636e6ddbcc4537183a3625ea61662f016
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122400
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Jenkins

diff --git a/include/svl/zforlist.hxx b/include/svl/zforlist.hxx
index a9b9fa37748a..59b748e4381e 100644
--- a/include/svl/zforlist.hxx
+++ b/include/svl/zforlist.hxx
@@ -247,11 +247,12 @@ enum NfIndexTableOffset
 
     NF_DATETIME_ISO_YYYYMMDD_HHMMSS,        // 1997-10-08 01:23:45          ISO (with blank instead of T)
     NF_DATETIME_ISO_YYYYMMDDTHHMMSS,        // 1997-10-08T01:23:45          ISO
+    NF_DATETIME_ISO_YYYYMMDDTHHMMSS000,     // 1997-10-08T01:23:45,678      ISO with milliseconds
 
     // XXX When adding values here, follow the comment above about
     // svx/source/items/numfmtsh.cxx
 
-    NF_INDEX_TABLE_ENTRIES                  // == 60, reserved to not be used in i18npool locale data.
+    NF_INDEX_TABLE_ENTRIES                  // == 61, reserved to not be used in i18npool locale data.
 
     // XXX Adding values above may increment the reserved area that can't be
     // used by i18npool's locale data FormatCode definitions, see the
diff --git a/svl/qa/unit/svl.cxx b/svl/qa/unit/svl.cxx
index 8baffff86cab..155fc9cbf1da 100644
--- a/svl/qa/unit/svl.cxx
+++ b/svl/qa/unit/svl.cxx
@@ -233,6 +233,7 @@ void Test::testNumberFormat()
     const char* pDateTimeExt2[] = {
         "YYYY-MM-DD HH:MM:SS",
         "YYYY-MM-DD\"T\"HH:MM:SS",
+        "YYYY-MM-DD\"T\"HH:MM:SS.000",
         nullptr
     };
 
@@ -264,7 +265,7 @@ void Test::testNumberFormat()
         { NF_TEXT, NF_TEXT, 1, pText },
         { NF_DATETIME_SYS_DDMMYYYY_HHMM, NF_DATETIME_SYS_DDMMYYYY_HHMM, 1, pDateTimeExt1 },
         { NF_FRACTION_3D, NF_FRACTION_100, 7, pFractionExt },
-        { NF_DATETIME_ISO_YYYYMMDD_HHMMSS, NF_DATETIME_ISO_YYYYMMDDTHHMMSS, 2, pDateTimeExt2 }
+        { NF_DATETIME_ISO_YYYYMMDD_HHMMSS, NF_DATETIME_ISO_YYYYMMDDTHHMMSS000, 3, pDateTimeExt2 }
     };
 
     SvNumberFormatter aFormatter(m_xContext, eLang);
diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx
index e623a0239743..dca678d81abd 100644
--- a/svl/source/numbers/zforlist.cxx
+++ b/svl/source/numbers/zforlist.cxx
@@ -169,7 +169,8 @@ sal_uInt32 const indexTable[NF_INDEX_TABLE_ENTRIES] = {
     ZF_STANDARD_FRACTION + 7, // NF_FRACTION_10
     ZF_STANDARD_FRACTION + 8, // NF_FRACTION_100
     ZF_STANDARD_DATETIME + 2, // NF_DATETIME_ISO_YYYYMMDD_HHMMSS
-    ZF_STANDARD_DATETIME + 3  // NF_DATETIME_ISO_YYYYMMDDTHHMMSS
+    ZF_STANDARD_DATETIME + 3, // NF_DATETIME_ISO_YYYYMMDDTHHMMSS
+    ZF_STANDARD_DATETIME + 5  // NF_DATETIME_ISO_YYYYMMDDTHHMMSS000
 };
 
 /**
@@ -1273,11 +1274,18 @@ bool SvNumberFormatter::IsNumberFormat(const OUString& sString,
             // Preserve ISO 8601 input.
             if (pStringScanner->HasIso8601Tsep())
             {
-                F_Index = GetFormatIndex( NF_DATETIME_ISO_YYYYMMDDTHHMMSS, ActLnge );
+                if (pStringScanner->GetDecPos())
+                    F_Index = GetFormatIndex( NF_DATETIME_ISO_YYYYMMDDTHHMMSS000, ActLnge );
+                else
+                    F_Index = GetFormatIndex( NF_DATETIME_ISO_YYYYMMDDTHHMMSS, ActLnge );
             }
             else if (pStringScanner->CanForceToIso8601( DateOrder::Invalid))
             {
-                F_Index = GetFormatIndex( NF_DATETIME_ISO_YYYYMMDD_HHMMSS, ActLnge );
+                /* TODO: add a millisecond format with space instead of 'T'? */
+                if (pStringScanner->GetDecPos())
+                    F_Index = GetFormatIndex( NF_DATETIME_ISO_YYYYMMDDTHHMMSS000, ActLnge );
+                else
+                    F_Index = GetFormatIndex( NF_DATETIME_ISO_YYYYMMDD_HHMMSS, ActLnge );
             }
             else
             {
@@ -1639,6 +1647,8 @@ sal_uInt32 SvNumberFormatter::GetEditFormat( double fNumber, sal_uInt32 nFIndex,
     case SvNumFormatType::DATETIME :
         if (nFIndex == GetFormatIndex( NF_DATETIME_ISO_YYYYMMDDTHHMMSS, eLang))
             nKey = GetFormatIndex( NF_DATETIME_ISO_YYYYMMDDTHHMMSS, eLang );
+        else if (nFIndex == GetFormatIndex( NF_DATETIME_ISO_YYYYMMDDTHHMMSS000, eLang))
+            nKey = GetFormatIndex( NF_DATETIME_ISO_YYYYMMDDTHHMMSS000, eLang );
         else if (nFIndex == GetFormatIndex( NF_DATETIME_ISO_YYYYMMDD_HHMMSS, eLang) || (pFormat && pFormat->IsIso8601( 0 )))
             nKey = GetFormatIndex( NF_DATETIME_ISO_YYYYMMDD_HHMMSS, eLang );
         else
@@ -2893,6 +2903,20 @@ void SvNumberFormatter::ImpGenerateFormats( sal_uInt32 CLOffset, bool bNoAdditio
     assert(pFormat);
     pFormat->SetComment("ISO 8601");    // not to be localized
 
+    // YYYY-MM-DD"T"HH:MM:SS,000   ISO with milliseconds and ',' or '.' decimal separator
+    aSingleFormatCode.Code =
+        rKeyword[NF_KEY_YYYY] + "-" +
+        rKeyword[NF_KEY_MM] + "-" +
+        rKeyword[NF_KEY_DD] + "\"T\"" +
+        rKeyword[NF_KEY_HH] + ":" +
+        rKeyword[NF_KEY_MMI] + ":" +
+        rKeyword[NF_KEY_SS] + (GetLocaleData()->getTime100SecSep() == "." ? "." : ",") +
+        "000";
+    pFormat = ImpInsertFormat( aSingleFormatCode,
+                     CLOffset + ZF_STANDARD_DATETIME+5 /* NF_DATETIME_ISO_YYYYMMDDTHHMMSS000 */ );
+    assert(pFormat);
+    pFormat->SetComment("ISO 8601");    // not to be localized
+
 
     // Scientific number
     aFormatSeq = xNFC->getAllFormatCode( i18n::KNumberFormatUsage::SCIENTIFIC_NUMBER, aLocale );
diff --git a/svl/source/numbers/zforscan.cxx b/svl/source/numbers/zforscan.cxx
index f6cdfdb5b339..a5f25637678a 100644
--- a/svl/source/numbers/zforscan.cxx
+++ b/svl/source/numbers/zforscan.cxx
@@ -1432,9 +1432,37 @@ sal_Int32 ImpSvNumberformatScan::ScanType()
                 eNewType = SvNumFormatType::TEXT;
                 break;
             default:
-                if (pLoc->getTime100SecSep() == sStrArray[i])
+                // Separator for SS,0
+                if ((eScannedType & SvNumFormatType::TIME)
+                        && 0 < i && (nTypeArray[i-1] == NF_KEY_S || nTypeArray[i-1] == NF_KEY_SS))
                 {
-                    bDecSep = true;                  // for SS,0
+                    // For ISO 8601 only YYYY-MM-DD"T"HH:MM:SS,0  accept both
+                    // ',' and '.' regardless of locale's separator, and only
+                    // those.
+                    // XXX NOTE: this catches only known separators of
+                    // NF_SYMBOLTYPE_DEL as all NF_SYMBOLTYPE_STRING are
+                    // skipped during the loop. Meant to error out if the
+                    // Time100SecSep or decimal separator differ and were used.
+                    if ((eScannedType & SvNumFormatType::DATE)
+                            && 11 <= i && i < nStringsCnt-1
+                            && (nTypeArray[i-6] == NF_SYMBOLTYPE_STRING
+                                && (sStrArray[i-6] == "\"T\"" || sStrArray[i-6] == "\\T"
+                                    || sStrArray[i-6] == "T"))
+                            && (nTypeArray[i-11] == NF_KEY_YYYY)
+                            && (nTypeArray[i-9] == NF_KEY_M || nTypeArray[i-9] == NF_KEY_MM)
+                            && (nTypeArray[i-7] == NF_KEY_D || nTypeArray[i-7] == NF_KEY_DD)
+                            && (nTypeArray[i-5] == NF_KEY_H || nTypeArray[i-5] == NF_KEY_HH)
+                            && (nTypeArray[i-3] == NF_KEY_MI || nTypeArray[i-3] == NF_KEY_MMI)
+                            && (nTypeArray[i+1] == NF_SYMBOLTYPE_DEL && sStrArray[i+1][0] == '0'))
+
+                    {
+                        if (sStrArray[i].getLength() == 1 && (sStrArray[i][0] == ',' || sStrArray[i][0] == '.'))
+                            bDecSep = true;
+                        else
+                            return nPos;            // Error
+                    }
+                    else if (pLoc->getTime100SecSep() == sStrArray[i])
+                        bDecSep = true;
                 }
                 eNewType = SvNumFormatType::UNDEFINED;
                 break;
diff --git a/svx/source/items/numfmtsh.cxx b/svx/source/items/numfmtsh.cxx
index 6ea63332191c..30f76ab3afb9 100644
--- a/svx/source/items/numfmtsh.cxx
+++ b/svx/source/items/numfmtsh.cxx
@@ -660,7 +660,7 @@ short SvxNumberFormatShell::FillEListWithDateTime_Impl(std::vector<OUString>& rL
 
     // Always add the internally generated ISO formats.
     nSelPos = FillEListWithFormats_Impl(rList, nSelPos, NF_DATETIME_ISO_YYYYMMDD_HHMMSS,
-                                        NF_DATETIME_ISO_YYYYMMDDTHHMMSS, false);
+                                        NF_DATETIME_ISO_YYYYMMDDTHHMMSS000, false);
 
     return nSelPos;
 }
@@ -720,6 +720,7 @@ bool SvxNumberFormatShell::IsEssentialFormat_Impl(SvNumFormatType eType, sal_uIn
         case NF_DATETIME_SYS_DDMMYYYY_HHMMSS:
         case NF_DATETIME_ISO_YYYYMMDD_HHMMSS:
         case NF_DATETIME_ISO_YYYYMMDDTHHMMSS:
+        case NF_DATETIME_ISO_YYYYMMDDTHHMMSS000:
             return true;
         default:
             break;


More information about the Libreoffice-commits mailing list