Related: tdf#125035 Introduce LongDateOrder and handle YDM in DateFormatter

This fixes also

    unotools/source/i18n/localedatawrapper.cxx:1473: LocaleDataWrapper::scanDateOrder: no magic applicable
    lv-LV requested
    lv-LV loaded

that is the only locale with a YDM long date order.

Change-Id: I776b8706bf5bd3ec11cc46d38fd3613c8df7519f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118482
Tested-by: Jenkins
Reviewed-by: Eike Rathke <erack@redhat.com>
(cherry picked from commit 5e3bfdeb5ea4878a2546a7e1e16d0f3b6482024e)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118520
diff --git a/include/unotools/localedatawrapper.hxx b/include/unotools/localedatawrapper.hxx
index 70108f8..0a0832b 100644
--- a/include/unotools/localedatawrapper.hxx
+++ b/include/unotools/localedatawrapper.hxx
@@ -52,6 +52,14 @@ enum class DateOrder {
    YMD,
};

enum class LongDateOrder {
    Invalid = -1,
    MDY = 0,
    DMY,
    YMD,
    YDM
};

enum class MeasurementSystem {
    Metric,
    US
@@ -80,7 +88,7 @@ class UNOTOOLS_DLLPUBLIC LocaleDataWrapper
    OUString                aCurrSymbol;
    OUString                aCurrBankSymbol;
    DateOrder               nDateOrder;
    DateOrder               nLongDateOrder;
    LongDateOrder           nLongDateOrder;
    sal_uInt16              nCurrPositiveFormat;
    sal_uInt16              nCurrNegativeFormat;
    sal_uInt16              nCurrDigits;
@@ -100,7 +108,7 @@ class UNOTOOLS_DLLPUBLIC LocaleDataWrapper
                            sal_Int32& nBlank, sal_Int32& nSym ) const;

    void                loadDateOrders();
    DateOrder           scanDateOrderImpl( const OUString& rCode ) const;
    LongDateOrder       scanDateOrderImpl( const OUString& rCode ) const;

    void                ImplAddFormatNum( rtl::OUStringBuffer& rBuf,
                            sal_Int64 nNumber, sal_uInt16 nDecimals,
@@ -299,7 +307,7 @@ public:

    // simple date and time formatting
    DateOrder          getDateOrder() const;
    DateOrder          getLongDateOrder() const;
    LongDateOrder      getLongDateOrder() const;
    /// only numerical values of Gregorian calendar
    OUString       getDate( const Date& rDate ) const;
    OUString       getTime( const tools::Time& rTime, bool bSec = true,
diff --git a/svl/source/numbers/zforfind.cxx b/svl/source/numbers/zforfind.cxx
index 4f5fd03..8b01deb 100644
--- a/svl/source/numbers/zforfind.cxx
+++ b/svl/source/numbers/zforfind.cxx
@@ -2728,7 +2728,7 @@ bool ImpSvNumberInputScan::ScanMidString( const OUString& rString, sal_uInt16 nS
        switch (eScannedType)
        {
        case SvNumFormatType::DATE:
            if (nMonthPos == 1 && pLoc->getLongDateOrder() == DateOrder::MDY)
            if (nMonthPos == 1 && pLoc->getLongDateOrder() == LongDateOrder::MDY)
            {
                // #68232# recognize long date separators like ", " in "September 5, 1999"
                if (SkipString( pLoc->getLongDateDaySep(), rString, nPos ))
diff --git a/unotools/source/i18n/localedatawrapper.cxx b/unotools/source/i18n/localedatawrapper.cxx
index 9765cec..fb70c06 100644
--- a/unotools/source/i18n/localedatawrapper.cxx
+++ b/unotools/source/i18n/localedatawrapper.cxx
@@ -691,12 +691,12 @@ DateOrder LocaleDataWrapper::getDateOrder() const
    return nDateOrder;
}

DateOrder LocaleDataWrapper::getLongDateOrder() const
LongDateOrder LocaleDataWrapper::getLongDateOrder() const
{
    return nLongDateOrder;
}

DateOrder LocaleDataWrapper::scanDateOrderImpl( const OUString& rCode ) const
LongDateOrder LocaleDataWrapper::scanDateOrderImpl( const OUString& rCode ) const
{
    // Only some european versions were translated, the ones with different
    // keyword combinations are:
@@ -760,18 +760,40 @@ DateOrder LocaleDataWrapper::scanDateOrderImpl( const OUString& rCode ) const
    }
    // compare with <= because each position may equal rCode.getLength()
    if ( nDay <= nMonth && nMonth <= nYear )
        return DateOrder::DMY;     // also if every position equals rCode.getLength()
        return LongDateOrder::DMY;     // also if every position equals rCode.getLength()
    else if ( nMonth <= nDay && nDay <= nYear )
        return DateOrder::MDY;
        return LongDateOrder::MDY;
    else if ( nYear <= nMonth && nMonth <= nDay )
        return DateOrder::YMD;
        return LongDateOrder::YMD;
    else if ( nYear <= nDay && nDay <= nMonth )
        return LongDateOrder::YDM;
    else
    {
        if (areChecksEnabled())
        {
            outputCheckMessage( appendLocaleInfo( "LocaleDataWrapper::scanDateOrder: no magic applicable" ) );
        }
        return DateOrder::DMY;
        return LongDateOrder::DMY;
    }
}

static DateOrder getDateOrderFromLongDateOrder( LongDateOrder eLong )
{
    switch (eLong)
    {
        case LongDateOrder::YMD:
            return DateOrder::YMD;
        break;
        case LongDateOrder::DMY:
            return DateOrder::DMY;
        break;
        case LongDateOrder::MDY:
            return DateOrder::MDY;
        break;
        case LongDateOrder::YDM:
        default:
            assert(!"unhandled LongDateOrder to DateOrder");
            return DateOrder::DMY;
    }
}

@@ -786,7 +808,8 @@ void LocaleDataWrapper::loadDateOrders()
        {
            outputCheckMessage( appendLocaleInfo( "LocaleDataWrapper::getDateOrdersImpl: no date formats" ) );
        }
        nDateOrder = nLongDateOrder = DateOrder::DMY;
        nDateOrder = DateOrder::DMY;
        nLongDateOrder = LongDateOrder::DMY;
        return;
    }
    // find the edit (21), a default (medium preferred),
@@ -844,16 +867,19 @@ void LocaleDataWrapper::loadDateOrders()
        }
        nEdit = nDef;
    }
    DateOrder nDF = scanDateOrderImpl( pFormatArr[nEdit].Code );
    LongDateOrder nDO = scanDateOrderImpl( pFormatArr[nEdit].Code );
    if ( pFormatArr[nEdit].Type == KNumberFormatType::LONG )
    {   // normally this is not the case
        nLongDateOrder = nDateOrder = nDF;
        nLongDateOrder = nDO;
        nDateOrder = getDateOrderFromLongDateOrder(nDO);
    }
    else
    {
        nDateOrder = nDF;
        // YDM should not occur in a short/medium date (i.e. no locale has
        // that) and is nowhere handled.
        nDateOrder = getDateOrderFromLongDateOrder(nDO);
        if ( nLong == -1 )
            nLongDateOrder = nDF;
            nLongDateOrder = nDO;
        else
            nLongDateOrder = scanDateOrderImpl( pFormatArr[nLong].Code );
    }
diff --git a/vcl/source/control/field2.cxx b/vcl/source/control/field2.cxx
index 0339052..64cc39d 100644
--- a/vcl/source/control/field2.cxx
+++ b/vcl/source/control/field2.cxx
@@ -1170,13 +1170,15 @@ void PatternBox::ReformatAll()
    SetUpdateMode( true );
}

static ExtDateFieldFormat ImplGetExtFormat( DateOrder eOld )
static ExtDateFieldFormat ImplGetExtFormat( LongDateOrder eOld )
{
    switch( eOld )
    {
        case DateOrder::DMY:   return ExtDateFieldFormat::ShortDDMMYY;
        case DateOrder::MDY:   return ExtDateFieldFormat::ShortMMDDYY;
        default:               return ExtDateFieldFormat::ShortYYMMDD;
        case LongDateOrder::YDM:
        case LongDateOrder::DMY:    return ExtDateFieldFormat::ShortDDMMYY;
        case LongDateOrder::MDY:    return ExtDateFieldFormat::ShortMMDDYY;
        case LongDateOrder::YMD:
        default:                    return ExtDateFieldFormat::ShortYYMMDD;
    }
}

@@ -1316,20 +1318,25 @@ bool DateFormatter::TextToDate(const OUString& rStr, Date& rDate, ExtDateFieldFo
    if ( eDateOrder == ExtDateFieldFormat::SystemLong )
    {
        OUString aCalendarName;
        DateOrder eFormat = rLocaleDataWrapper.getLongDateOrder();
        LongDateOrder eFormat = rLocaleDataWrapper.getLongDateOrder();
        switch( eFormat )
        {
            case DateOrder::MDY:
            case LongDateOrder::MDY:
                nMonth = ImplCutMonthFromString( aStr, aCalendarName, rLocaleDataWrapper, rCalendarWrapper );
                nDay = ImplCutNumberFromString( aStr );
                nYear  = ImplCutNumberFromString( aStr );
                break;
            case DateOrder::DMY:
            case LongDateOrder::DMY:
                nDay = ImplCutNumberFromString( aStr );
                nMonth = ImplCutMonthFromString( aStr, aCalendarName, rLocaleDataWrapper, rCalendarWrapper );
                nYear  = ImplCutNumberFromString( aStr );
                break;
            case DateOrder::YMD:
            case LongDateOrder::YDM:
                nYear  = ImplCutNumberFromString( aStr );
                nDay = ImplCutNumberFromString( aStr );
                nMonth = ImplCutMonthFromString( aStr, aCalendarName, rLocaleDataWrapper, rCalendarWrapper );
                break;
            case LongDateOrder::YMD:
            default:
                nYear = ImplCutNumberFromString( aStr );
                nMonth = ImplCutMonthFromString( aStr, aCalendarName, rLocaleDataWrapper, rCalendarWrapper );