Android Question Converting a string

Sergey_New

Well-Known Member
Licensed User
Longtime User
Please tell me how to convert the string "21/01/2020" to "01/21/2020".
I need this to get ticks from a date in "MM.dd.yyyy" format using DateTime.DateParse
 
Last edited:

Sergey_New

Well-Known Member
Licensed User
Longtime User
Not sure, maybe yes, maybe no. Never used AI for programming.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Not sure, maybe yes, maybe no. Never used AI for programming.
ChatGPT:

B4X:
' --- costruzione della regex a pezzi (B4X) ---
' qualificatori opzionali come ABT, AFT, FROM, TO, ecc.
Dim reQualifier As String = "(?:(?:ABT|AFT|BEF|BET|CAL|EST|FROM|TO))\s"
Dim reQualifierGroup As String = "(" & reQualifier & ")?" ' gruppo 1 - opzionale

' possibili formati di data:
Dim reDayMonthYear As String = "(?:\d{0,2}\s\D{3}\s\d{1,4})"   ' es. "12 MAR 1990"
Dim reDotDate       As String = "(?:\d{1,2}\.\d{1,2}\.\d{1,4})" ' es. "12.3.1990"
Dim reYear         As String = "\d{1,4}"                       ' es. "1990"

' unione dei formati di data (non-capturing internamente)
Dim reDate As String = "(?:" & reDayMonthYear & "|" & reDotDate & "|" & reYear & ")"

' separatore di intervallo (AND o TO) come gruppo opzionale
Dim reRangeSepGroup As String = "((?:AND|TO))?" ' gruppo 3 nella composizione finale

' seconda data opzionale (gruppo 4)
Dim secondDateGroup As String = "(" & reDate & ")?" ' gruppo 4 - opzionale

' composizione finale (corrisponde alla regex originale)
Dim patDate As String = reQualifierGroup & reDate & "\s?" & reRangeSepGroup & "\s?" & secondDateGroup

To test:
B4X:
Dim source As String = "FROM 12 MAR 1990 TO 1995"
Dim m As Matcher = Regex.Matcher(patDate, source)
If m.Find = True Then
    Log("Match completo: " & m.Group(0))
    Log("Qualifier (gr.1): " & m.Group(1))   ' es. "FROM "
    Log("Date1     (gr.2): " & m.Group(2))   ' es. "12 MAR 1990"
    Log("RangeSep  (gr.3): " & m.Group(3))   ' es. "TO"
    Log("Date2     (gr.4): " & m.Group(4))   ' es. "1995" (può essere null)
End If
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
Thanks, that's what I do.
B4X:
Sub date_parse(dates As String) As String(4)
    Dim m As Matcher = Regex.Matcher(patDate,dates)
    Dim pref1 As String
    Dim date1 As String
    Dim pref2 As String
    Dim date2 As String
    Do While m.Find
        pref1 = m.Group(1)
        date1 = m.Group(2)
        pref2 = m.Group(3)
        date2 = m.Group(4)
    Loop
    If pref1=Null Then
        pref1=""
    Else
        pref1=pref1.Trim
        pref1=Starter.loc.Localize(pref1)
    End If
    If pref2=Null Then
        pref2=""
    Else
        pref2=Starter.loc.Localize(pref2.Trim)
    End If
    If date1.Length>4 Then
        date1=ConvertDate(date1)
    End If
    If date2<>Null Then
        If date2.Length>4 Then
            date2=ConvertDate(date2)
        End If
    Else
        date2=""
    End If
    Return Array As String(pref1,date1,pref2,date2)
End Sub
The problem will be with the date "FROM MAR 12 1990 TO 1995"
We need to somehow supplement the pattern for the formats "MM.dd.yyyy", "MM/dd/yyyy", "MM-dd-yyyy", "yyyy/MM/dd", "yyyy-MM-dd"
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
We need to somehow supplement the pattern for the formats "MM.dd.yyyy", "MM/dd/yyyy", "MM-dd-yyyy", "yyyy/MM/dd", "yyyy-MM-dd"
We? ChatGPT 😄

Trying to ask it...

it provided two (equivalent) versions:
1.
B4X:
' formati già presenti
Dim reDayMonthYear As String = "(?:\d{0,2}\s\D{3}\s\d{1,4})"   ' es. "12 MAR 1990"
Dim reDotDate       As String = "(?:\d{1,2}\.\d{1,2}\.\d{1,4})" ' es. "12.3.1990"
Dim reYear          As String = "\d{1,4}"                       ' es. "1990"

' nuovi formati numerici
Dim reMM_DD_YYYY_Dot As String = "(?:\d{1,2}\.\d{1,2}\.\d{4})"
Dim reMM_DD_YYYY_Slash As String = "(?:\d{1,2}/\d{1,2}/\d{4})"
Dim reMM_DD_YYYY_Dash As String = "(?:\d{1,2}-\d{1,2}-\d{4})"
Dim reYYYY_MM_DD_Slash As String = "(?:\d{4}/\d{1,2}/\d{1,2})"
Dim reYYYY_MM_DD_Dash As String = "(?:\d{4}-\d{1,2}-\d{1,2})"

' unione di tutti i formati
Dim reDate As String = "(?:" & reDayMonthYear & "|" & reDotDate & "|" & reYear & "|" & reMM_DD_YYYY_Dot & "|" & reMM_DD_YYYY_Slash & "|" & reMM_DD_YYYY_Dash & "|" & reYYYY_MM_DD_Slash & "|" & reYYYY_MM_DD_Dash & ")"

2.
B4X:
' --- costruzione regex aggiornata ---
Dim reQualifier As String = "(?:(?:ABT|AFT|BEF|BET|CAL|EST|FROM|TO))\s"
Dim reQualifierGroup As String = "(" & reQualifier & ")?"

' formati di data supportati
Dim reDayMonthYear As String = "(?:\d{0,2}\s\D{3}\s\d{1,4})"   ' es. 12 MAR 1990
Dim reDotDate      As String = "(?:\d{1,2}\.\d{1,2}\.\d{1,4})" ' es. 12.03.1990
Dim reSlashDate    As String = "(?:\d{1,2}/\d{1,2}/\d{1,4})"   ' es. 12/03/1990
Dim reDashDate     As String = "(?:\d{1,2}-\d{1,2}-\d{1,4})"   ' es. 12-03-1990
Dim reYearFirstSlash As String = "(?:\d{4}/\d{1,2}/\d{1,2})"   ' es. 1990/03/12
Dim reYearFirstDash  As String = "(?:\d{4}-\d{1,2}-\d{1,2})"   ' es. 1990-03-12
Dim reYear         As String = "\d{1,4}"                       ' es. 1990

' unione dei formati in un'unica regex
Dim reDate As String = "(?:" & reDayMonthYear & "|" & reDotDate & "|" & reSlashDate & "|" & reDashDate & "|" & reYearFirstSlash & "|" & reYearFirstDash & "|" & reYear & ")"

' separatore AND|TO
Dim reRangeSepGroup As String = "((?:AND|TO))?"

' seconda data opzionale
Dim secondDateGroup As String = "(" & reDate & ")?"

' regex finale
Dim patDate As String = reQualifierGroup & reDate & "\s?" & reRangeSepGroup & "\s?" & secondDateGroup
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
Both options do not work.
Example attached.
 

Attachments

  • test.zip
    3.8 KB · Views: 26
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
I don't have access to these links, and I don't know how to ask AI questions about programming. :(
It's not hard!

Ask in your language:

Translate the following code into B4X code:

Dim patDate As String="((?:(?:ABT|AFT|BEF|BET|CAL|EST|FROM|TO))\s)?((?:\d{0,2}\s\D{3}\s\d{1,4})|(?:\d{1,2}\.\d{1,2}\.\d{1,4})|\d{1,4})\s?((?:AND|TO))?\s?((?:\d{0,2}\s\D{3}\s\d{1,4})|(?:\d{1,2}\.\d{1,2}\.\d{1,4})|\d{1,4})?"
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
But how to ask a question?
Exactly so:

1757344346510.png


https://www.b4x.com/android/forum/threads/converting-a-string.168560/post-1033221

or, better:

"Переведите следующий код в код B4X:"
B4X:
Dim patDate As String="((?:(?:ABT|AFT|BEF|BET|CAL|EST|FROM|TO))\s)?((?:\d{0,2}\s\D{3}\s\d{1,4})|(?:\d{1,2}\.\d{1,2}\.\d{1,4})|\d{1,4})\s?((?:AND|TO))?\s?((?:\d{0,2}\s\D{3}\s\d{1,4})|(?:\d{1,2}\.\d{1,2}\.\d{1,4})|\d{1,4})?"
 
Upvote 0

emexes

Expert
Licensed User
Longtime User
I feel like this could be a useful part of the regex pattern:

Perl:
(\d{1,2}|\d{4}|[a-zA-Z]{3})

and also that regex is going to become more and more unwieldy as you try to cover more and more variations, so that eventually you're going to end up using a B4X Sub to parse it, especially if you are also to handle from-to- date ranges.

Are these dates coming from user input, or from a file?

Also what are the prefixes "cal" and "est"?

Is "cal" for "calendar", or for "calculate"?

The "est" reminds me of a book catalogue assignment at uni that needed to be able to represent approximate dates as well as actual dates.

With the prefixes, I'd be moving towards the VAX VMS CLI approach of recognising the minimum unique start of keywords, eg for the prefix "before" you'd also recognise "bef", "befo", "befor" and "before", and "after" would recognise "aft", "afte" and "after".

Same with the mmm representation for months - I have a vague recollection that some date formatting routines expect/emit "july" (not "jul") for July. And not that you're interpreting day-of-week (yet) but I have often seen Tuesday shortened to "tues" and less-often Thursday shortened to "thurs".

It's nice to have the shortened versions but it's also nice to let the user just type the whole prefix instead of having to remember the short versions.

Especially for "abt" which is not the first 3 letters of "about". "abt" is a good shortening, but it's one more thing to remember.
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
Longtime User
Maybe this might spark some new parsing ideas too:

B4X:
Dim TestDate() As String = Array As String( _
    "from 1st July 2020 to 09-09-25", _
    "August 1st, 1291", _
    "09/09/2025" _
)

For Each TD As String In TestDate
    Dim DateElement() As String = Regex.Split("[^\w]+", TD)    'splits string into alphanumeric-plus-underscore words - use [^0-9A-Za-z] if underscores are a problem
  
    Log(TD)
    For Each E As String In DateElement
        Log(TAB & E & TAB & Regex.Replace("[^0-9]", E, ""))
    Next
Next
Log output:
from 1st July 2020 to 09-09-25
    from 
    1st     1
    July 
    2020    2020
    to 
    09      09
    09      09
    25      25
August 1st, 1291
    August 
    1st     1
    1291    1291
09/09/2025
    09      09
    09      09
    2025    2025
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
Longtime User
To handle " to " date ranges, maybe:

B4X:
Dim TestDate() As String = Array As String( _
    "from 1st July 2020 to 09-09-25", _
    "August 1st, 1291", _
    "09/09/2025" _
)

For Each TD As String In TestDate
    Dim DateElement() As String = Regex.Split("[^\w]+", TD)
    
    Log(TD)
    
    Dim DateRange() As String = Regex.Split("\s+[Tt][Oo]\s+", TD)
    For Each D As String In DateRange
        Log(TAB & D)
    Next
Next
Log output:
from 1st July 2020 to 09-09-25
    from 1st July 2020
    09-09-25
August 1st, 1291
    August 1st, 1291
09/09/2025
    09/09/2025
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
Also what are the prefixes
Prefixes are taken from the data file and cannot be changed.
This is their purpose:
ABT = About, meaning the date is not exact.
CAL = Calculated mathematically, for example, from an event date and age.
EST = Estimated based on an algorithm using some other event date.
AFT = Event happened after the given date.
BEF = Event happened before the given date.
BET = Event happened some time between date 1 AND date 2.
FROM = Indicates the beginning of a happening or state.
TO = Indicates the ending of a happening or state.
AND = Indicates that an event took place at some time between two dates.
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
Maybe this might spark some new parsing ideas too
Thank you!
I have already written above that my pattern copes well with parsing dates, except for individual date formats.
Since the code is large, I will try to extract the necessary code from the program and create a small example. It needs to add changes for date formats that cannot be processed yet.
 
Upvote 0
Top