Page 1 of 2

Calculate first day of last month

Posted: Sun Oct 03, 2021 1:02 pm
by BarryG
I'm hopeless with date calculations, but I've come up with the below. All I want to do is know what the date is for the first day of the previous month.

Surely there is a much better and more efficient way to calculate this than with the 2 x ugly AddDate() commands below? LOL!

Code: Select all

Procedure.q FirstDayOfLastMonth()
  d=Date(2022,1,15,0,0,0) ; Test with 15 Jan 2022 because we want 1 Dec 2021 returned.
  ;d=Date()
  f.q=AddDate(d,#PB_Date_Month,-1) ; Go back one month.
  f=AddDate(f,#PB_Date_Day,-(Day(f)-1)) ; And set the day to the 1st.
  ProcedureReturn f
EndProcedure

d=FirstDayOfLastMonth()
Debug FormatDate("%dd/%mm/%yyyy",d) ; 1 Dec 2021

Re: Calculate first day of last month

Posted: Sun Oct 03, 2021 1:46 pm
by RASHAD
Hi BarryG

Code: Select all

date = Date(2022,1,15,0,0,0)-(3600*45*24) ;15 day + 30 day
Debug FormatDate("%dd/%mm/%yyyy", date)

Re: Calculate first day of last month

Posted: Sun Oct 03, 2021 3:07 pm
by normeus
My naive attempt assuming all months begin with 01

Code: Select all

da=Date(2022,01,15,0,0,0)
d=AddDate(da,#PB_Date_Day,-Day(da)); get day number of month then delete it from month 
Debug FormatDate("01/%mm/%yyyy",d) ; 1 Dec 2021  hard code 01

Norm

Re: Calculate first day of last month

Posted: Mon Oct 04, 2021 1:35 am
by BarryG
Rashad, yours doesn't work with today's date:

Code: Select all

date = Date()-(3600*45*24) ; Today is 04/10/2021
Debug FormatDate("%dd/%mm/%yyyy", date) ; 20/08/2021 (wrong, should show 01/09/2021)
normeus, I need the actual new date value, not just a hard-coded "01" for display. The display was just to ensure the right date was being calculated.

Thanks to both of you for looking.

Re: Calculate first day of last month

Posted: Mon Oct 04, 2021 2:40 am
by normeus
BarryG:
just add one to the date number, remember the year limits with DATE() (1970..2038) in case you program lives another 17 years

Code: Select all

da=Date(2022,01,15,0,0,0)
d=AddDate(da,#PB_Date_Day,-Day(da))+1; get day number of month then delete it from month and add one day 
Debug FormatDate("%dd/%mm/%yyyy",d) ; 
Norm.

Re: Calculate first day of last month

Posted: Mon Oct 04, 2021 3:05 am
by BarryG
Norm, your calc doesn't work:

Code: Select all

da=Date(2022,01,15,0,0,0)
d=AddDate(da,#PB_Date_Day,-Day(da))+1
Debug FormatDate("%dd/%mm/%yyyy",d) ; Incorrectly shows 31/12/2021 instead of 01/12/2021
It's not easy, eh? Might have to stick with my double-AddDate() solution.

Also, the year limit of 2038 is of no concern (I use the Date64 module).

Re: Calculate first day of last month

Posted: Mon Oct 04, 2021 3:35 am
by normeus
Sorry, I am having a difficult time with the day being before the month :P . It looks like your way is the best for now. here's the one I should've posted.

Code: Select all

da=Date(2022,03,15,0,0,0)
da=AddDate(da,#PB_Date_Month,-1)-((Day(da)-1)*86400)
Debug FormatDate("%dd/%mm/%yyyy",da) ; 

Norm.

Re: Calculate first day of last month

Posted: Mon Oct 04, 2021 4:39 am
by kenmo
If you can spare a few lines... isn't this an easy, understandable way to achieve it?

Code: Select all

Procedure.q FirstDayOfLastMonth()
  d=Date(2022,1,15,0,0,0) ; Test with 15 Jan 2022 because we want 1 Dec 2021 returned.
  ;d=Date()
  If Month(d) = 1 ; January
    f = Date(Year(d) - 1, 12, 1, 0, 0, 0)
  Else
    f = Date(Year(d), Month(d)-1, 1, 0, 0, 0)
  EndIf
  ProcedureReturn f
EndProcedure

d=FirstDayOfLastMonth()
Debug FormatDate("%dd/%mm/%yyyy",d) ; 1 Dec 2021

Re: Calculate first day of last month

Posted: Mon Oct 04, 2021 5:01 am
by BarryG
Kenmo, you legend! I didn't even think to hard-code the day and month like that. I was too hooked up on trying to find a calculation to do it. Thanks.

The only thing I changed was make "d" and "f" into quads, for dates past the year 2038 (I use the Date64 module). Other than that, perfect!

Re: Calculate first day of last month

Posted: Mon Oct 04, 2021 7:52 am
by RASHAD
Hi BarryG
You didn't get the idea
You can add plus or minus how many seconds to any date to get what you want
45 I used is to suit your provided example that is it
It is so simple
Only one line of code you need :)
Check tomorrow and the day after and you will get the right answer

Code: Select all

date = Date()-((Day(Date())+29)*24*3600)
Debug FormatDate("%dd/%mm/%yyyy", date)

Re: Calculate first day of last month

Posted: Mon Oct 04, 2021 8:32 am
by BarryG
Rashad, sorry, I don't understand. When any date in Jan 2022 arrives, your latest code will be wrong:

Code: Select all

d = Date(2022,1,15,0,0,0) ; Test with 15 Jan 2022 because we want 1 Dec 2021 returned.
date = d-((Day(d)+29)*24*3600)
Debug FormatDate("%dd/%mm/%yyyy", date) ; Returns 2 Dec 2021, which is wrong.
I don't think there's a one-size-fits-all calculation that can be done in one step.

Re: Calculate first day of last month

Posted: Mon Oct 04, 2021 9:32 am
by BarryG
normeus wrote: Mon Oct 04, 2021 3:35 amhere's the one I should've posted
It doesn't work:

Code: Select all

da=Date(2022,12,31,0,0,0) ; 31 Dec 2022, so we want 1 Nov 2022
da=AddDate(da,#PB_Date_Month,-1)-((Day(da)-1)*86400)
Debug FormatDate("%dd/%mm/%yyyy",da) ; Incorrectly shows 31 Oct 2022
Okay, I think I'll stick with my 2 x AddDate(), or maybe Kenmo's if speed tests show that it's faster.

Sorry for all the trouble!

Re: Calculate first day of last month

Posted: Mon Oct 04, 2021 12:44 pm
by the.weavster
@BarryG
I don't see much wrong with your original function. If you want it as a one-liner just nest the two steps:

Code: Select all

Procedure.q FirstDayOfLastMonth(d.q)
  ProcedureReturn AddDate(AddDate(d, #PB_Date_Month, -1), #PB_Date_Day, -(Day(d)-1))
EndProcedure

; Test With 15 Jan 2022 because we want 1 Dec 2021 returned.
d = FirstDayOfLastMonth(Date(2022,1,15,0,0,0))
Debug FormatDate("%dd/%mm/%yyyy", d)

; Test with today
d = FirstDayOfLastMonth(Date())
Debug FormatDate("%dd/%mm/%yyyy", d)

Re: Calculate first day of last month

Posted: Mon Oct 04, 2021 1:12 pm
by RASHAD

Code: Select all

d = Date(2023,1,15,0,0,0)
date = d-((Day(d)+25)*24*3600)
Repeat
  date = date - 24*3600
Until Day(date) = 1
Debug FormatDate("%dd/%mm/%yyyy", date)

Re: Calculate first day of last month

Posted: Mon Oct 04, 2021 1:36 pm
by KianV
This should do the trick.

Code: Select all

d = Date(2022,1,15,0,0,0) ; Test with 15 Jan 2022 because we want 1 Dec 2021 returned.
date=Date(Year(d)-Bool(Month(d)=1),Month(d)-1+(12*Bool(Month(d)=1)),1,0,0,0)
Debug FormatDate("%dd/%mm/%yyyy", date)