Jump to content

czardas
 Share

Recommended Posts

_DateSetFormat and _ReadDate

This is work in progress and needs further testing and development. I plan to add some multilingual support and a sliding 100 year window for two digit year disambiguation - an excelent suggestion by our MvP water. The code is rough and ready, although suitable for my current needs. New features and documentation will have to wait since I have other pressing priorities. So please consider this as a beta release. I hope it serves some use to someone.

The formats supported were all taken from wikipedia, although it is possible to create several artificial formats not recognized as standard. This is just a by product, and is of no particular interest or significance.


DateFormat.zip

Previous downloads 29

Thanks to guiness for discovering the following spelling mistake in Finnish:

Loulukuuta changed to Joulukuuta - New version uploaded.

Edited by czardas
Link to comment
Share on other sites

  • 2 weeks later...

This seems like the start of a very useful UDF.

If you find the time, it would be useful to include languages from around the world, so that you can get from f.ex

20111101

to

نوفمبر 01 2011

given language chosen is "Arab"

Although of course the task of doing this is very hard, because some languages have different endings to weekdays and month names depending on position in date.

I have personally used resources from Omniglot

http://www.omniglot.com/language/time/months.htm

http://www.omniglot.com/language/time/days.htm

I am just a hobby programmer, and nothing great to publish right now.

Link to comment
Share on other sites

Myicq Thanks your vote of confidence, and for the links. :D

I have identified 18 languages which I can easily incorporate, but unfortunately Arabic was not among them. The languages I have selected can all be produced using Standard and Extended American AscII Characters. It would require Unicode characters to write Arabic, and unfortunately I am not familiar enough with using Unicode to offer any immediate promises.It could take me a while to figure it out. I feel less qualified to tackle certain languages (Chinese being another example).

As I am not a linguist, I do have some concerns about grammar. It's very easy to go wrong with something like this. For example I have discovered that in Finnish, month names do not have an abbreviated form, and in the written form the letters 'ta' are appended after the month.

The plan is that the end user will be able to control how dates are formatted in some settings panel. Once set, the program will handle everything else such as sorting by date or searching etc.. I should have something new to add to this within a day or two.

Edited by czardas
Link to comment
Share on other sites

Added

Support for month names in twenty different languages

100 year sliding window for two digit year disambiguation

Please see attachment to the first post.

Details

International short and long month names appear in the following languages: Albanian, Danish, Dutch, English, Estonian, Finnish, French, German, Greenlandic, Hungarian, Icelandic, Italian, Lithuanian, Norwegian, Portuguese, Romanian, Slovak, Slovenian, Spanish and Swedish. It is easy to add more languages if required.

Since the code contains several extended ascii characters, posting it directly on to the forum won't work, so the code is in the the zip file. The characters may (or may not) appear differently depending on your computer's regional settings. I think it should work on most Western and European computers. Any issues, please let me know.

This is not intended to be a date recognition system. The code should be viewed as formatting options based on a few loosely defined rules. Different combinations of settings should cover most common formats. It is possible to create illegal formats, so it is down to the user to decide which available options best suit his or her own language. It may appear complicated at first, but it's not so difficult once you get used to it.

If you are a native speaker of one of the above languages, please let me know if you are unable to create a compatible date format using month names in your language. If you would like me to add more languages, then please say which. Since this is a multilingual community, your input and suggestions would be a great help, and hopefully lead to a much more flexible set of functions than are available in the current UDF. Thanks!

The examples in the zip file are just all the tests I have been running during development. I'll create something more interactive later. Also note that there are quite a few error codes. These are for debugging purposes and are currently under revision.

Planned Improvements: New functions to prefix, append or strip days of the week in different languages / formats.

Edited by czardas
Link to comment
Share on other sites

  • 1 month later...

Added

Two new functions:

_DayGetName() and _DayStripName()

Please see updated attachment to the first post.

Details

Both abbreviated and full day name formats are included in the following languages:

Estonian, Danish, Dutch, English, Finnish, French, Greenlandic, Icelandic, German, Italian, Norwegian, Portuguese, Slovak, Spanish and Swedish.

This UDF only supports abbreviated day formats for Lithuanian and Hungarian.

Albanian has no abbreviated day format.

Comments

This UDF covers more than I am likely to use, and when I do finally get around to implementing it in a program, I will most likely create a slimmed down version to suit my personal needs. Extending this to include more languages will require Unicode and a lot more research. If anyone ever decides to add improvements, please post the code. :)

Link to comment
Share on other sites

  • 7 months later...

I just spent an hour stripping this out of a recent project. I said I would produce a decent example to demonstrate this UDF, so here it is. DateFormat Dialogue GUI. I'm not sure if I should include it in the UDF or not. It currently behaves as it does in my program, but the window could also return a value and close automatically. I prefer it as it is. It remembers settings stored in the array Misc. These values can be written to an ini file.

IMPORTANT The accel key F4 opens the Date Dialogue window

#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiEdit.au3>
#include <GUIComboBox.au3>
#include <ButtonConstants.au3>
#include <DateFormat.au3>

_DateDialogue_Example()

Func _DateDialogue_Example()
    Local $aMisc[7] ; Default date parameters
    $aMisc[0] = 0 ; DateFormat UDF 2nd param - Format
    $aMisc[1] = 1 ; DateFormat UDF 3rd param - Delimiters
    $aMisc[2] = 0 ; DateFormat UDF 4th param - Flag
    $aMisc[3] = "EN" ; DateFormat UDF 5th param - Language
    $aMisc[4] = 0 ; Day Name... 0 = exclude , 1 = prefix, 2 = abbreviate
    $aMisc[5] = True ; Append Time
    $aMisc[6] = False ; Previous Date... Default = Today

    Local $hGUI = GUICreate("Date Time Example", 600, 400, Default, Default, BitOR($WS_OVERLAPPEDWINDOW, $WS_EX_COMPOSITED))

    Local $hEdit1 = GUICtrlCreateEdit("Press the F4 key", 0, 0, 600, 400, Default, $WS_EX_LAYERED)
    GUICtrlSetFont($hEdit1, 12, 400, 0, "Courier New")

    Local $hDummy = GUICtrlCreateDummy()
    Local $AccelKeys[1][2] = [["{F4}", $hDummy]]
    GUISetAccelerators($AccelKeys)

    GUISetState(@SW_SHOW)

    While 1
        $msg = GUIGetMsg(1)
        Switch $msg[0]
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $hDummy ; Date / Time
                _DateDialogue($hGUI, $hEdit1, $aMisc)
        EndSwitch
    WEnd
EndFunc ;==>_DateDialogue_Example


Func _DateDialogue($hGUI, $hEdit, ByRef $aMisc)
    Local $aDateLang[19][2] = _
    [["Albanian","AL"],["Danish","DK"],["Dutch","NL"],["English","EN"], _
    ["Estonian","EE"],["Finnish","FI"],["French","FR"],["German","DE"], _
    ["Greenlandic","GL"],["Hungarian","HU"],["Icelandic","IS"],["Italian","IT"], _
    ["Lithuanian","LT"],["Norwegian","NO"],["Portuguese","PT"],["Slovak","SK"], _
    ["Spanish","ES"],["Swedish","SE"]]

    $hChild = GUICreate("Date / Time", 452, 254, Default, Default, BitOR($WS_CAPTION, $WS_POPUP, $WS_SYSMENU), $WS_EX_TOPMOST, $hGUI)

    $hDate = GUICtrlCreateMonthCal($aMisc[6], 6, 8, 180, 161)

    $hCombo = GUICtrlCreateCombo("Albanian",322, 5, 120, 19)
    GUICtrlSetFont(-1, 9)
    For $i = 1 To 17
        _GUICtrlComboBox_AddString($hCombo, $aDateLang[$i][0])
    Next
    For $i = 0 To 17
        If $aDateLang[$i][1] = $aMisc[3] Then ExitLoop
    Next
    If $i = 18 Then
        $i = 3
        $aMisc[3] = $aDateLang[$i][1]
    EndIf
    _GUICtrlComboBox_SetEditText($hCombo, $aDateLang[$i][0])

    GUICtrlCreateGroup(" Format ", 194, 29, 250, 141)
    GUIStartGroup($hChild)
    Local $aDateFormat[7][3]
    $aDateFormat[1][0] = GUICtrlCreateRadio(" y/m/d", 203, 47, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")
    $aDateFormat[1][1] = GUICtrlCreateRadio(" d/m/y", 285, 47, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")
    $aDateFormat[1][2] = GUICtrlCreateRadio(" m/d/y", 363, 47, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")

    $aDateFormat[2][0] = GUICtrlCreateRadio(" y-m-d", 203, 67, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")
    $aDateFormat[2][1] = GUICtrlCreateRadio(" d-m-y", 285, 67, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")
    $aDateFormat[2][2] = GUICtrlCreateRadio(" m-d-y", 363, 67, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")

    $aDateFormat[3][0] = GUICtrlCreateRadio(" y.m.d", 203, 87, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")
    $aDateFormat[3][1] = GUICtrlCreateRadio(" d.m.y", 285, 87, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")
    $aDateFormat[3][2] = GUICtrlCreateRadio(" m.d.y", 363, 87, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")

    $aDateFormat[4][0] = GUICtrlCreateRadio(" y m d", 203, 107, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")
    $aDateFormat[4][1] = GUICtrlCreateRadio(" d m y", 285, 107, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")
    $aDateFormat[4][2] = GUICtrlCreateRadio(" m d y", 363, 107, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")

    $aDateFormat[5][0] = GUICtrlCreateRadio(" y. m d.", 203, 127, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")
    $aDateFormat[5][1] = GUICtrlCreateRadio(" d-m.y", 285, 127, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")
    $aDateFormat[5][2] = GUICtrlCreateRadio(" m d, y", 363, 127, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")

    $aDateFormat[6][0] = GUICtrlCreateRadio(" y. m. d.", 203, 147, 72, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")
    $aDateFormat[6][1] = GUICtrlCreateRadio(" d. m y", 285, 147, 70, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")
    $aDateFormat[6][2] = GUICtrlCreateRadio(" m. d, y", 363, 147, 72, 18)
    GUICtrlSetFont(-1, 9, 400, 0, "Lucida Console")

    GUICtrlSetState($aDateFormat[$aMisc[1]][$aMisc[0]], $GUI_CHECKED)

    Local $ahControl[6]
    GUICtrlCreateGroup("", 6, 172, 339, 74)
    GUIStartGroup($hChild)
    $hDigits = GUICtrlCreateRadio(" Month Digits", 14, 183, 105, 18)
    $ahControl[2] = GUICtrlCreateRadio(" Month Name", 120, 183, 105, 18)
    $ahControl[5] = GUICtrlCreateRadio(" Roman Numerals", 235, 183, 106, 18)
    If BitAND($aMisc[2], 32) = 32 Then
        GUICtrlSetState($ahControl[5], $GUI_CHECKED)
    ElseIf BitAND($aMisc[2], 4) = 4 Then
        GUICtrlSetState($ahControl[2], $GUI_CHECKED)
    Else
        GUICtrlSetState($hDigits, $GUI_CHECKED)
    EndIf

    $ahControl[0] = GUICtrlCreateCheckbox(" Prefix Zeros", 14, 203, 105, 18)
    If BitAND($aMisc[2], 1) <> 1 Then GUICtrlSetState($ahControl[0], $GUI_CHECKED)
    $ahControl[3] = GUICtrlCreateCheckbox(" Abbreviate Month ", 120, 203, 105, 18)
    If BitAND($aMisc[2], 8) = 8 Then GUICtrlSetState($ahControl[3], $GUI_CHECKED)
    $ahControl[4] = GUICtrlCreateCheckbox(" Lower Case", 235, 203, 95, 18)
    If BitAND($aMisc[2], 16) = 16 Then GUICtrlSetState($ahControl[4], $GUI_CHECKED)

    $hDayName = GUICtrlCreateCheckbox(" Day Name", 14, 223, 105, 18)
    If BitAND($aMisc[4], 1) = 1 Then GUICtrlSetState($hDayName, $GUI_CHECKED)
    $hDayAbbr = GUICtrlCreateCheckbox(" Abbreviate Day", 120, 223, 105, 18)
    If BitAND($aMisc[4], 2) = 2 Then GUICtrlSetState($hDayAbbr, $GUI_CHECKED)
    $ahControl[1] = GUICtrlCreateCheckbox(" Two Digit Year", 235, 223, 95, 18)
    If BitAND($aMisc[2], 2) = 2 Then GUICtrlSetState($ahControl[1], $GUI_CHECKED)

    $hTime = GUICtrlCreateCheckbox(" Append Time", 356, 183, 95, 18)
    If $aMisc[5] Then GUICtrlSetState($hTime, $GUI_CHECKED)
    $hOkay = GUICtrlCreateButton("Ok", 355, 205, 89, 19, $BS_DEFPUSHBUTTON)
    $hClose = GUICtrlCreateButton("Close", 355, 228, 89, 19)

    Local $sDate, $sLang, $bLowerCase, $bDisableM = False, $bDisableD = False, $bDisableL = False

    GUISetState(@SW_SHOW)

    While 1
        If $bDisableM And BitAND(GUICtrlRead($ahControl[2]), $GUI_CHECKED) = $GUI_CHECKED Then
            GUICtrlSetState($ahControl[3], $GUI_ENABLE)
            $bDisableM = False
        ElseIf Not $bDisableM And BitAND(GUICtrlRead($ahControl[2]), $GUI_CHECKED) <> $GUI_CHECKED Then
            GUICtrlSetState($ahControl[3], $GUI_DISABLE)
            $bDisableM = True
        EndIf

        If $bDisableD And BitAND(GUICtrlRead($hDayName), $GUI_CHECKED) = $GUI_CHECKED Then
            GUICtrlSetState($hDayAbbr, $GUI_ENABLE)
            $bDisableD = False
        ElseIf Not $bDisableD And BitAND(GUICtrlRead($hDayName), $GUI_CHECKED) <> $GUI_CHECKED Then
            GUICtrlSetState($hDayAbbr, $GUI_DISABLE)
            $bDisableD = True
        EndIf

        If Not $bDisableL And $bDisableM And $bDisableD And BitAND(GUICtrlRead($ahControl[5]), $GUI_CHECKED) <> $GUI_CHECKED Then
            GUICtrlSetState($ahControl[4], $GUI_DISABLE)
            $bDisableL = True
        ElseIf $bDisableL And (Not $bDisableM Or Not $bDisableD Or BitAND(GUICtrlRead($ahControl[5]), $GUI_CHECKED) = $GUI_CHECKED) Then
            GUICtrlSetState($ahControl[4], $GUI_ENABLE)
            $bDisableL = False
        EndIf

        $msg2 = GUIGetMsg()
        Switch $msg2
            Case $hClose, $GUI_EVENT_CLOSE
                ExitLoop
            Case $hOkay
                For $i = 0 To 2
                    For $j = 1 To 6
                        If BitAND(GUICtrlRead($aDateFormat[$j][$i]), $GUI_CHECKED) = $GUI_CHECKED Then
                            $aMisc[0] = $i
                            $aMisc[1] = $j
                            ExitLoop 2
                        EndIf
                    Next
                Next

                If BitAND(GUICtrlRead($ahControl[0]), $GUI_CHECKED) <> $GUI_CHECKED Then
                    $aMisc[2] = BitOR($aMisc[2], 1)
                ElseIf BitAND($aMisc[2], 1) = 1 Then
                    $aMisc[2] = BitXOR($aMisc[2], 1)
                EndIf

                For $i = 1 To 5
                    If BitAND(GUICtrlRead($ahControl[$i]), $GUI_CHECKED) = $GUI_CHECKED Then
                        $aMisc[2] = BitOR($aMisc[2], 2^$i)
                    ElseIf BitAND($aMisc[2], 2^$i) = 2^$i Then
                        $aMisc[2] = BitXOR($aMisc[2], 2^$i)
                    EndIf
                Next

                If BitAND(GUICtrlRead($hDayName), $GUI_CHECKED) = $GUI_CHECKED Then
                    $aMisc[4] = BitOR($aMisc[4], 1)
                ElseIf BitAND($aMisc[4], 1) = 1 Then
                    $aMisc[4] = BitXOR($aMisc[4], 1)
                EndIf

                If BitAND(GUICtrlRead($hDayAbbr), $GUI_CHECKED) = $GUI_CHECKED Then
                    $aMisc[4] = BitOR($aMisc[4], 2)
                ElseIf BitAND($aMisc[4], 2) = 2 Then
                    $aMisc[4] = BitXOR($aMisc[4], 2)
                EndIf

                If BitAND(GUICtrlRead($hTime), $GUI_CHECKED) = $GUI_CHECKED Then
                    $aMisc[5] = True
                Else
                    $aMisc[5] = False
                EndIf

                If Not $bDisableD Or Not $bDisableM Then
                    $sLang = GUICtrlRead($hCombo)
                    For $i = 0 To 19
                        If $aDateLang[$i][0] = $sLang Then ExitLoop
                    Next
                    If $i < 20 Then
                        $aMisc[3] = $aDateLang[$i][1]
                    Else
                        MsgBox(BitOR(262144, 8240), " Error", 'Please choose a language' & @TAB)
                        ContinueLoop
                    EndIf
                EndIf

                $aMisc[6] = GUICtrlRead($hDate)
                $sDate = _ReadDate($aMisc[6], 0)

                $sReplacement = _DateSetFormat($sDate, $aMisc[0], $aMisc[1], $aMisc[2], $aMisc[3])

                If BitAND(GUICtrlRead($ahControl[4]), $GUI_CHECKED) = $GUI_CHECKED Then
                    $bLowerCase = True
                Else
                    $bLowerCase = False
                EndIf

                If $aMisc[4] = 1 Then
                    $sDay = _DayGetName($sDate, $aMisc[3], $bLowerCase)
                    If Not @error Then $sReplacement = $sDay & " " & $sReplacement
                ElseIf $aMisc[4] = 3 Then
                    $sDay = _DayGetName($sDate, $aMisc[3], $bLowerCase, True)
                    If Not @error Then $sReplacement = $sDay & " " & $sReplacement
                EndIf

                If $aMisc[5] Then
                    $sReplacement &= " " & @HOUR & ":" & @MIN & ":" & @SEC
                EndIf
                _GUICtrlEdit_ReplaceSel($hEdit, $sReplacement)
        EndSwitch
    WEnd

    GUIDelete($hChild)
EndFunc ;==>_DateDialogue
Edited by czardas
Link to comment
Share on other sites

I forgot to mention in my previous post, you need to download DateFormat.zip, attached to the first post, if you want to run the example above. I will be updating this along with several other UDFs in the near future. Do you think I should include this _DateDialogue function?

Edit

While the inclusion of this function would make the UDF much easier to use and more accessible, I have several other projects requiring urgent attention, so I may just simply leave it out. I don't exactly know how it should be adapted to suit more general purposes, as I mentioned previously - there are several possibilities. Perhaps it would be best as a settings panel, but I'm also using it as a floating toolbar. Notice it has the option to close instead of cancel. This is the main cause of my confusion.

Edited by czardas
Link to comment
Share on other sites

I have commented on your work before. It's starting to take shape, welcomed additions, but a few comments.

1) I seem to think you are painting yourself into a corner of too many "case" sentences, which is hard to debug and takes much time to write. I, in your place, would do a function read_longdayname($langid="EN") returning f.ex "Montag" for parameter "DE". All from a database source, be it text files or SQLite or whatever.

2) Your entire work with case strings etc actually can be replaced by API calls. This is REAL hardcore, but Windows DOES have API to do this. F.ex to specify what "Monday" is in Swahili, Arab, Chinese or any other language you may think of.

There is a guy that did some impressive forensics in this topic, you can read his source code here:

http://www.flounder.com/localeexplorer.htm

Not saying you HAVE to use this, it's just a more general solution. And since AutoIT sort of always has Windows in it's back (fundamentally a windows tool), these functions are always there.

Oh, and Windows can also parse the strings for you. So you could create something like "datestring("dd-mm-yyyy hh?nn#ss!zzz", "NL") for a date formattet in Dutch.

Just a few comments. But again: good work so far.

I am just a hobby programmer, and nothing great to publish right now.

Link to comment
Share on other sites

Hey Myicq, that's great, especially the link. I do like to explore things for myself to learn the fundamentals of programming. Much of the internal windows stuff is done for you, and I feel that I won't learn so much if I always rely on it. I agree that the UDF could be improved in several ways, although I plan on becoming more accustomed to working with unicode before I start thinking about people writing Swahili in my apps.

Anyway I'm grateful for both your responces. In all honesty, It may be a while before I can devote time to this. I have created an editor and this date dialogue is only one of over fifty currently working features (icing on the cake). I have left some of the more interesting bits to the end, and those are the parts I'm working on right now. :)

Edit

I will come back to this when time permits.

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...