Hi,
I`m trying to generate a list of dates for the last days of the month, to use in a query for grouping data by month (based on a long field). I tried this but its not giving the expected result:
B4X:
Sub build_dates
Dim dt(12) As Long
Dim tmp As Long
Dim p1 As Period
p1.Days = -1
DateTime.DateFormat = "dd/mm/yyyy"
For i = 1 To 12
If sf.Len(i) = 1 Then
tmp = DateTime.DateParse("01/0" & i & "/" & DateTime.GetYear(DateTime.Now))
Log("tmp = " & DateTime.Date(tmp))
dt(i) = DateUtils.AddPeriod(tmp, p1)
Log("dt(i) = " & DateTime.Date(dt(i)))
Else
tmp = DateTime.DateParse("01/" & i & "/" & DateTime.GetYear(DateTime.Now))
Log("tmp = " & DateTime.Date(tmp))
dt(i) = DateUtils.AddPeriod(tmp, p1)
Log("dt(i) = " & DateTime.Date(dt(i)))
End If
Next
End Sub
Sub GenerateMonthEnd
Dim yyyy As Int = DateTime.GetYear(DateTime.Now)
DateTime.DateFormat = "dd/MM/yyyy"
For mm = 1 To 12
Dim FirstDay As Long = DateUtils.SetDate(yyyy, mm, 1)
Log( DateTime.Date(FirstDay) )
Dim days As Int = DateUtils.NumberOfDaysInMonth(mm, yyyy)
Dim LastDay As Long = DateUtils.SetDate(yyyy, mm, days)
Log( DateTime.Date(LastDay) )
Next
End Sub
Here is another method without involving DateUtils lib:
B4X:
For i=1 To 12
Log(LastDayofMonth(i, 2023))
Next
B4X:
Sub LastDayofMonth(m As Int, y As Int) As String
DateTime.DateFormat = "dd/MM/yyyy"
Select m
Case 1, 3, 5,7,8,10,12
Return $"31/${m}/${y}"$
Case 4, 6, 9,11
Return $"30/${m}/${y}"$
Case Else
If y Mod 4 = 0 Then
Return $"29/${m}/${y}"$
Else
Return $"28/${m}/${y}"$
End If
End Select
End Sub
I usually just add 1 to the month and then subtract one day:
B4X:
Public Sub MonthEnd(Year As Int, Month As Int) As Long
DateTime.DateFormat = "MM/dd/yyyy"
Dim plDate As Long = DateTime.DateParse(Month & "/01/" & Year)
plDate = DateTime.Add(plDate, 0, 1, -1)
Return plDate
End Sub
And if you want another method that involves SQLite here it is:
B4X:
Sub DisplayLastDayOfMonthUsingSQLite(yr As Int)
For i=1 To 12
Dim s As String = IIf(i > 9, $"${yr}-${i}-01"$, $"${yr}-0${i}-01"$)
Log(SQL.ExecQuerySingleResult($"SELECT strftime('%m/%d/%Y', '${s}','start of month','+1 month','-1 day')"$))
Next
End Sub