Jump to content

Please test this in your language / region


Recommended Posts

Windows 7 Ultimate 64 Bit

Keyboard and Language set to English

Format and Location set to Germany

Works like a charm :)

I had the Jan 01 to Dec 31 problem when testing (changing region/language settings).

You have to restart the script and then it works...

 

p.s. I got an empty nth element on a couple of the first tests but it looks like they were also the jan01 to dec 31 ones..

one was 3 years so not only affected by short ranges...

Edited by l3ill
Link to comment
Share on other sites

  • Replies 54
  • Created
  • Last Reply

Top Posters In This Topic

I think I know what is wrong with the MMDDYYYY order. It's a silly oversight on my part. The other issues don't make much sense to me right now. After I clean up the code, perhaps I'll discover something. One thing I would like to know is whether these empty array elements are an extra day added to the selected range, or the last day within the selected range.

This clearly needs more work.

Edited by czardas
Link to comment
Share on other sites

I was able to reproduce the  empty nth element with the jan01 dec31 "bug".

It only happens here when I set to US Format and Location settings.

 

edit: location settings are irrelevant. US format clearly causes problems though...

Restarting the script fixes the Jan Dec bug but not the nth element bug.

Edited by l3ill
Link to comment
Share on other sites

1 hour ago, czardas said:

You must have somehow only clicked the year or something.

It could be the many pages of code, or it could be my ability to navigate a date control, and you went with the latter?  It is getting late over there :)

 

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

  • Moderators

Odd. Now when I put in a date beginning today and ending two weeks from now on the 17th, it gives me everything from the End Date to the end of the year. I deleted the old code, was it doing that before?

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

I will have to look at it again tomorrow because I am too tired at the moment. It might be something to do with ArrayWorkshop.au3. However it could be something really simple like a bad regexp somewhere. Here's the earlier (more broken) version of the particular function which I updated in the first post. I have yet to try different language settings on my PC. The descriptions you have given me should be very helpful (much appreciated). It's very easy to miss a problem that hides itself away like this.

Func GetDateArray($sStartDate, $sStopDate, $sDelim = Default, $sFormat = Default, $iDayName = -1)
    Local $iID = _WinAPI_GetUserDefaultLCID(), _
    $aDateSplit = StringRegExp(_WinAPI_GetLocaleInfo($iID, $LOCALE_SSHORTDATE), '\w+', 3)

    If IsArray($aDateSplit) And UBound($aDateSplit) = 3 Then
        For $i = 0 To 2 ; determine the locale ymd order
            If StringInStr($aDateSplit[$i], 'y') Then
                $aDateSplit[$i] = 1 ; year
            ElseIf StringInStr($aDateSplit[$i], 'm') Then
                $aDateSplit[$i] = 2 ; month
            ElseIf StringInStr($aDateSplit[$i], 'd') Then
                $aDateSplit[$i] = 3 ; day
            EndIf
        Next

    Else ; let's try an alternative method [both methods work on Win7 in the UK]
        Local $sLongDate = _WinAPI_GetDateFormat(0, 0, $DATE_LONGDATE)
        $aDateSplit = StringRegExp($sLongDate, '(*UCP)\w+', 3)
        If Not IsArray($aDateSplit) And UBound($aDateSplit) <> 3 Then Return SetError(1) ; undetermined error?

        For $i = 0 To 2 ; determine the locale ymd order
            If $aDateSplit[$i] = @YEAR Then ; hopefully this method will work for all international regions
                $aDateSplit[$i] = 1 ; year
            ElseIf $aDateSplit[$i] = _DateToMonth(@MON, $DMW_LOCALE_LONGNAME) Then
                $aDateSplit[$i] = 2 ; month
            Else
                $aDateSplit[$i] = 3 ; day
            EndIf
        Next
    EndIf

    ; check the array contains numbers 1 to 3
    Local $sTest = $aDateSplit[0] & $aDateSplit[1] & $aDateSplit[2]
    If Not (StringInStr($sTest, '1') And StringInStr($sTest, '2') And StringInStr($sTest, '3')) Then Return SetError(2) ; undetermined error?

    If $sDelim = Default Then $sDelim = StringRegExp($sStartDate, '\D+', 3)[0]

    Local $iCount = 1, $sYMD = ''
    Do
        For $i = 0 To 2
            If $aDateSplit[$i] = $iCount Then
                $sYMD &= '$'& ($i*2 +1) & ($iCount <> 3 ? $sDelim : '')
                $iCount += 1
                ExitLoop
            EndIf
        Next
    Until $iCount = 4

    $sStartDate = StringRegExpReplace($sStartDate, '(\d+)(\D)(\d+)(\D)(\d+)', $sYMD)
    $sStopDate  = StringRegExpReplace($sStopDate,  '(\d+)(\D)(\d+)(\D)(\d+)', $sYMD)

    Local $vReverse = False
    If $sStartDate > $sStopDate Then
        $vReverse = $sStartDate
        $sStartDate = $sStopDate
        $sStopDate = $vReverse
    EndIf

    ; internal format = yyyy/mm/dd
    Local $iStartYear = Number(StringRegExp($sStartDate, '\d+', 3)[0]), $iStopYear = Number(StringRegExp($sStopDate, '\d+', 3)[0])

    Local $aTimeLine[(($iStopYear - $iStartYear +1) *366)]

    $iCount = 0
    For $iYear = $iStartYear To $iStopYear
        For $iMon = 1 To 12
            Switch $iMon
                Case 1, 3, 5, 7, 8, 10, 12
                    For $iDay = 1 To 31 ; this section of code can be shortened
                        $aTimeLine[$iCount] = $iYear & $sDelim & StringFormat('%02i', $iMon) & $sDelim & StringFormat('%02i', $iDay)
                        If $aTimeLine[$iCount] = $sStopDate Then ExitLoop 3
                        $iCount += 1
                    Next

                Case 4, 6, 9, 11
                    For $iDay = 1 To 30
                        $aTimeLine[$iCount] = $iYear & $sDelim & StringFormat('%02i', $iMon) & $sDelim & StringFormat('%02i', $iDay)
                        If $aTimeLine[$iCount] = $sStopDate Then ExitLoop 3
                        $iCount += 1
                    Next

                Case Else
                    For $iDay = 1 To _DateIsLeapYear($iYear) ? 29 : 28
                        $aTimeLine[$iCount] = $iYear & $sDelim & StringFormat('%02i', $iMon) & $sDelim & StringFormat('%02i', $iDay)
                        If $aTimeLine[$iCount] = $sStopDate Then ExitLoop 3
                        $iCount += 1
                    Next
            EndSwitch
        Next
    Next

    ReDim $aTimeLine[$iCount +1] ; get rid of unused elements

    For $i = 0 To UBound($aTimeLine) -1
        If $aTimeLine[$i] = $sStartDate Then
            _DeleteRegion($aTimeLine, 1, 0, $i)
            ExitLoop
        EndIf
    Next

    _Predim($aTimeLine, 2) ; add 2nd dimension

    ; adding a day name column only works for start dates up to christmas day 2999 [millennium bug], is it worth fixing? ==> [FIXED]

    If $iDayName <> -1 Then ; $iDayName set to -1 because _DateDayOfWeek() format values range from 0 to 3
        ReDim $aTimeLine[UBound($aTimeLine)][2]

        Local $aNextDay, $iDayNum

        If $sStartDate <= ('2999' & $sDelim & '12' & $sDelim & '25') Then
            For $i = 0 To 6
                If $i = UBound($aTimeLine) Then ExitLoop
                $aNextDay = StringRegExp($aTimeLine[$i][0], '\d+', 3)
                $iDayNum = _DateToDayOfWeek (Number($aNextDay[0]), Number($aNextDay[1]), Number($aNextDay[2]))
                $aTimeLine[$i][1] = _DateDayOfWeek($iDayNum, $iDayName)
            Next

            For $i = 7 To UBound($aTimeLine) -1
                $aTimeLine[$i][1] = $aTimeLine[Mod($i, 7)][1]
            Next

        Else
            Local $aDayName[7]
            For $i = 25 To 31
                $aNextDay = StringRegExp('2999/12/' & $i, '\d+', 3)
                $iDayNum = _DateToDayOfWeek (Number($aNextDay[0]), Number($aNextDay[1]), Number($aNextDay[2]))
                $aDayName[$i -25] = _DateDayOfWeek($iDayNum, $iDayName)
            Next

            Local $iDateDiff = DateRange('2999/12/25', StringReplace($aTimeLine[0][0], $sDelim, '/'))

            For $i = 0 to 6
                If $i = UBound($aTimeLine) Then ExitLoop
                $aTimeLine[$i][1] = $aDayName[Mod($iDateDiff + $i -1, 7)]
            Next

            For $i = 7 To UBound($aTimeLine) -1
                $aTimeLine[$i][1] = $aTimeLine[Mod($i, 7)][1]
            Next
        EndIf
    EndIf

    If $sFormat = Default Then $sFormat = $sYMD ; [regexp pattern stored in ini or settings]
    For $i = 0 To UBound($aTimeLine) -1
        $aTimeLine[$i][0] = StringRegExpReplace($aTimeLine[$i][0], '(\d+)(\D)(\d+)(\D)(\d+)', $sFormat)
    Next

    If $vReverse Then _ReverseArray($aTimeLine)

    _ArrayDisplay($aTimeLine)
    Return $aTimeLine
EndFunc ;==> GetDateArray

 

Edited by czardas
Link to comment
Share on other sites

do yall even UAT :)    (i learned my lesson from the rubiks cube, save and version everything Czardas does)

no matter what you select the array looks like this 

$array[0][0] = 01JAN $BeginDateSelectionYear

$array[ubound($array) - 1][1] = 01JAN DAY the day after $EndDateSelectionYear, with Col 0 blank.

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

if it ends up being that, I would blame it on date.au3 and want to give it an option to normalize data, no?

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

There do seem to be a few incompatible formats and a degree of inconsistency between working ranges. The function GUICtrlCreateDate() creates day names in any language (and everything else) up to the year 9999. It only gives me the formatted date in my current region when I use GUICtrlRead(), so I have to be able to parse any language format because I don't know the hidden secret - there might not even be one. :'( The function _DateDiff() only works up to the year 3000. I think _DateIsLeapYear() also has inconsistent limitations. [actually not true - I only rewrote it to test it]. I'm sure all these formats/ranges have there individual merit, but it can be tricky to combine them sometimes.

Edited by czardas
Link to comment
Share on other sites

think normalizing the day and month with stringformat cleared up the spray,  where the F is that first day coming from though?

#include <Array.au3>
#include <GUIConstants.au3>
#include <GuiEdit.au3>
#include <Misc.au3>
#include <GuiTab.au3>
#include <Date.au3>
#include <APILocaleConstants.au3>
#include <WinAPILocale.au3>
;#include <ArrayWorkshop.au3> ; required functions are already included in this demo

NewTable()

Func NewTable(); ($hParent, $idListView, $hListView) ; [missing parent window]
    Local $sTitle = "New Table", _
    $iStyle = BitOR($WS_CAPTION, $WS_POPUP, $WS_SYSMENU), _
    $iExStyle = BitOR($WS_EX_MDICHILD, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST), _
    $iWidth = 250, _
    $iHeight = 292

    Local $hChild = GUICreate($sTitle, $iWidth, $iHeight, Default + 100, Default + 100); , $iStyle, $iExStyle, $hParent)

    Local $idTab = GUICtrlCreateTab(2, 2, $iWidth -2, $iHeight -32)

    GUICtrlCreateTabItem("Standard")

    GUICtrlCreateLabel("Table Dimensions", 14, 35, 120, 20)
    GUICtrlSetColor(-1, 0x008000)

    GUICtrlCreateLabel("Number Of Columns", 14, 60, 94, 18)
    Local $hStandardCols = GUICtrlCreateInput("0", 104 +14, 55, 50, 20, BitOR($WS_TABSTOP, $ES_CENTER, $ES_NUMBER))
    GUICtrlSetFont(-1, 10)

    GUICtrlCreateLabel("Number Of Rows", 14, 83, 90, 18)
    Local $hStandardRows = GUICtrlCreateInput("0", 104 +14, 81, 50, 20, BitOR($WS_TABSTOP, $ES_CENTER, $ES_NUMBER))
    GUICtrlSetFont(-1, 10)

    GUICtrlCreateLabel("Table Indices", 14, 114, 120, 20)
    GUICtrlSetColor(-1, 0x008000)

    Local $hIndices = GUICtrlCreateCheckbox(" Enumerate First Column", 14, 137, 160, 20) ; REMEMBER YES, SETTINGS NO

    Local $hPadding = GUICtrlCreateCheckbox(" Include Leading Zeros", 14, 161, 124, 20) ; REMEMBER YES, SETTINGS NO

    GUICtrlCreateTabItem("Advanced")

    GUICtrlCreateLabel("Column 1 = Date Range", 14, 35, 120, 20)
    GUICtrlSetColor(-1, 0x008000)

    GUICtrlCreateLabel("Start Date", 14, 35 +20, 100, 20)
    Local $idDate1 = GUICtrlCreateDate("", 14, 56 +20, 105, 20, $WS_TABSTOP)

    GUICtrlCreateLabel("End Date", $iWidth - 118, 35 +20, 100, 20)
    Local $idDate2 = GUICtrlCreateDate("", $iWidth - 118, 56 +20, 105, 20, BitOR($WS_TABSTOP, $DTS_RIGHTALIGN))

    GUICtrlCreateLabel("Column 2 = Days Of The Week (Optional)", 14, 108, 220, 20)
    GUICtrlSetColor(-1, 0x008000)

    Local $hCheckBox = GUICtrlCreateCheckbox(" Include Days Of The Week ", 14, 128, 190, 20) ; REMEMBER YES, SETTINGS NO

    Local $hRadio1 = GUICtrlCreateRadio(" Use Short Name", 14, 151)
    Local $hRadio2 = GUICtrlCreateRadio(" Use Long Name", $iWidth - 118, 151)
    GUICtrlSetState(-1, $GUI_CHECKED)
    GUICtrlSetState($hRadio1, $GUI_DISABLE) ; check settings later
    GUICtrlSetState($hRadio2, $GUI_DISABLE) ; check settings later

    GUICtrlCreateLabel("Add More Columns", 14, 181, 222, 20)
    GUICtrlSetColor(-1, 0x008000)

    GUICtrlCreateLabel("Total Number Of Columns", 14, 182 +23, 129, 18)
    Local $hColNum = GUICtrlCreateInput("1", 130 +14, 182 +21, 50, 20, BitOR($WS_TABSTOP, $ES_CENTER, $ES_NUMBER)) ; REMEMBER YES, SETTINGS NO
    GUICtrlSetFont(-1, 10)

    GUICtrlCreateTabItem("") ; end tabitem definition

    Local $hCancel = GUICtrlCreateButton("Cancel", $iWidth -143, $iHeight -25, 66, 20)
    Local $hOkay = GUICtrlCreateButton("OK", $iWidth -69, $iHeight -25, 66, 20)
    GUISetState(@SW_SHOW)

    Local $msg2, $bDisable = True, $iMaxFields = 65000, $bStandardError = False, $iRows = 0, $iCols = 0, _
    $sMonitorAdv = GUICtrlRead($idDate1) & GUICtrlRead($idDate2) & GUICtrlRead($hColNum), $sDate1, $sDate2, $sColsAdv, $iDiff, $bErrorAdv = False

    While 1
        $msg2 = GUIGetMsg()
        If $msg2 = $hCancel Or $msg2 = $GUI_EVENT_CLOSE Then ExitLoop

        If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED Then
            If $bDisable Then
                GUICtrlSetState($hRadio1, $GUI_ENABLE)
                GUICtrlSetState($hRadio2, $GUI_ENABLE)
                $bDisable  = False
            EndIf

        ElseIf Not $bDisable Then
            GUICtrlSetState($hRadio1, $GUI_DISABLE)
            GUICtrlSetState($hRadio2, $GUI_DISABLE)
            $bDisable  = True
        EndIf

        $sDate1 = GUICtrlRead($idDate1)
        $sDate2 = GUICtrlRead($idDate2)
        $sColsAdv = GUICtrlRead($hColNum)

        If $sDate1 & $sDate2 & $sColsAdv <> $sMonitorAdv Then

            $iDiff = DateRange(LocaleDateToYMD($sDate1), LocaleDateToYMD($sDate2)) ; _DateDiff() is too limited

            If $iDiff * $sColsAdv > $iMaxFields Then
                If Not $bErrorAdv Then
                    GUICtrlSetBkColor($hColNum, 0xFFA090)
                    $bErrorAdv = True
                EndIf

            ElseIf $bErrorAdv Then
                GUICtrlSetBkColor($hColNum, 0xFFFFFF)
                $bErrorAdv = False
            EndIf

            $sMonitorAdv = $sDate1 & $sDate2 & $sColsAdv
        EndIf

        $iCols = GUICtrlRead($hStandardCols)
        $iRows = GUICtrlRead($hStandardRows)

        If Not $iRows Then GUICtrlSetData($hStandardRows, 0)
        If Not $iCols Then GUICtrlSetData($hStandardCols, 0)

        If ControlGetFocus($hChild) <> "Edit2" And StringRegExp($iRows, '\A0+[1-9]') Then GUICtrlSetData($hStandardRows, StringRegExpReplace($iRows, '(\A0+)([1-9])(\d+)*', '$2$3'))
        If ControlGetFocus($hChild) <> "Edit1" And StringRegExp($iCols, '\A0+[1-9]') Then GUICtrlSetData($hStandardCols, StringRegExpReplace($iCols, '(\A0+)([1-9])(\d+)*', '$2$3'))

        If $iRows > $iMaxFields Or $iCols > $iMaxFields Or GUICtrlRead($hStandardRows) * GUICtrlRead($hStandardCols) > $iMaxFields Then
            If Not $bStandardError Then
                GUICtrlSetBkColor($hStandardRows, 0xFFA090)
                GUICtrlSetBkColor($hStandardCols, 0xFFA090)
                $bStandardError = True
            EndIf

        ElseIf $bStandardError Then
            GUICtrlSetBkColor($hStandardRows, 0xFFFFFF)
            GUICtrlSetBkColor($hStandardCols, 0xFFFFFF)
            $bStandardError = False
        EndIf

        $iCols = GUICtrlRead($hColNum)
        If ControlGetFocus($hChild) <> "Edit3" And StringRegExp($iCols, '\A0+[1-9]') Then GUICtrlSetData($hColNum, StringRegExpReplace($iCols, '(\A0+)([1-9])(\d+)*', '$2$3'))

        $iCols = GUICtrlRead($hColNum)
        If $iCols < 1 Then
            If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED And ControlGetFocus($hChild) <> "Edit3" Then
                GUICtrlSetData($hColNum, 2)
            Else
                GUICtrlSetData($hColNum, 1)
            EndIf
            If ControlGetFocus($hChild) = "Edit3" Then _GUICtrlEdit_SetSel($hColNum, 0, -1)
        EndIf

        If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED Then
            If $iCols < 2 And ControlGetFocus($hChild) <> "Edit3" Then
                If ControlGetFocus($hChild) = "Button3" Then
                    While _IsPressed('01')
                        Sleep(20)
                    WEnd
                EndIf

                If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED Then
                    GUICtrlSetData($hColNum, 2)
                Else
                    GUICtrlSetData($hColNum, 1)
                EndIf
            EndIf
        Else
            If $iCols < 1 Then
                GUICtrlSetData($hColNum, 1)
                If ControlGetFocus($hChild) = "Edit3" Then _GUICtrlEdit_SetSel($hColNum, 0, -1)
            EndIf
        EndIf

        If $msg2 = $hOkay Then
            If $bErrorAdv Then
                MsgBox(262160, "uh-uh!", "Out of Range")
                ContinueLoop
            EndIf

            Local $sDelim = '-' ; read from settings ??? [maybe]
            If _GUICtrlTab_GetCurFocus($idTab) = 1 Then
                Local $iName, $sFormat = Default ; read from settings [ini]
                If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED Then
                    $iName = (BitAND(GUICtrlRead($hRadio1), $GUI_CHECKED) == $GUI_CHECKED) ? 3 : 2
                Else
                    $iName = -1
                EndIf

                ; $sStartDate, $sStopDate, $sDelim = Default, $sFormat = Default, $iDayName = -1)
                GetDateArray(GUICtrlRead($idDate1), GUICtrlRead($idDate2), $sDelim, $sFormat, $iName) ; US [, '$3-$5-$1'])

            EndIf
        EndIf
    WEnd
    GUIDelete($hChild)
EndFunc ;==> NewTable

Func LocaleDateToYMD($sDate, $sDelim = '/')
    Local $iID = _WinAPI_GetUserDefaultLCID(), _
    $aDateSplit = StringRegExp(_WinAPI_GetLocaleInfo($iID, $LOCALE_SSHORTDATE), '\w+', 3), _
    $vTest = True ; [floating variable]

    If IsArray($aDateSplit) And UBound($aDateSplit) = 3 Then
        For $i = 0 To 2 ; determine the locale ymd order
            If StringInStr($aDateSplit[$i], 'y') Then
                $aDateSplit[$i] = 1 ; year
            ElseIf StringInStr($aDateSplit[$i], 'm') Then
                $aDateSplit[$i] = 2 ; month
            ElseIf StringInStr($aDateSplit[$i], 'd') Then
                $aDateSplit[$i] = 3 ; day
            EndIf
        Next

        $vTest = $aDateSplit[0] & $aDateSplit[1] & $aDateSplit[2]
        If StringInStr($vTest, '1') And StringInStr($vTest, '2') And StringInStr($vTest, '3') Then $vTest = False ; success
    EndIf

    If $vTest Then ; failure with the previous method [both methods work on Win7 in the UK]
        Local $sLongDate = _WinAPI_GetDateFormat(0, 0, $DATE_LONGDATE)
        $aDateSplit = StringRegExp($sLongDate, '(*UCP)\w+', 3)
        If Not IsArray($aDateSplit) And UBound($aDateSplit) <> 3 Then Return SetError(1) ; undetermined error?

        For $i = 0 To 2 ; determine the locale ymd order
            If $aDateSplit[$i] = @YEAR Then ; hopefully this method will work for all international regions
                $aDateSplit[$i] = 1 ; year
            ElseIf $aDateSplit[$i] = _DateToMonth(@MON, $DMW_LOCALE_LONGNAME) Then
                $aDateSplit[$i] = 2 ; month
            Else
                $aDateSplit[$i] = 3 ; day
            EndIf
        Next

        $vTest = $aDateSplit[0] & $aDateSplit[1] & $aDateSplit[2]
        If Not (StringInStr($vTest, '1') And StringInStr($vTest, '2') And StringInStr($vTest, '3')) Then Return SetError(2) ; undetermined error?
    EndIf

    Local $iCount = 1, $sYMD = ''
    Do
        For $i = 0 To 2
            If $aDateSplit[$i] = $iCount Then
                $sYMD &= '$'& ($i*2 +1) & ($iCount <> 3 ? $sDelim : '')
                $iCount += 1
                ExitLoop
            EndIf
        Next
    Until $iCount = 4

    Return StringRegExpReplace($sDate, '(\d+)(\D)(\d+)(\D)(\d+)', $sYMD)
EndFunc

Func GetDateArray($sStartDate, $sStopDate, $sDelim = Default, $sFormat = Default, $iDayName = -1)
    Local $iID = _WinAPI_GetUserDefaultLCID(), _
    $aDateSplit = StringRegExp(_WinAPI_GetLocaleInfo($iID, $LOCALE_SSHORTDATE), '\w+', 3)

    If IsArray($aDateSplit) And UBound($aDateSplit) = 3 Then
        For $i = 0 To 2 ; determine the locale ymd order
            If StringInStr($aDateSplit[$i], 'y') Then
                $aDateSplit[$i] = 1 ; year
            ElseIf StringInStr($aDateSplit[$i], 'm') Then
                $aDateSplit[$i] = 2 ; month
            ElseIf StringInStr($aDateSplit[$i], 'd') Then
                $aDateSplit[$i] = 3 ; day
            EndIf
        Next

    Else ; let's try an alternative method [both methods work on Win7 in the UK]
        Local $sLongDate = _WinAPI_GetDateFormat(0, 0, $DATE_LONGDATE)
        $aDateSplit = StringRegExp($sLongDate, '(*UCP)\w+', 3)
        If Not IsArray($aDateSplit) And UBound($aDateSplit) <> 3 Then Return SetError(1) ; undetermined error?

        For $i = 0 To 2 ; determine the locale ymd order
            If $aDateSplit[$i] = @YEAR Then ; hopefully this method will work for all international regions
                $aDateSplit[$i] = 1 ; year
            ElseIf $aDateSplit[$i] = _DateToMonth(@MON, $DMW_LOCALE_LONGNAME) Then
                $aDateSplit[$i] = 2 ; month
            Else
                $aDateSplit[$i] = 3 ; day
            EndIf
        Next
    EndIf

    ; check the array contains numbers 1 to 3
    Local $sTest = $aDateSplit[0] & $aDateSplit[1] & $aDateSplit[2]
    If Not (StringInStr($sTest, '1') And StringInStr($sTest, '2') And StringInStr($sTest, '3')) Then Return SetError(2) ; undetermined error?

    If $sDelim = Default Then $sDelim = StringRegExp($sStartDate, '\D+', 3)[0]

    Local $iCount = 1, $sYMD = ''
    Do
        For $i = 0 To 2
            If $aDateSplit[$i] = $iCount Then
                $sYMD &= '$'& ($i*2 +1) & ($iCount <> 3 ? $sDelim : '')
                $iCount += 1
                ExitLoop
            EndIf
        Next
    Until $iCount = 4

    $sStartDate = StringRegExpReplace($sStartDate, '(\d+)(\D)(\d+)(\D)(\d+)', $sYMD)
    $sStopDate  = StringRegExpReplace($sStopDate,  '(\d+)(\D)(\d+)(\D)(\d+)', $sYMD)

    Local $vReverse = False
    If $sStartDate > $sStopDate Then
        $vReverse = $sStartDate
        $sStartDate = $sStopDate
        $sStopDate = $vReverse
    EndIf

    ; internal format = yyyy/mm/dd
    Local $iStartYear = Number(StringRegExp($sStartDate, '\d+', 3)[0]), $iStopYear = Number(StringRegExp($sStopDate, '\d+', 3)[0])

    Local $aTimeLine[(($iStopYear - $iStartYear +1) *366)]

    $iCount = 0
    For $iYear = $iStartYear To $iStopYear
        For $iMon = 1 To 12
            Switch $iMon
                Case 1, 3, 5, 7, 8, 10, 12
                    For $iDay = 1 To 31 ; this section of code can be shortened
                        $aTimeLine[$iCount] = $iYear & $sDelim & StringFormat('%02i', $iMon) & $sDelim & StringFormat('%02i', $iDay)
                        If $aTimeLine[$iCount] = $sStopDate Then ExitLoop 3
                        $iCount += 1
                    Next

                Case 4, 6, 9, 11
                    For $iDay = 1 To 30
                        $aTimeLine[$iCount] = $iYear & $sDelim & StringFormat('%02i', $iMon) & $sDelim & StringFormat('%02i', $iDay)
                        If $aTimeLine[$iCount] = $sStopDate Then ExitLoop 3
                        $iCount += 1
                    Next

                Case Else
                    For $iDay = 1 To IsLeapYear($iYear) ? 29 : 28
                        $aTimeLine[$iCount] = $iYear & $sDelim & StringFormat('%02i', $iMon) & $sDelim & StringFormat('%02i', $iDay)
                        If $aTimeLine[$iCount] = $sStopDate Then ExitLoop 3
                        $iCount += 1
                    Next
            EndSwitch
        Next
    Next

    ReDim $aTimeLine[$iCount +1] ; get rid of unused elements

    For $i = 0 To UBound($aTimeLine) -1
        If $aTimeLine[$i] = $sStartDate Then
            _DeleteRegion($aTimeLine, 1, 0, $i)
            ExitLoop
        EndIf
    Next

    _Predim($aTimeLine, 2) ; add 2nd dimension

    ; adding a day name column only works for start dates up to christmas day 2999 [millennium bug], is it worth fixing? ==> [FIXED]

    If $iDayName <> -1 Then ; $iDayName set to -1 because _DateDayOfWeek() format values range from 0 to 3
        ReDim $aTimeLine[UBound($aTimeLine)][2]

        Local $aNextDay, $iDayNum

        If $sStartDate <= ('2999' & $sDelim & '12' & $sDelim & '25') Then
            For $i = 0 To 6
                If $i = UBound($aTimeLine) Then ExitLoop
                $aNextDay = StringRegExp($aTimeLine[$i][0], '\d+', 3)
                $iDayNum = _DateToDayOfWeek (Number($aNextDay[0]), Number($aNextDay[1]), Number($aNextDay[2]))
                $aTimeLine[$i][1] = _DateDayOfWeek($iDayNum, $iDayName)
            Next

            For $i = 7 To UBound($aTimeLine) -1
                $aTimeLine[$i][1] = $aTimeLine[Mod($i, 7)][1]
            Next

        Else
            Local $aDayName[7]
            For $i = 25 To 31
                $aNextDay = StringRegExp('2999/12/' & $i, '\d+', 3)
                $iDayNum = _DateToDayOfWeek (Number($aNextDay[0]), Number($aNextDay[1]), Number($aNextDay[2]))
                $aDayName[$i -25] = _DateDayOfWeek($iDayNum, $iDayName)
            Next

            Local $iDateDiff = DateRange('2999/12/25', StringReplace($aTimeLine[0][0], $sDelim, '/'))

            For $i = 0 to 6
                If $i = UBound($aTimeLine) Then ExitLoop
                $aTimeLine[$i][1] = $aDayName[Mod($iDateDiff + $i -1, 7)]
            Next

            For $i = 7 To UBound($aTimeLine) -1
                $aTimeLine[$i][1] = $aTimeLine[Mod($i, 7)][1]
            Next
        EndIf
    EndIf

    If $sFormat = Default Then ; [regexp pattern stored in ini or settings]
        $aDateSplit = StringRegExp($sYMD, '\d', 3)
        _Predim($aDateSplit, 2)
        ReDim $aDateSplit[3][2]
        $aDateSplit[0][1] = 1
        $aDateSplit[1][1] = 3
        $aDateSplit[2][1] = 5
        _ArraySort($aDateSplit)
        $sFormat = '$' & $aDateSplit[0][1] & $sDelim & '$' &  $aDateSplit[1][1] & $sDelim & '$' &  $aDateSplit[2][1]
    EndIf

    For $i = 0 To UBound($aTimeLine) -1
        $aTimeLine[$i][0] = StringRegExpReplace($aTimeLine[$i][0], '(\d+)(\D)(\d+)(\D)(\d+)', $sFormat)
    Next

    If $vReverse Then _ReverseArray($aTimeLine)

    _ArrayDisplay($aTimeLine)
    Return $aTimeLine
EndFunc ;==> GetDateArray

Func IsLeapYear($iYear)
    If Mod($iYear, 4) Then
        Return False
    ElseIf Mod($iYear, 100) Then
        Return True
    ElseIf Mod($iYear, 400) Then
        Return False
    Else
        Return True
    EndIf
EndFunc ;==> IsLeapYear

Func DateRange($sDate1, $sDate2) ; must be yyyy/mm/dd

$aDate1 = stringsplit($sDate1 , "/")
$aDate1[2] = stringformat("%02i" , $aDate1[2])
$aDate1[3] = stringformat("%02i" , $aDate1[3])

$aDate2 = stringsplit($sDate1 , "/")
$aDate2[2] = stringformat("%02i" , $aDate2[2])
$aDate2[3] = stringformat("%02i" , $aDate2[3])

;~ msgbox(0, '' , $aDate1[1] & @LF & $aDate1[2] & @LF & $aDate1[3])

$sDate1 = $aDate1[1] & "/" & $aDate1[2] & "/" & $aDate1[3]
$sDate2 = $aDate2[1] & "/" & $aDate2[2] & "/" & $aDate2[3]

;~    msgbox(0, '' , $sDate1 & @LF & $sDate2)

    Local $vTemp
    If $sDate1 > $sDate2 Then
        $vTemp = $sDate1
        $sDate1 = $sDate2
        $sDate2 = $vTemp
    EndIf

    Local $aArray1 = StringRegExp($sDate1, '\d+', 3), $aArray2 = StringRegExp($sDate2, '\d+', 3)
    For $i = 0 To 2
        $aArray1[$i] = Number($aArray1[$i])
        $aArray2[$i] = Number($aArray2[$i])
    Next

    Local $iCount = 0
    For $i = $aArray1[0] +1 To $aArray2[0] -1
        If Not IsLeapYear($i) Then
            $iCount += 365
        Else
            $iCount += 366
        EndIf
    Next

    Local $iFirstMonth = 0
    Switch $aArray1[1]
        Case 1, 3, 5, 7, 8, 10, 12
            $iFirstMonth = 32 - $aArray1[2]
        Case 4, 6, 9, 11
            $iFirstMonth = 31 - $aArray1[2]
        Case Else
            $iFirstMonth = (IsLeapYear($aArray1[0]) ? 30 : 29) - $aArray1[2]
    EndSwitch

    If $aArray1[0] < $aArray2[0] Then
        $iCount += $iFirstMonth

        For $i = $aArray1[1] +1 to 12
            Switch $i
                Case 1, 3, 5, 7, 8, 10, 12
                    $iCount += 31
                Case 4, 6, 9, 11
                    $iCount += 30
                Case Else
                    $iCount += (IsLeapYear($aArray1[0]) ? 29 : 28)
            EndSwitch
        Next

        $iCount += $aArray2[2] ; add remaining days in final month
        If $aArray2[1] > 1 Then
            For $i = 1 To $aArray2[1] -1
                Switch $i
                    Case 1, 3, 5, 7, 8, 10, 12
                        $iCount += 31
                    Case 4, 6, 9, 11
                        $iCount += 30
                    Case Else
                        $iCount += (IsLeapYear($aArray2[0]) ? 29 : 28)
                EndSwitch
            Next
        EndIf

    ElseIf $aArray1[1] < $aArray2[1] Then ; same year, different month
        $iCount += $iFirstMonth
        For $i = $aArray1[1] +1 to $aArray2[1] -1
            Switch $i
                Case 1, 3, 5, 7, 8, 10, 12
                    $iCount += 31
                Case 4, 6, 9, 11
                    $iCount += 30
                Case Else
                    $iCount += (IsLeapYear($aArray1[0]) ? 29 : 28)
            EndSwitch
        Next
        $iCount += $aArray2[2]

    Else ; same month and year
        $iCount = $aArray2[2] - $aArray1[2] +1
    EndIf

    Return $iCount
EndFunc ;==> DateRange

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Functions from ArrayWorkshop.au3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

#Au3Stripper_Off

Func _ReverseArray(ByRef $aArray, $iDimension = 1, $iStart = 0, $iEnd = -1)
    If Not IsArray($aArray) Or UBound($aArray, 0) > 9 Then Return SetError(1) ; not a valid array

    Local $aBound = __GetBounds($aArray)
    If @error Then Return SetError(2) ; array contains zero elements

    $iDimension = ($iDimension = Default) ? 1 : Int($iDimension)
    If $iDimension < 1 Or $iDimension > $aBound[0] Then Return SetError(3) ; dimension does not exist

    $iStart = ($iStart = Default) ? 0 : Int($iStart)
    If $iStart < 0 Or $iStart > $aBound[$iDimension] - 2 Then Return SetError(4) ; meaningless $iStart value

    $iEnd = ($iEnd = -1 Or $iEnd = Default) ? $aBound[$iDimension] - 1 : Int($iEnd)
    If $iEnd <= $iStart Or $iEnd >= $aBound[$iDimension] Then Return SetError(5) ; meaningless $iEnd value

    If $aBound[0] = 1 Then
        ___Reverse1D($aArray, $iStart, $iEnd)
    Else
        $aBound[$iDimension] = 1
        Local $aRegion = ___NewArray($aBound) ; to store extracted regions

        For $i = 1 To $aBound[0]
            $aBound[$i] -= 1
        Next

        Local $sIndices = __HiddenIndices($aBound[0], $iDimension), $fnFloodFill = __FloodFunc()[$aBound[0]], _
                $sTransfer = '$aSource' & $sIndices ; array syntax

        While $iEnd > $iStart
            $fnFloodFill($aRegion, $aBound, $iDimension, 0, $iStart, $aArray, $sTransfer) ; extract the current start region

            $sTransfer = '$aTarget' & $sIndices
            $fnFloodFill($aArray, $aBound, $iDimension, $iStart, $iEnd, '', $sTransfer) ; overwrite the current start region

            $sTransfer = '$aSource' & $sIndices
            $fnFloodFill($aArray, $aBound, $iDimension, $iEnd, 0, $aRegion, $sTransfer) ; overwrite the current end region

            $iStart += 1
            $iEnd -= 1
        WEnd
    EndIf
EndFunc    ;==>_ReverseArray

Func _DeleteRegion(ByRef $aArray, $iDimension = 1, $iSubIndex = 0, $iRange = 1)
    If Not IsArray($aArray) Then Return SetError(1)

    Local $aBound = __GetBounds($aArray) ; get the bounds of each dimension
    If @error Then Return SetError(4) ; $aArray must contain at least one element
    If $aBound[0] > 9 Then Return SetError(2) ; nine dimension limit

    $iDimension = ($iDimension = Default) ? 1 : Int($iDimension)
    If $iDimension > $aBound[0] Or $iDimension < 1 Then Return SetError(3) ; out of bounds dimension

    $iSubIndex = ($iSubIndex = Default) ? 0 : Int($iSubIndex)
    If $iSubIndex < 0 Or $iSubIndex > $aBound[$iDimension] - 1 Then Return SetError(5) ; sub-index does not exist in the dimension

    $iRange = ($iRange = Default) ? 1 : Int($iRange)
    If $iRange < 1 Then Return SetError(6) ; range must be greater than zero
    $iRange = ($iSubIndex + $iRange < $aBound[$iDimension]) ? $iRange : $aBound[$iDimension] - $iSubIndex ; corrects for overflow
    If $iRange = $aBound[$iDimension] Then Return SetError(6) ; deleting the whole region is not currently supported [give reason]

    $aBound[$iDimension] -= $iRange ; the size of the dimension in the new array

    If $aBound[0] = 1 Then
        For $iNext = $iSubIndex To $aBound[$iDimension] - 1
            $aArray[$iNext] = $aArray[$iNext + $iRange]
        Next
        ReDim $aArray[$aBound[$iDimension]]
        Return
    EndIf

    Local $iMaxIndex = $aBound[$iDimension] - 1
    For $i = 1 To $aBound[0]
        $aBound[$i] -= 1
    Next
    $aBound[$iDimension] = 0 ; set to loop once [one region at a time]

    Local $iFrom, $sTransfer = '$aTarget' & __HiddenIndices($aBound[0], $iDimension), $fnFloodFill = __FloodFunc()[$aBound[0]]

    For $iNext = $iSubIndex To $iMaxIndex
        $iFrom = $iNext + $iRange
        $fnFloodFill($aArray, $aBound, $iDimension, $iNext, $iFrom, '', $sTransfer) ; overwrite the final [untouched] region
    Next

    $aBound[$iDimension] = $iMaxIndex
    For $i = 1 To $aBound[0]
        $aBound[$i] += 1
    Next

    __ResetBounds($aArray, $aBound) ; delete remaining indices
EndFunc    ;==>_DeleteRegion

Func _PreDim(ByRef $aArray, $iDimensions, $bPush = False)
    If Not IsArray($aArray) Then Return SetError(1)

    $iDimensions = Int($iDimensions)
    If $iDimensions < 1 Or $iDimensions > 9 Then Return SetError(2)

    Local $iPreDims = UBound($aArray, 0) ; current number of dimensions
    If $iPreDims = $iDimensions Then Return ; no change
    If $iPreDims > 9 Then Return SetError(3) ; too many dimensions

    Local $aBound = __GetBounds($aArray) ; get the size of each original dimension
    If @error Then Return SetError(4) ; $aArray must contain at least one element

    $aBound[0] = $iDimensions ; overwrite this value with the new number of dimensions

    Local $sTransfer = '[$a[1]][$a[2]][$a[3]][$a[4]][$a[5]][$a[6]][$a[7]][$a[8]][$a[9]]' ; array syntax to be sent to the remote loop region

    If $bPush Then ; prefix dimensions, or delete from the left
        Local $iOffset = Abs($iDimensions - $iPreDims)
        If $iPreDims > $iDimensions Then ; lower dimensions get deleted
            For $i = 1 To $iDimensions ; shift elements to lower indices
                $aBound[$i] = $aBound[$i + $iOffset]
            Next
            $sTransfer = '$aSource' & StringLeft('[0][0][0][0][0][0][0][0]', $iOffset * 3) & StringLeft($sTransfer, $iDimensions * 7)

        Else ; lower dimensions are created
            ReDim $aBound[$iDimensions + 1] ; make space for more dimensions
            For $i = $iDimensions To $iOffset + 1 Step -1 ; shift elements to higher indices
                $aBound[$i] = $aBound[$i - $iOffset]
            Next
            For $i = 1 To $iOffset ; assign the size of each additional dimension [1][1][1]... etc...
                $aBound[$i] = 1
            Next

            $sTransfer = '$aSource' & StringMid($sTransfer, 1 + $iOffset * 7, $iPreDims * 7)
        EndIf

    Else ; Default behaviour = append dimensions, or delete from the right
        ReDim $aBound[$iDimensions + 1] ; modify the number of dimensions [according to the new array]

        For $i = $iPreDims + 1 To $iDimensions ; assign the size of each new dimension ...[1][1][1] etc...
            $aBound[$i] = 1
        Next
        $sTransfer = '$aSource' & StringLeft($sTransfer, $iPreDims * 7)
    EndIf

    ; add or remove dimensions
    Local $aNewArray = ___NewArray($aBound)

    For $i = 1 To $iDimensions
        $aBound[$i] -= 1 ; convert elements to the maximum index value within each dimension
    Next

    ; access the remote loop region
    Local $iSubIndex = 0, $aFloodFill = __FloodFunc()
    $aFloodFill[$iDimensions]($aNewArray, $aBound, 0, $iSubIndex, '', $aArray, $sTransfer)

    $aArray = $aNewArray
EndFunc    ;==>_PreDim

Func __GetBounds($aArray, $iHypothetical = 0)
    Local $iMaxDim = UBound($aArray, 0)
    Local $aBound[($iHypothetical ? $iHypothetical : $iMaxDim) + 1] ; [or ==> Local $aBound[9]]
    $aBound[0] = $iMaxDim
    For $i = 1 To $iMaxDim
        $aBound[$i] = UBound($aArray, $i)
        If $aBound[$i] = 0 Then Return SetError(1)
    Next
    If $iHypothetical Then
        For $i = $iMaxDim + 1 To $iHypothetical
            $aBound[$i] = 1 ; imaginary dimensions
        Next
    EndIf
    Return $aBound
EndFunc    ;==>__GetBounds

Func __HiddenIndices($iBound, $iDimension)
    Local $sSyntax = '' ; to access elements at their original indices
    For $i = 1 To $iBound
        If $i <> $iDimension Then
            $sSyntax &= '[$a[' & $i & ']]' ; default ==> '$aSource[$iFrom][$a[2]][$a[3]][$a[4]][$a[5]] etc...'
        Else
            $sSyntax &= '[$iFrom]'
        EndIf
    Next
    Return $sSyntax
EndFunc    ;==>__HiddenIndices

Func ___NewArray($aBound)
    Switch $aBound[0]
        Case 1
            Local $aArray[$aBound[1]]
        Case 2
            Local $aArray[$aBound[1]][$aBound[2]]
        Case 3
            Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]]
        Case 4
            Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]]
        Case 5
            Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]]
        Case 6
            Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]]
        Case 7
            Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]]
        Case 8
            Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]]
        Case 9
            Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]][$aBound[9]]
    EndSwitch
    Return $aArray
EndFunc    ;==>___NewArray

Func ___Reverse1D(ByRef $aArray, $iStart, $iStop)
    Local $vTemp
    While $iStop > $iStart
        $vTemp = $aArray[$iStart]
        $aArray[$iStart] = $aArray[$iStop]
        $aArray[$iStop] = $vTemp
        $iStart += 1
        $iStop -= 1
    WEnd
EndFunc    ;==>___Reverse1D

Func __ResetBounds(ByRef $aArray, $aBound)
    Switch $aBound[0]
        Case 1
            ReDim $aArray[$aBound[1]]
        Case 2
            ReDim $aArray[$aBound[1]][$aBound[2]]
        Case 3
            ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]]
        Case 4
            ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]]
        Case 5
            ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]]
        Case 6
            ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]]
        Case 7
            ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]]
        Case 8
            ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]]
        Case 9
            ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]][$aBound[9]]
    EndSwitch
EndFunc    ;==>__ResetBounds

Func __FloodFunc() ; [modified for this demo]
    Local $aFloodFunc = ['', ___Flood1D, ___Flood2D] ; , ___Flood3D, ___Flood4D, ___Flood5D, ___Flood6D, ___Flood7D, ___Flood8D, ___Flood9D]
    Return $aFloodFunc
EndFunc    ;==>__FloodFunc

Func ___Flood1D(ByRef $aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer) ; [still experimental]
    #forceref $iDimension, $iFrom, $aSource ; $iDimension would normally not apply here (special case)
    Local $a[10] = ['', 0, 0, 0, 0, 0, 0, 0, 0, 0] ; loop iteration count [or indices of higher dimensions within the source array]
    For $a[1] = $iSubIndex To $aBound[1] ; from the start to the bounds of the 1st dimension (special case)
        ; only one operation is needed in this special case
        $aTarget[$a[1]] = Execute($sTransfer) ; hidden parameters may appear in the code being executed
    Next
EndFunc    ;==>___Flood1D

Func ___Flood2D(ByRef $aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer)
    #forceref $iFrom, $aSource ; hidden parameters
    Local $a[10] = ['', 0, 0, 0, 0, 0, 0, 0, 0, 0] ; loop iteration count [or indices of higher dimensions within the source array]
    For $a[2] = 0 To $aBound[2]
        For $a[1] = 0 To $aBound[1]
            $a[$iDimension] = $iSubIndex ; override the iteration count (fast method) - $a[0] has no influence
            $aTarget[$a[1]][$a[2]] = Execute($sTransfer) ; hidden parameters may appear in the code being executed
        Next
    Next
EndFunc    ;==>___Flood2D

#Au3Stripper_On

 

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

It's a bug in the recognition of Start/End Date. I'm now almost certain that it's a format recognition issue, and that some kind of universal date format recognition algorithm should fix it. Grab some dates, analyse the locale format and then tweak the recognition pattern (if I'm right).

I'm not brave enough to set my locale to Chinese, in case I can't undo the changes.

Edited by czardas
Link to comment
Share on other sites

 

 @iamtheky  You were heading the right direction, but on a parallel path. How's this? The empty elements have gone away.

#include <Array.au3>
#include <GUIConstants.au3>
#include <GuiEdit.au3>
#include <Misc.au3>
#include <GuiTab.au3>
#include <Date.au3>
#include <APILocaleConstants.au3>
#include <WinAPILocale.au3>
;#include <ArrayWorkshop.au3> ; required functions are already included in this demo

NewTable()

Func NewTable(); ($hParent, $idListView, $hListView) ; [missing parent window]
    Local $sTitle = "New Table", _
    $iStyle = BitOR($WS_CAPTION, $WS_POPUP, $WS_SYSMENU), _
    $iExStyle = BitOR($WS_EX_MDICHILD, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST), _
    $iWidth = 250, _
    $iHeight = 292

    Local $hChild = GUICreate($sTitle, $iWidth, $iHeight, Default + 100, Default + 100); , $iStyle, $iExStyle, $hParent)

    Local $idTab = GUICtrlCreateTab(2, 2, $iWidth -2, $iHeight -32)

    GUICtrlCreateTabItem("Standard")

    GUICtrlCreateLabel("Table Dimensions", 14, 35, 120, 20)
    GUICtrlSetColor(-1, 0x008000)

    GUICtrlCreateLabel("Number Of Columns", 14, 60, 94, 18)
    Local $hStandardCols = GUICtrlCreateInput("0", 104 +14, 55, 50, 20, BitOR($WS_TABSTOP, $ES_CENTER, $ES_NUMBER))
    GUICtrlSetFont(-1, 10)

    GUICtrlCreateLabel("Number Of Rows", 14, 83, 90, 18)
    Local $hStandardRows = GUICtrlCreateInput("0", 104 +14, 81, 50, 20, BitOR($WS_TABSTOP, $ES_CENTER, $ES_NUMBER))
    GUICtrlSetFont(-1, 10)

    GUICtrlCreateLabel("Table Indices", 14, 114, 120, 20)
    GUICtrlSetColor(-1, 0x008000)

    Local $hIndices = GUICtrlCreateCheckbox(" Enumerate First Column", 14, 137, 160, 20) ; REMEMBER YES, SETTINGS NO

    Local $hPadding = GUICtrlCreateCheckbox(" Include Leading Zeros", 14, 161, 124, 20) ; REMEMBER YES, SETTINGS NO

    GUICtrlCreateTabItem("Advanced")

    GUICtrlCreateLabel("Column 1 = Date Range", 14, 35, 120, 20)
    GUICtrlSetColor(-1, 0x008000)

    GUICtrlCreateLabel("Start Date", 14, 35 +20, 100, 20)
    Local $idDate1 = GUICtrlCreateDate("", 14, 56 +20, 105, 20, $WS_TABSTOP)

    GUICtrlCreateLabel("End Date", $iWidth - 118, 35 +20, 100, 20)
    Local $idDate2 = GUICtrlCreateDate("", $iWidth - 118, 56 +20, 105, 20, BitOR($WS_TABSTOP, $DTS_RIGHTALIGN))

    GUICtrlCreateLabel("Column 2 = Days Of The Week (Optional)", 14, 108, 220, 20)
    GUICtrlSetColor(-1, 0x008000)

    Local $hCheckBox = GUICtrlCreateCheckbox(" Include Days Of The Week ", 14, 128, 190, 20) ; REMEMBER YES, SETTINGS NO

    Local $hRadio1 = GUICtrlCreateRadio(" Use Short Name", 14, 151)
    Local $hRadio2 = GUICtrlCreateRadio(" Use Long Name", $iWidth - 118, 151)
    GUICtrlSetState(-1, $GUI_CHECKED)
    GUICtrlSetState($hRadio1, $GUI_DISABLE) ; check settings later
    GUICtrlSetState($hRadio2, $GUI_DISABLE) ; check settings later

    GUICtrlCreateLabel("Add More Columns", 14, 181, 222, 20)
    GUICtrlSetColor(-1, 0x008000)

    GUICtrlCreateLabel("Total Number Of Columns", 14, 182 +23, 129, 18)
    Local $hColNum = GUICtrlCreateInput("1", 130 +14, 182 +21, 50, 20, BitOR($WS_TABSTOP, $ES_CENTER, $ES_NUMBER)) ; REMEMBER YES, SETTINGS NO
    GUICtrlSetFont(-1, 10)

    GUICtrlCreateTabItem("") ; end tabitem definition

    Local $hCancel = GUICtrlCreateButton("Cancel", $iWidth -143, $iHeight -25, 66, 20)
    Local $hOkay = GUICtrlCreateButton("OK", $iWidth -69, $iHeight -25, 66, 20)
    GUISetState(@SW_SHOW)

    Local $msg2, $bDisable = True, $iMaxFields = 65000, $bStandardError = False, $iRows = 0, $iCols = 0, _
    $sMonitorAdv = GUICtrlRead($idDate1) & GUICtrlRead($idDate2) & GUICtrlRead($hColNum), $sDate1, $sDate2, $sColsAdv, $iDiff, $bErrorAdv = False

    While 1
        $msg2 = GUIGetMsg()
        If $msg2 = $hCancel Or $msg2 = $GUI_EVENT_CLOSE Then ExitLoop

        If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED Then
            If $bDisable Then
                GUICtrlSetState($hRadio1, $GUI_ENABLE)
                GUICtrlSetState($hRadio2, $GUI_ENABLE)
                $bDisable  = False
            EndIf

        ElseIf Not $bDisable Then
            GUICtrlSetState($hRadio1, $GUI_DISABLE)
            GUICtrlSetState($hRadio2, $GUI_DISABLE)
            $bDisable  = True
        EndIf

        $sDate1 = GUICtrlRead($idDate1)
        $sDate2 = GUICtrlRead($idDate2)
        $sColsAdv = GUICtrlRead($hColNum)

        If $sDate1 & $sDate2 & $sColsAdv <> $sMonitorAdv Then

            $iDiff = DateRange(LocaleDateToYMD($sDate1), LocaleDateToYMD($sDate2)) ; _DateDiff() is too limited

            If $iDiff * $sColsAdv > $iMaxFields Then
                If Not $bErrorAdv Then
                    GUICtrlSetBkColor($hColNum, 0xFFA090)
                    $bErrorAdv = True
                EndIf

            ElseIf $bErrorAdv Then
                GUICtrlSetBkColor($hColNum, 0xFFFFFF)
                $bErrorAdv = False
            EndIf

            $sMonitorAdv = $sDate1 & $sDate2 & $sColsAdv
        EndIf

        $iCols = GUICtrlRead($hStandardCols)
        $iRows = GUICtrlRead($hStandardRows)

        If Not $iRows Then GUICtrlSetData($hStandardRows, 0)
        If Not $iCols Then GUICtrlSetData($hStandardCols, 0)

        If ControlGetFocus($hChild) <> "Edit2" And StringRegExp($iRows, '\A0+[1-9]') Then GUICtrlSetData($hStandardRows, StringRegExpReplace($iRows, '(\A0+)([1-9])(\d+)*', '$2$3'))
        If ControlGetFocus($hChild) <> "Edit1" And StringRegExp($iCols, '\A0+[1-9]') Then GUICtrlSetData($hStandardCols, StringRegExpReplace($iCols, '(\A0+)([1-9])(\d+)*', '$2$3'))

        If $iRows > $iMaxFields Or $iCols > $iMaxFields Or GUICtrlRead($hStandardRows) * GUICtrlRead($hStandardCols) > $iMaxFields Then
            If Not $bStandardError Then
                GUICtrlSetBkColor($hStandardRows, 0xFFA090)
                GUICtrlSetBkColor($hStandardCols, 0xFFA090)
                $bStandardError = True
            EndIf

        ElseIf $bStandardError Then
            GUICtrlSetBkColor($hStandardRows, 0xFFFFFF)
            GUICtrlSetBkColor($hStandardCols, 0xFFFFFF)
            $bStandardError = False
        EndIf

        $iCols = GUICtrlRead($hColNum)
        If ControlGetFocus($hChild) <> "Edit3" And StringRegExp($iCols, '\A0+[1-9]') Then GUICtrlSetData($hColNum, StringRegExpReplace($iCols, '(\A0+)([1-9])(\d+)*', '$2$3'))

        $iCols = GUICtrlRead($hColNum)
        If $iCols < 1 Then
            If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED And ControlGetFocus($hChild) <> "Edit3" Then
                GUICtrlSetData($hColNum, 2)
            Else
                GUICtrlSetData($hColNum, 1)
            EndIf
            If ControlGetFocus($hChild) = "Edit3" Then _GUICtrlEdit_SetSel($hColNum, 0, -1)
        EndIf

        If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED Then
            If $iCols < 2 And ControlGetFocus($hChild) <> "Edit3" Then
                If ControlGetFocus($hChild) = "Button3" Then
                    While _IsPressed('01')
                        Sleep(20)
                    WEnd
                EndIf

                If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED Then
                    GUICtrlSetData($hColNum, 2)
                Else
                    GUICtrlSetData($hColNum, 1)
                EndIf
            EndIf
        Else
            If $iCols < 1 Then
                GUICtrlSetData($hColNum, 1)
                If ControlGetFocus($hChild) = "Edit3" Then _GUICtrlEdit_SetSel($hColNum, 0, -1)
            EndIf
        EndIf

        If $msg2 = $hOkay Then
            If $bErrorAdv Then
                MsgBox(262160, "uh-uh!", "Out of Range")
                ContinueLoop
            EndIf

            Local $sDelim = '-' ; read from settings ??? [maybe]
            If _GUICtrlTab_GetCurFocus($idTab) = 1 Then
                Local $iName, $sFormat = Default ; read from settings [ini]
                If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED Then
                    $iName = (BitAND(GUICtrlRead($hRadio1), $GUI_CHECKED) == $GUI_CHECKED) ? 3 : 2
                Else
                    $iName = -1
                EndIf

                ; $sStartDate, $sStopDate, $sDelim = Default, $sFormat = Default, $iDayName = -1)
                GetDateArray(GUICtrlRead($idDate1), GUICtrlRead($idDate2), $sDelim, $sFormat, $iName) ; US [, '$3-$5-$1'])

            EndIf
        EndIf
    WEnd
    GUIDelete($hChild)
EndFunc ;==> NewTable

Func LocaleDateToYMD($sDate, $sDelim = '/')
    Local $iID = _WinAPI_GetUserDefaultLCID(), _
    $aDateSplit = StringRegExp(_WinAPI_GetLocaleInfo($iID, $LOCALE_SSHORTDATE), '\w+', 3), _
    $vTest = True ; [floating variable]

    If IsArray($aDateSplit) And UBound($aDateSplit) = 3 Then
        For $i = 0 To 2 ; determine the locale ymd order
            If StringInStr($aDateSplit[$i], 'y') Then
                $aDateSplit[$i] = 1 ; year
            ElseIf StringInStr($aDateSplit[$i], 'm') Then
                $aDateSplit[$i] = 2 ; month
            ElseIf StringInStr($aDateSplit[$i], 'd') Then
                $aDateSplit[$i] = 3 ; day
            EndIf
        Next

        $vTest = $aDateSplit[0] & $aDateSplit[1] & $aDateSplit[2]
        If StringInStr($vTest, '1') And StringInStr($vTest, '2') And StringInStr($vTest, '3') Then $vTest = False ; success
    EndIf

    If $vTest Then ; failure with the previous method [both methods work on Win7 in the UK]
        Local $sLongDate = _WinAPI_GetDateFormat(0, 0, $DATE_LONGDATE)
        $aDateSplit = StringRegExp($sLongDate, '(*UCP)\w+', 3)
        If Not IsArray($aDateSplit) And UBound($aDateSplit) <> 3 Then Return SetError(1) ; undetermined error?

        For $i = 0 To 2 ; determine the locale ymd order
            If $aDateSplit[$i] = @YEAR Then ; hopefully this method will work for all international regions
                $aDateSplit[$i] = 1 ; year
            ElseIf $aDateSplit[$i] = _DateToMonth(@MON, $DMW_LOCALE_LONGNAME) Then
                $aDateSplit[$i] = 2 ; month
            Else
                $aDateSplit[$i] = 3 ; day
            EndIf
        Next

        $vTest = $aDateSplit[0] & $aDateSplit[1] & $aDateSplit[2]
        If Not (StringInStr($vTest, '1') And StringInStr($vTest, '2') And StringInStr($vTest, '3')) Then Return SetError(2) ; undetermined error?
    EndIf

    Local $iCount = 1, $sYMD = ''
    Do
        For $i = 0 To 2
            If $aDateSplit[$i] = $iCount Then
                $sYMD &= '$'& ($i*2 +1) & ($iCount <> 3 ? $sDelim : '')
                $iCount += 1
                ExitLoop
            EndIf
        Next
    Until $iCount = 4

    Return StringRegExpReplace($sDate, '(\d+)(\D)(\d+)(\D)(\d+)', $sYMD)
EndFunc

Func GetDateArray($sStartDate, $sStopDate, $sDelim = Default, $sFormat = Default, $iDayName = -1)
    Local $iID = _WinAPI_GetUserDefaultLCID(), _
    $aDateSplit = StringRegExp(_WinAPI_GetLocaleInfo($iID, $LOCALE_SSHORTDATE), '\w+', 3)

    If IsArray($aDateSplit) And UBound($aDateSplit) = 3 Then
        For $i = 0 To 2 ; determine the locale ymd order
            If StringInStr($aDateSplit[$i], 'y') Then
                $aDateSplit[$i] = 1 ; year
            ElseIf StringInStr($aDateSplit[$i], 'm') Then
                $aDateSplit[$i] = 2 ; month
            ElseIf StringInStr($aDateSplit[$i], 'd') Then
                $aDateSplit[$i] = 3 ; day
            EndIf
        Next

    Else ; let's try an alternative method [both methods work on Win7 in the UK]
        Local $sLongDate = _WinAPI_GetDateFormat(0, 0, $DATE_LONGDATE)
        $aDateSplit = StringRegExp($sLongDate, '(*UCP)\w+', 3)
        If Not IsArray($aDateSplit) And UBound($aDateSplit) <> 3 Then Return SetError(1) ; undetermined error?

        For $i = 0 To 2 ; determine the locale ymd order
            If $aDateSplit[$i] = @YEAR Then ; hopefully this method will work for all international regions
                $aDateSplit[$i] = 1 ; year
            ElseIf $aDateSplit[$i] = _DateToMonth(@MON, $DMW_LOCALE_LONGNAME) Then
                $aDateSplit[$i] = 2 ; month
            Else
                $aDateSplit[$i] = 3 ; day
            EndIf
        Next
    EndIf

    ; check the array contains numbers 1 to 3
    Local $sTest = $aDateSplit[0] & $aDateSplit[1] & $aDateSplit[2]
    If Not (StringInStr($sTest, '1') And StringInStr($sTest, '2') And StringInStr($sTest, '3')) Then Return SetError(2) ; undetermined error?

    If $sDelim = Default Then $sDelim = StringRegExp($sStartDate, '\D+', 3)[0]

    Local $iCount = 1, $sYMD = ''
    Do
        For $i = 0 To 2
            If $aDateSplit[$i] = $iCount Then
                $sYMD &= '$'& ($i*2 +1) & ($iCount <> 3 ? $sDelim : '')
                $iCount += 1
                ExitLoop
            EndIf
        Next
    Until $iCount = 4

    $sStartDate = StringRegExpReplace($sStartDate, '(\d+)(\D)(\d+)(\D)(\d+)', $sYMD)
    $aDateSplit = StringRegExp($sStartDate, '\d+', 3)
    $sStartDate = StringFormat('%04i' & $sDelim & '%02i' & $sDelim & '%02i', $aDateSplit[0], $aDateSplit[1], $aDateSplit[2])

    $sStopDate  = StringRegExpReplace($sStopDate,  '(\d+)(\D)(\d+)(\D)(\d+)', $sYMD)
    $aDateSplit = StringRegExp($sStopDate, '\d+', 3)
    $sStopDate = StringFormat('%04i' & $sDelim & '%02i' & $sDelim & '%02i', $aDateSplit[0], $aDateSplit[1], $aDateSplit[2])

    Local $vReverse = False
    If $sStartDate > $sStopDate Then
        $vReverse = $sStartDate
        $sStartDate = $sStopDate
        $sStopDate = $vReverse
    EndIf

    ; internal format = yyyy/mm/dd
    Local $iStartYear = Number(StringRegExp($sStartDate, '\d+', 3)[0]), $iStopYear = Number(StringRegExp($sStopDate, '\d+', 3)[0])

    Local $aTimeLine[(($iStopYear - $iStartYear +1) *366)]

    $iCount = 0
    For $iYear = $iStartYear To $iStopYear
        For $iMon = 1 To 12
            Switch $iMon
                Case 1, 3, 5, 7, 8, 10, 12
                    For $iDay = 1 To 31 ; this section of code can be shortened
                        $aTimeLine[$iCount] = $iYear & $sDelim & StringFormat('%02i', $iMon) & $sDelim & StringFormat('%02i', $iDay)
                        If $aTimeLine[$iCount] = $sStopDate Then ExitLoop 3
                        $iCount += 1
                    Next

                Case 4, 6, 9, 11
                    For $iDay = 1 To 30
                        $aTimeLine[$iCount] = $iYear & $sDelim & StringFormat('%02i', $iMon) & $sDelim & StringFormat('%02i', $iDay)
                        If $aTimeLine[$iCount] = $sStopDate Then ExitLoop 3
                        $iCount += 1
                    Next

                Case Else
                    For $iDay = 1 To IsLeapYear($iYear) ? 29 : 28
                        $aTimeLine[$iCount] = $iYear & $sDelim & StringFormat('%02i', $iMon) & $sDelim & StringFormat('%02i', $iDay)
                        If $aTimeLine[$iCount] = $sStopDate Then ExitLoop 3
                        $iCount += 1
                    Next
            EndSwitch
        Next
    Next

    ReDim $aTimeLine[$iCount +1] ; get rid of unused elements

    For $i = 0 To UBound($aTimeLine) -1
        If $aTimeLine[$i] = $sStartDate Then
            _DeleteRegion($aTimeLine, 1, 0, $i)
            ExitLoop
        EndIf
    Next

    _Predim($aTimeLine, 2) ; add 2nd dimension

    ; adding a day name column only works for start dates up to christmas day 2999 [millennium bug], is it worth fixing? ==> [FIXED]

    If $iDayName <> -1 Then ; $iDayName set to -1 because _DateDayOfWeek() format values range from 0 to 3
        ReDim $aTimeLine[UBound($aTimeLine)][2]

        Local $aNextDay, $iDayNum

        If $sStartDate <= ('2999' & $sDelim & '12' & $sDelim & '25') Then
            For $i = 0 To 6
                If $i = UBound($aTimeLine) Then ExitLoop
                $aNextDay = StringRegExp($aTimeLine[$i][0], '\d+', 3)
                $iDayNum = _DateToDayOfWeek (Number($aNextDay[0]), Number($aNextDay[1]), Number($aNextDay[2]))
                $aTimeLine[$i][1] = _DateDayOfWeek($iDayNum, $iDayName)
            Next

            For $i = 7 To UBound($aTimeLine) -1
                $aTimeLine[$i][1] = $aTimeLine[Mod($i, 7)][1]
            Next

        Else
            Local $aDayName[7]
            For $i = 25 To 31
                $aNextDay = StringRegExp('2999/12/' & $i, '\d+', 3)
                $iDayNum = _DateToDayOfWeek (Number($aNextDay[0]), Number($aNextDay[1]), Number($aNextDay[2]))
                $aDayName[$i -25] = _DateDayOfWeek($iDayNum, $iDayName)
            Next

            Local $iDateDiff = DateRange('2999/12/25', StringReplace($aTimeLine[0][0], $sDelim, '/'))

            For $i = 0 to 6
                If $i = UBound($aTimeLine) Then ExitLoop
                $aTimeLine[$i][1] = $aDayName[Mod($iDateDiff + $i -1, 7)]
            Next

            For $i = 7 To UBound($aTimeLine) -1
                $aTimeLine[$i][1] = $aTimeLine[Mod($i, 7)][1]
            Next
        EndIf
    EndIf

    If $sFormat = Default Then ; [regexp pattern stored in ini or settings]
        $aDateSplit = StringRegExp($sYMD, '\d', 3)
        _Predim($aDateSplit, 2)
        ReDim $aDateSplit[3][2]
        $aDateSplit[0][1] = 1
        $aDateSplit[1][1] = 3
        $aDateSplit[2][1] = 5

        _ArraySort($aDateSplit)
        $sFormat = '$' & $aDateSplit[0][1] & $sDelim & '$' &  $aDateSplit[1][1] & $sDelim & '$' &  $aDateSplit[2][1]
    EndIf

    For $i = 0 To UBound($aTimeLine) -1
        $aTimeLine[$i][0] = StringRegExpReplace($aTimeLine[$i][0], '(\d+)(\D)(\d+)(\D)(\d+)', $sFormat)
    Next

    If $vReverse Then _ReverseArray($aTimeLine)

    _ArrayDisplay($aTimeLine)
    Return $aTimeLine
EndFunc ;==> GetDateArray

Func IsLeapYear($iYear)
    If Mod($iYear, 4) Then
        Return False
    ElseIf Mod($iYear, 100) Then
        Return True
    ElseIf Mod($iYear, 400) Then
        Return False
    Else
        Return True
    EndIf
EndFunc ;==> IsLeapYear

Func DateRange($sDate1, $sDate2) ; must be yyyy/mm/dd
    Local $vTemp
    If $sDate1 > $sDate2 Then
        $vTemp = $sDate1
        $sDate1 = $sDate2
        $sDate2 = $vTemp
    EndIf

    Local $aArray1 = StringRegExp($sDate1, '\d+', 3), $aArray2 = StringRegExp($sDate2, '\d+', 3)
    For $i = 0 To 2
        $aArray1[$i] = Number($aArray1[$i])
        $aArray2[$i] = Number($aArray2[$i])
    Next

    Local $iCount = 0
    For $i = $aArray1[0] +1 To $aArray2[0] -1
        If Not IsLeapYear($i) Then
            $iCount += 365
        Else
            $iCount += 366
        EndIf
    Next

    Local $iFirstMonth = 0
    Switch $aArray1[1]
        Case 1, 3, 5, 7, 8, 10, 12
            $iFirstMonth = 32 - $aArray1[2]
        Case 4, 6, 9, 11
            $iFirstMonth = 31 - $aArray1[2]
        Case Else
            $iFirstMonth = (IsLeapYear($aArray1[0]) ? 30 : 29) - $aArray1[2]
    EndSwitch

    If $aArray1[0] < $aArray2[0] Then
        $iCount += $iFirstMonth

        For $i = $aArray1[1] +1 to 12
            Switch $i
                Case 1, 3, 5, 7, 8, 10, 12
                    $iCount += 31
                Case 4, 6, 9, 11
                    $iCount += 30
                Case Else
                    $iCount += (IsLeapYear($aArray1[0]) ? 29 : 28)
            EndSwitch
        Next

        $iCount += $aArray2[2] ; add remaining days in final month
        If $aArray2[1] > 1 Then
            For $i = 1 To $aArray2[1] -1
                Switch $i
                    Case 1, 3, 5, 7, 8, 10, 12
                        $iCount += 31
                    Case 4, 6, 9, 11
                        $iCount += 30
                    Case Else
                        $iCount += (IsLeapYear($aArray2[0]) ? 29 : 28)
                EndSwitch
            Next
        EndIf

    ElseIf $aArray1[1] < $aArray2[1] Then ; same year, different month
        $iCount += $iFirstMonth
        For $i = $aArray1[1] +1 to $aArray2[1] -1
            Switch $i
                Case 1, 3, 5, 7, 8, 10, 12
                    $iCount += 31
                Case 4, 6, 9, 11
                    $iCount += 30
                Case Else
                    $iCount += (IsLeapYear($aArray1[0]) ? 29 : 28)
            EndSwitch
        Next
        $iCount += $aArray2[2]

    Else ; same month and year
        $iCount = $aArray2[2] - $aArray1[2] +1
    EndIf

    Return $iCount
EndFunc ;==> DateRange

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Functions from ArrayWorkshop.au3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

#Au3Stripper_Off

Func _ReverseArray(ByRef $aArray, $iDimension = 1, $iStart = 0, $iEnd = -1)
    If Not IsArray($aArray) Or UBound($aArray, 0) > 9 Then Return SetError(1) ; not a valid array

    Local $aBound = __GetBounds($aArray)
    If @error Then Return SetError(2) ; array contains zero elements

    $iDimension = ($iDimension = Default) ? 1 : Int($iDimension)
    If $iDimension < 1 Or $iDimension > $aBound[0] Then Return SetError(3) ; dimension does not exist

    $iStart = ($iStart = Default) ? 0 : Int($iStart)
    If $iStart < 0 Or $iStart > $aBound[$iDimension] - 2 Then Return SetError(4) ; meaningless $iStart value

    $iEnd = ($iEnd = -1 Or $iEnd = Default) ? $aBound[$iDimension] - 1 : Int($iEnd)
    If $iEnd <= $iStart Or $iEnd >= $aBound[$iDimension] Then Return SetError(5) ; meaningless $iEnd value

    If $aBound[0] = 1 Then
        ___Reverse1D($aArray, $iStart, $iEnd)
    Else
        $aBound[$iDimension] = 1
        Local $aRegion = ___NewArray($aBound) ; to store extracted regions

        For $i = 1 To $aBound[0]
            $aBound[$i] -= 1
        Next

        Local $sIndices = __HiddenIndices($aBound[0], $iDimension), $fnFloodFill = __FloodFunc()[$aBound[0]], _
                $sTransfer = '$aSource' & $sIndices ; array syntax

        While $iEnd > $iStart
            $fnFloodFill($aRegion, $aBound, $iDimension, 0, $iStart, $aArray, $sTransfer) ; extract the current start region

            $sTransfer = '$aTarget' & $sIndices
            $fnFloodFill($aArray, $aBound, $iDimension, $iStart, $iEnd, '', $sTransfer) ; overwrite the current start region

            $sTransfer = '$aSource' & $sIndices
            $fnFloodFill($aArray, $aBound, $iDimension, $iEnd, 0, $aRegion, $sTransfer) ; overwrite the current end region

            $iStart += 1
            $iEnd -= 1
        WEnd
    EndIf
EndFunc    ;==>_ReverseArray

Func _DeleteRegion(ByRef $aArray, $iDimension = 1, $iSubIndex = 0, $iRange = 1)
    If Not IsArray($aArray) Then Return SetError(1)

    Local $aBound = __GetBounds($aArray) ; get the bounds of each dimension
    If @error Then Return SetError(4) ; $aArray must contain at least one element
    If $aBound[0] > 9 Then Return SetError(2) ; nine dimension limit

    $iDimension = ($iDimension = Default) ? 1 : Int($iDimension)
    If $iDimension > $aBound[0] Or $iDimension < 1 Then Return SetError(3) ; out of bounds dimension

    $iSubIndex = ($iSubIndex = Default) ? 0 : Int($iSubIndex)
    If $iSubIndex < 0 Or $iSubIndex > $aBound[$iDimension] - 1 Then Return SetError(5) ; sub-index does not exist in the dimension

    $iRange = ($iRange = Default) ? 1 : Int($iRange)
    If $iRange < 1 Then Return SetError(6) ; range must be greater than zero
    $iRange = ($iSubIndex + $iRange < $aBound[$iDimension]) ? $iRange : $aBound[$iDimension] - $iSubIndex ; corrects for overflow
    If $iRange = $aBound[$iDimension] Then Return SetError(6) ; deleting the whole region is not currently supported [give reason]

    $aBound[$iDimension] -= $iRange ; the size of the dimension in the new array

    If $aBound[0] = 1 Then
        For $iNext = $iSubIndex To $aBound[$iDimension] - 1
            $aArray[$iNext] = $aArray[$iNext + $iRange]
        Next
        ReDim $aArray[$aBound[$iDimension]]
        Return
    EndIf

    Local $iMaxIndex = $aBound[$iDimension] - 1
    For $i = 1 To $aBound[0]
        $aBound[$i] -= 1
    Next
    $aBound[$iDimension] = 0 ; set to loop once [one region at a time]

    Local $iFrom, $sTransfer = '$aTarget' & __HiddenIndices($aBound[0], $iDimension), $fnFloodFill = __FloodFunc()[$aBound[0]]

    For $iNext = $iSubIndex To $iMaxIndex
        $iFrom = $iNext + $iRange
        $fnFloodFill($aArray, $aBound, $iDimension, $iNext, $iFrom, '', $sTransfer) ; overwrite the final [untouched] region
    Next

    $aBound[$iDimension] = $iMaxIndex
    For $i = 1 To $aBound[0]
        $aBound[$i] += 1
    Next

    __ResetBounds($aArray, $aBound) ; delete remaining indices
EndFunc    ;==>_DeleteRegion

Func _PreDim(ByRef $aArray, $iDimensions, $bPush = False)
    If Not IsArray($aArray) Then Return SetError(1)

    $iDimensions = Int($iDimensions)
    If $iDimensions < 1 Or $iDimensions > 9 Then Return SetError(2)

    Local $iPreDims = UBound($aArray, 0) ; current number of dimensions
    If $iPreDims = $iDimensions Then Return ; no change
    If $iPreDims > 9 Then Return SetError(3) ; too many dimensions

    Local $aBound = __GetBounds($aArray) ; get the size of each original dimension
    If @error Then Return SetError(4) ; $aArray must contain at least one element

    $aBound[0] = $iDimensions ; overwrite this value with the new number of dimensions

    Local $sTransfer = '[$a[1]][$a[2]][$a[3]][$a[4]][$a[5]][$a[6]][$a[7]][$a[8]][$a[9]]' ; array syntax to be sent to the remote loop region

    If $bPush Then ; prefix dimensions, or delete from the left
        Local $iOffset = Abs($iDimensions - $iPreDims)
        If $iPreDims > $iDimensions Then ; lower dimensions get deleted
            For $i = 1 To $iDimensions ; shift elements to lower indices
                $aBound[$i] = $aBound[$i + $iOffset]
            Next
            $sTransfer = '$aSource' & StringLeft('[0][0][0][0][0][0][0][0]', $iOffset * 3) & StringLeft($sTransfer, $iDimensions * 7)

        Else ; lower dimensions are created
            ReDim $aBound[$iDimensions + 1] ; make space for more dimensions
            For $i = $iDimensions To $iOffset + 1 Step -1 ; shift elements to higher indices
                $aBound[$i] = $aBound[$i - $iOffset]
            Next
            For $i = 1 To $iOffset ; assign the size of each additional dimension [1][1][1]... etc...
                $aBound[$i] = 1
            Next

            $sTransfer = '$aSource' & StringMid($sTransfer, 1 + $iOffset * 7, $iPreDims * 7)
        EndIf

    Else ; Default behaviour = append dimensions, or delete from the right
        ReDim $aBound[$iDimensions + 1] ; modify the number of dimensions [according to the new array]

        For $i = $iPreDims + 1 To $iDimensions ; assign the size of each new dimension ...[1][1][1] etc...
            $aBound[$i] = 1
        Next
        $sTransfer = '$aSource' & StringLeft($sTransfer, $iPreDims * 7)
    EndIf

    ; add or remove dimensions
    Local $aNewArray = ___NewArray($aBound)

    For $i = 1 To $iDimensions
        $aBound[$i] -= 1 ; convert elements to the maximum index value within each dimension
    Next

    ; access the remote loop region
    Local $iSubIndex = 0, $aFloodFill = __FloodFunc()
    $aFloodFill[$iDimensions]($aNewArray, $aBound, 0, $iSubIndex, '', $aArray, $sTransfer)

    $aArray = $aNewArray
EndFunc    ;==>_PreDim

Func __GetBounds($aArray, $iHypothetical = 0)
    Local $iMaxDim = UBound($aArray, 0)
    Local $aBound[($iHypothetical ? $iHypothetical : $iMaxDim) + 1] ; [or ==> Local $aBound[9]]
    $aBound[0] = $iMaxDim
    For $i = 1 To $iMaxDim
        $aBound[$i] = UBound($aArray, $i)
        If $aBound[$i] = 0 Then Return SetError(1)
    Next
    If $iHypothetical Then
        For $i = $iMaxDim + 1 To $iHypothetical
            $aBound[$i] = 1 ; imaginary dimensions
        Next
    EndIf
    Return $aBound
EndFunc    ;==>__GetBounds

Func __HiddenIndices($iBound, $iDimension)
    Local $sSyntax = '' ; to access elements at their original indices
    For $i = 1 To $iBound
        If $i <> $iDimension Then
            $sSyntax &= '[$a[' & $i & ']]' ; default ==> '$aSource[$iFrom][$a[2]][$a[3]][$a[4]][$a[5]] etc...'
        Else
            $sSyntax &= '[$iFrom]'
        EndIf
    Next
    Return $sSyntax
EndFunc    ;==>__HiddenIndices

Func ___NewArray($aBound)
    Switch $aBound[0]
        Case 1
            Local $aArray[$aBound[1]]
        Case 2
            Local $aArray[$aBound[1]][$aBound[2]]
        Case 3
            Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]]
        Case 4
            Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]]
        Case 5
            Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]]
        Case 6
            Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]]
        Case 7
            Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]]
        Case 8
            Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]]
        Case 9
            Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]][$aBound[9]]
    EndSwitch
    Return $aArray
EndFunc    ;==>___NewArray

Func ___Reverse1D(ByRef $aArray, $iStart, $iStop)
    Local $vTemp
    While $iStop > $iStart
        $vTemp = $aArray[$iStart]
        $aArray[$iStart] = $aArray[$iStop]
        $aArray[$iStop] = $vTemp
        $iStart += 1
        $iStop -= 1
    WEnd
EndFunc    ;==>___Reverse1D

Func __ResetBounds(ByRef $aArray, $aBound)
    Switch $aBound[0]
        Case 1
            ReDim $aArray[$aBound[1]]
        Case 2
            ReDim $aArray[$aBound[1]][$aBound[2]]
        Case 3
            ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]]
        Case 4
            ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]]
        Case 5
            ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]]
        Case 6
            ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]]
        Case 7
            ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]]
        Case 8
            ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]]
        Case 9
            ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]][$aBound[9]]
    EndSwitch
EndFunc    ;==>__ResetBounds

Func __FloodFunc() ; [modified for this demo]
    Local $aFloodFunc = ['', ___Flood1D, ___Flood2D] ; , ___Flood3D, ___Flood4D, ___Flood5D, ___Flood6D, ___Flood7D, ___Flood8D, ___Flood9D]
    Return $aFloodFunc
EndFunc    ;==>__FloodFunc

Func ___Flood1D(ByRef $aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer) ; [still experimental]
    #forceref $iDimension, $iFrom, $aSource ; $iDimension would normally not apply here (special case)
    Local $a[10] = ['', 0, 0, 0, 0, 0, 0, 0, 0, 0] ; loop iteration count [or indices of higher dimensions within the source array]
    For $a[1] = $iSubIndex To $aBound[1] ; from the start to the bounds of the 1st dimension (special case)
        ; only one operation is needed in this special case
        $aTarget[$a[1]] = Execute($sTransfer) ; hidden parameters may appear in the code being executed
    Next
EndFunc    ;==>___Flood1D

Func ___Flood2D(ByRef $aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer)
    #forceref $iFrom, $aSource ; hidden parameters
    Local $a[10] = ['', 0, 0, 0, 0, 0, 0, 0, 0, 0] ; loop iteration count [or indices of higher dimensions within the source array]
    For $a[2] = 0 To $aBound[2]
        For $a[1] = 0 To $aBound[1]
            $a[$iDimension] = $iSubIndex ; override the iteration count (fast method) - $a[0] has no influence
            $aTarget[$a[1]][$a[2]] = Execute($sTransfer) ; hidden parameters may appear in the code being executed
        Next
    Next
EndFunc    ;==>___Flood2D

#Au3Stripper_On

 

12-28-7466|Fri
12-29-7466|Sat
12-30-7466|Sun
12-31-7466|Mon
01-01-7467|Tue
01-02-7467|Wed
01-03-7467|Thu
01-04-7467|Fri
01-05-7467|Sat
01-06-7467|Sun
01-07-7467|Mon

 

Edited by czardas
Link to comment
Share on other sites

Taking another look at this today, I see that there may still be some minor issues (I have my suspicions): nothing I can't fix. I noticed various options when playing around with language settings. One of the Simplified Chinese options seemed to work, although I can't read the day name. I may have only installed a limited language set when I installed windows. I haven't exactly accounted for two digit years, but it seems ridiculous that they might appear in a date control which covers almost 10 millennia - who would do something so crazy as that? Delimiters may be longer than a single digit, and not necessarily consistent (a simple regexp tweak will fix this). I only intend to support formats which use Arabic numerals though.

Please could someone who was having problems yesterday confirm that the above version now works in the US/Holland.

Edited by czardas
Link to comment
Share on other sites

Excellent! :thumbsup: I'll play around with it a little, and later I'll post some better organized code along with comments. I have a busy schedule right now, so it might take me a day or two. You have been very helpful. Thanks everyone.

Edited by czardas
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...