Android Question Comparing 2 date time values in b4A and displaying date in dd-Mon-yyyy hh:mm AMPM format - reg.

beelze69

Active Member
Licensed User
Longtime User
Hi,

I have the following doubts with regard to handling date and time in b4A:

1) I have to perform the following validation:

If input Date=System Date then
the input time should not be within 1 hour from the system time
i.e. if the input date equals the system date and the current time is 11:30 am then the input time should
be greater than or equal to 12:30 pm...



For date comparison we can use the
DateTime.Date(lnginputDate)=DateTime.Date(lngsystemDate)
{Where lnginputDate=Datetime.DateParse(inputdate)
and lngSystemDate=Datetime.DateParse(DateTime.Now) }

For hour difference we can use

Dim PerDiff as Period
PerDiff=DateUtils.PeriodBetween(Datetime.DateParse(inputDate),DateTime.now)

Log("Difference in Minutes:" & Perdiff.Minutes)

However, I have my input date as a string in dd-mm-yyyy hh:mm format ,for example: 21-02-2022 11:10

And DateTime.DateFormat = "dd-MM-yyyy hh:mm" is not acceptable.

So how can we do the above comparison in such case ?

2) In SQLLITE (and via DateTime/DateUtils), how does one display the date 21-02-2022 21:05 as
as 21-Feb-2022 9:05 pm ?


Require some assistance on the above.

Thanks..
 
Last edited:

beelze69

Active Member
Licensed User
Longtime User
Please use [code]code here...[/code] tags when posting code.


Why not?
I am attaching some code which I have written in which I tried to use the dd-mm-yyyy hh:mm format but it gives me the Unparseable Date error..


B4X:
    Dim cs As CSBuilder
    Dim PerDiff As Period
    Dim constructedInputDateTime As String
    Dim dSelectedDate As Long
    Dim dSystemDate As Long
    DateTime.DateFormat = "dd-MM-yyyy hh:mm"
    'I have separate labels for storing the Date part and the time part and hence I am
    'concatenating them below
    constructedInputDateTime=lblDate.Text & " " &  lblHour.Text & ":" & lblMinute.Text
    dSelectedDate = DateTime.DateParse(constructedInputDateTime)
    dSystemDate = DateTime.Dateparse(  DateTime.Now)'
    Log("Your Selected Date is " & DateTime.Date(dSelectedDate) & " " & "Current Date is " & DateTime.Date(dSystemDate))
    If DateTime.Date(dSelectedDate) < DateTime.Date(dSystemDate) Then
     
        Dialog.Title = cs.Initialize.Size(20).Append("Message").PopAll
        Wait For (Dialog.Show( "Appointment Date cannot be before the System Date ..",  "Ok",  "", "")) Complete (unUsedReturnValue As Int)
     
    End If
    If DateTime.Date(dSelectedDate) = DateTime.Date(dSystemDate) Then
        Log("CURRENT DATE IS SELECTED")
        PerDiff=DateUtils.PeriodBetween(DateTime.DateParse(constructedInputDateTime),DateTime.Now)
        Log("Difference in days:" & PerDiff.Days)
        Log("Difference in Minutes:" & PerDiff.Minutes)
        Log("difference in seconds :" & PerDiff.Seconds)
    End If

I am getting the following error:

B4X:
Error occurred on line: 422 (pg1)
java.text.ParseException: Unparseable date: "21-02-2022 19:45"
    at java.text.DateFormat.parse(DateFormat.java:362)
    at anywheresoftware.b4a.keywords.DateTime.DateParse(DateTime.java:148)
    at b4a.example.pg1$ResumableSub_btnConfirmScheduling_Click.resume(pg1.java:590)
    at b4a.example.pg1._btnconfirmscheduling_click(pg1.java:538)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
    at anywheresoftware.b4a.BA$2.run(BA.java:387)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:201)
    at android.app.ActivityThread.main(ActivityThread.java:6823)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)

Also requesting for answer to the 2nd point viz.

2) In SQLLITE (and via DateTime/DateUtils), how does one display the date 21-02-2022 21:05 as
as 21-Feb-2022 9:05 pm ?

Thanks..
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
As @Spavlyuk mentioned, if you store your date as ticks in the SQLite, you can use:
B4X:
DateTime.DateFormat = "dd-MM-yyyy HH:mm" 'for 24 hr format
If you want to use AM/PM format the format must be:
B4X:
DateTime.DateFormat = "dd-MM-yyyy hh:mm a"

2) In SQLLITE (and via DateTime/DateUtils), how does one display the date 21-02-2022 21:05 as
as 21-Feb-2022 9:05 pm ?

As for question#2: If you stored your date as ticks using the 24 hr format and you want to display your data like 21-Feb-2022 9:05 pm, you need to change your date format before displaying the information to this format:
B4X:
DateTime.DateFormat = "dd-MMM-yyyy hh:mm a"
 
Upvote 0

beelze69

Active Member
Licensed User
Longtime User
Using capital letters for parsing 24h formats.
B4X:
DateTime.DateFormat = "dd-MM-yyyy HH:mm"

You can find all the format options here: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
Hi !,

I modified the code accordingly... I also found an issue in the line dSystemDate = DateTime.Dateparse( DateTime.Now) on my above code and corrected it ..
Modified code is :

B4X:
Dim cs As CSBuilder
    Dim PerDiff As Period
    Dim constructedInputDateTime As String
    Dim constructedSystemDateTime As String
    Dim dSelectedDate As Long
    Dim dSystemDate As Long
    DateTime.DateFormat = "dd-MM-yyyy HH:mm"
    Log("Current Date and Time from vide click button is :")
    Log(DateTime.Date( DateTime.Now))
    constructedInputDateTime=lblDate.Text & " " &  lblHour.Text & ":" & lblMinute.Text
    dSelectedDate = DateTime.DateParse( constructedInputDateTime)
    constructedSystemDateTime=DateTime.Date( DateTime.Now)
    dSystemDate = DateTime.DateParse(  constructedSystemDateTime)
    Log("Your Selected Date is " & DateTime.Date( dSelectedDate) & " " & "Current Date is " & DateTime.Date(dSystemDate))
    If DateTime.Date(dSelectedDate) < DateTime.Date(dSystemDate) Then
       
        Dialog.Title = cs.Initialize.Size(20).Append("Message").PopAll
        Wait For (Dialog.Show( "Appointment Date cannot be before the System Date ..",  "Ok",  "", "")) Complete (unUsedReturnValue As Int)
       
    End If
    If DateTime.Date(dSelectedDate) = DateTime.Date(dSystemDate) Then
        Log("CURRENT DATE IS SELECTED")
        PerDiff=DateUtils.PeriodBetween(DateTime.DateParse(constructedInputDateTime),DateTime.Now)
        Log("Difference in days:" & PerDiff.Days)
        Log("Difference in Minutes:" & PerDiff.Minutes)
        Log("difference in seconds :" & PerDiff.Seconds)
    End If

However, I am now getting the following error:
B4X:
Error occurred on line: 429 (pg1)

java.lang.NumberFormatException: For input string: "21-02-2022 11:50"

    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)

    at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)

    at java.lang.Double.parseDouble(Double.java:538)

    at b4a.example.pg1$ResumableSub_btnConfirmScheduling_Click.resume(pg1.java:617)

    at b4a.example.pg1._btnconfirmscheduling_click(pg1.java:538)

    at java.lang.reflect.Method.invoke(Native Method)

    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)

    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)

    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)

    at java.lang.reflect.Method.invoke(Native Method)

    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)

    at anywheresoftware.b4a.BA$2.run(BA.java:387)

    at android.os.Handler.handleCallback(Handler.java:873)

    at android.os.Handler.dispatchMessage(Handler.java:99)

    at android.os.Looper.loop(Looper.java:201)

    at android.app.ActivityThread.main(ActivityThread.java:6823)

    at java.lang.reflect.Method.invoke(Native Method)

    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)

    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)


Requesting for help...

Thanks..
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
When you compare dates, do not compare the string dates. You can parse the string date, but compare dates in ticks. For instance:
instead of:
B4X:
If DateTime.Date(dSelectedDate) < DateTime.Date(dSystemDate) Then
You should use:
B4X:
If dSelectedDate < dSystemDate Then
The same applies if you are comparing any additional dates in your code.
You may also want to log the hours in the latter part of your code: You are logging days, minutes but not hours
 
Upvote 0

beelze69

Active Member
Licensed User
Longtime User
When you compare dates, do not compare the string dates. You can parse the string date, but compare dates in ticks. For instance:
instead of:
B4X:
If DateTime.Date(dSelectedDate) < DateTime.Date(dSystemDate) Then
You should use:
B4X:
If dSelectedDate < dSystemDate Then
The same applies if you are comparing any additional dates in your code.
You may also want to log the hours in the latter part of your code: You are logging days, minutes but not hours
 
Last edited:
Upvote 0

Mahares

Expert
Licensed User
Longtime User
. Hence I am comparing only the Date part of the ticks values with
DateTime.Date(dSelectedDate) and DateTime.Date(dSystemDate)
No. Those dates are a combination of date and time because your Dateformat is:DateTime.DateFormat = "dd-MM-yyyy HH:mm"
Look at the diffeence between these two below formats:
B4X:
DateTime.DateFormat = "dd-MM-yyyy"
    DateTime.TimeFormat = "HH:mm"
    Log(DateTime.Date(DateTime.Now))    '21-02-2022
    Log(DateTime.time(DateTime.Now))

B4X:
 DateTime.DateFormat = "dd-MM-yyyy HH:mm"
    Log(DateTime.Date(DateTime.Now))  '21-02-2022 20:09
    Log(DateTime.time(DateTime.Now))
If you are still: 'Requesting for help..' , you are better off put a little project together and upload it.
 
Upvote 0

beelze69

Active Member
Licensed User
Longtime User
Hi Mahares,

Thanks a lot for the guidance.

I think I have resolved it, albeit in a very crude way.

For one, I am changing the date format to include and exclude the time components and storing the appropriate string values extracted via DateParse into different variables.

Then I store the ticks values of all these string variables into corr. long variables.

Then I do the comparison using only the ticks as you suggested..

Wondering, if there is a better way to do this..

Please see below code:

B4X:
Dim cs As CSBuilder
    Dim PerDiff As Period
    Dim constructedInputDate As String
    Dim constructedSystemDate As String
    Dim constructedInputDateTime As String
    Dim constructedSystemDateTime As String
    Dim dSelectedDate As Long
    Dim dSelectedDateWithTime As Long
    Dim dSystemDate As Long
    Dim dSystemDateWithTime As Long
    DateTime.DateFormat = "dd-MM-yyyy HH:mm"
    Log( DateTime.Date(DateTime.Now))
    constructedInputDateTime=lblDate.Text & " " &  lblHour.Text & ":" & lblMinute.Text
    dSelectedDateWithTime = DateTime.DateParse(constructedInputDateTime)
    constructedSystemDateTime=DateTime.Date(DateTime.Now)
    dSystemDateWithTime = DateTime.DateParse(  constructedSystemDateTime)
    Log("Your Selected Date is " & DateTime.Date(dSelectedDateWithTime) & " " & "Current Date is " & DateTime.Date(dSystemDateWithTime))
    'now string only the date part into corr. string variables..
    constructedInputDate=lblDate.Text
    DateTime.DateFormat="dd-MM-yyyy"
    constructedSystemDate=DateTime.Date(DateTime.Now)
    'now store the ticks value of only the Date Part into corr long variables before you compare
    dSelectedDate=DateTime.DateParse(constructedInputDate)
    dSystemDate=DateTime.DateParse(constructedSystemDate)
    If  dSelectedDate < dSystemDate Then
     
        Dialog.Title = cs.Initialize.Size(20).Append("Message").PopAll
        Wait For (Dialog.Show( "Appointment Date cannot be before the System Date ..",  "Ok",  "", "")) Complete (unUsedReturnValue As Int)
     
    End If
    If dSelectedDate = dSystemDate Then
        Log("CURRENT DATE IS SELECTED")
        PerDiff=DateUtils.PeriodBetweenindays(dSystemDateWithTime,dSelectedDateWithTime)
 
        Log("Difference in days:" & PerDiff.Days)
        Log("Difference in Hours:" & PerDiff.Hours)
        Log("Difference in Minutes:" & PerDiff.Minutes)
        Log("difference in seconds :" & PerDiff.Seconds)
     
    End If
 
Last edited:
Upvote 0

beelze69

Active Member
Licensed User
Longtime User
Please use [code]code here...[/code] tags when posting code.


Why not?
Hi Erel,

Thanks.. I have posted my final code post chat with Mahares...
Please guide on any better way to do this (rather than changing the DateFormat everytime, extracting out the Ticks Part via DateParse and then doing the comparison of the Ticks - the way I have done)..

Thanks...
 
Upvote 0

AnandGupta

Expert
Licensed User
Longtime User
Hi @beelze69

If you want (but not needed) to compare date (only date) in string, then use format
B4X:
       DateTime.DateFormat = "yyyyMMdd"
This way dates will be correctly sorted for comparision. We do it in Xbase++/Clipper as there is no ticks support here.
 
Upvote 0

beelze69

Active Member
Licensed User
Longtime User
Hi @beelze69

If you want (but not needed) to compare date (only date) in string, then use format
B4X:
       DateTime.DateFormat = "yyyyMMdd"
This way dates will be correctly sorted for comparision. We do it in Xbase++/Clipper as there is no ticks support here.
Wow !

You still use Clipper ? ... Wonderful Programming Language.. But I never really got to use it fully... Was totally into Foxpro ... The Foxpro guys gave one Compiler to create standalone exe but it was WAY TOO BULKY...

I tried Clipper way back in the 90s (under DOS environment) [before Windows 3.1]...

Thanks for that info.. on Date format.. .. Will try it out...
 
Upvote 0

AnandGupta

Expert
Licensed User
Longtime User
Wow !

You still use Clipper ? ... Wonderful Programming Language.. But I never really got to use it fully... Was totally into Foxpro ... The Foxpro guys gave one Compiler to create standalone exe but it was WAY TOO BULKY...

I tried Clipper way back in the 90s (under DOS environment) [before Windows 3.1]...

Thanks for that info.. on Date format.. .. Will try it out...

Well I learnt Basic (Original) , Fortran and Cobol. Then worked on BasicA, GWBasic, dBase II, dBase III+, FoxBase, FoxPro, Clipper 87, Clipper 5, Xbase++, VB.Net and now Java and B4X. For network I worked on Novell Netware and Ms Client/Server. Also had some hands on Linux but very little, as all our clients used Windows and we had to make products for them.

In nearly all languages I worked, I made complete application products which were sold by our company.
 
Upvote 0

beelze69

Active Member
Licensed User
Longtime User
Well I learnt Basic (Original) , Fortran and Cobol. Then worked on BasicA, GWBasic, dBase II, dBase III+, FoxBase, FoxPro, Clipper 87, Clipper 5, Xbase++, VB.Net and now Java and B4X. For network I worked on Novell Netware and Ms Client/Server. Also had some hands on Linux but very little, as all our clients used Windows and we had to make products for them.

In nearly all languages I worked, I made complete application products which were sold by our company.
That's great..

Is Clipper still used ? I mean.. now that DOS is gone... You have Clipper apps still running ?
To carry Anand's post further, you can actuall use yyyy-MM-dd or yyyy/MM/dd or yyyy.MM.dd. It looks like a real date and you can still sort by it, especially if you are using it in a SQL query.
Thanks .. will try it out...
 
Upvote 0
Top