Calculate first day of last month

Just starting out? Need help? Post your questions and find answers here.
BarryG
Addict
Addict
Posts: 4173
Joined: Thu Apr 18, 2019 8:17 am

Calculate first day of last month

Post 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
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Calculate first day of last month

Post 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)
Egypt my love
normeus
Enthusiast
Enthusiast
Posts: 472
Joined: Fri Apr 20, 2012 8:09 pm
Contact:

Re: Calculate first day of last month

Post 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
google Translate;Makes my jokes fall flat- Fait mes blagues tombent à plat- Machte meine Witze verpuffen- Eh cumpari ci vo sunari
BarryG
Addict
Addict
Posts: 4173
Joined: Thu Apr 18, 2019 8:17 am

Re: Calculate first day of last month

Post 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.
normeus
Enthusiast
Enthusiast
Posts: 472
Joined: Fri Apr 20, 2012 8:09 pm
Contact:

Re: Calculate first day of last month

Post 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.
google Translate;Makes my jokes fall flat- Fait mes blagues tombent à plat- Machte meine Witze verpuffen- Eh cumpari ci vo sunari
BarryG
Addict
Addict
Posts: 4173
Joined: Thu Apr 18, 2019 8:17 am

Re: Calculate first day of last month

Post 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).
normeus
Enthusiast
Enthusiast
Posts: 472
Joined: Fri Apr 20, 2012 8:09 pm
Contact:

Re: Calculate first day of last month

Post 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.
google Translate;Makes my jokes fall flat- Fait mes blagues tombent à plat- Machte meine Witze verpuffen- Eh cumpari ci vo sunari
User avatar
kenmo
Addict
Addict
Posts: 2043
Joined: Tue Dec 23, 2003 3:54 am

Re: Calculate first day of last month

Post 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
BarryG
Addict
Addict
Posts: 4173
Joined: Thu Apr 18, 2019 8:17 am

Re: Calculate first day of last month

Post 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!
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Calculate first day of last month

Post 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)
Egypt my love
BarryG
Addict
Addict
Posts: 4173
Joined: Thu Apr 18, 2019 8:17 am

Re: Calculate first day of last month

Post 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.
BarryG
Addict
Addict
Posts: 4173
Joined: Thu Apr 18, 2019 8:17 am

Re: Calculate first day of last month

Post 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!
User avatar
the.weavster
Addict
Addict
Posts: 1577
Joined: Thu Jul 03, 2003 6:53 pm
Location: England

Re: Calculate first day of last month

Post 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)
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Calculate first day of last month

Post 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)
Egypt my love
KianV
User
User
Posts: 16
Joined: Thu Dec 26, 2019 3:31 pm

Re: Calculate first day of last month

Post 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) 
Post Reply