Calculate first day of current month and last day of current month

As far as I can tell in Hugo there is no simple method (or multiple methods) to get the last Day of a given month, such as:

  • Jan → 31
  • Feb → 28/29
  • April → 30

In Javascript one can do this:

d = new Date(); d.setFullYear(2018, 01, 0);
//  Sun Jan 31 2018 ...

d.GetDate();
// 31

Does anyone have a func or trick to achieve this I am overlooking?

{{/* $ldocm = last day of current month */}}
{{ $ldocm := (time.AsTime (printf "%d-%02d-01" now.Year now.Month)).AddDate 0 1 -1 }}

This is much better:

{{/* $fdocm = first day of current month */}}
{{ $fdocm := now.AddDate 0 0 (add 1 (sub 0 now.Day) | int) }}

{{/* $ldocm = last day of current month */}}
{{ $ldocm := now.AddDate 0 1 (sub 0 now.Day | int) }}
1 Like

@jmooring thanks :slight_smile: so your approach relies on the now.Day method. Interesting. This did not work for my needs, but reminded me of the .AddDate method which feels a bit counter-intuitive but hey, it works powerfully :rofl:

In my case I needed to feed .AddDate a specific arbitrary date values in the past such as 2022-02-01 so here is what works for my use case:

{{ $d := "2022-02-01" | time.AsTime }}

{{ $d.AddDate 0 1 -1 | time.Format "2006-01-02" }}
// 2022-02-28

{{ $d.AddDate 0 1 -1 | time.Format "02" }}
// 28

I realize the way I worded this topic @jmooring answer is correct and thus is the Solution.

I haven’t looked at the details above, but I wanted to remind you of (perhaps) unexpected behavior when using the AddDate method on a time.Time value:

https://gohugo.io/methods/time/adddate/

When adding months or years, Hugo normalizes the final time.Time value if the resulting day does not exist. For example, adding one month to 31 January produces 2 March or 3 March, depending on the year.

See this explanation from the Go team.

Your example will fail with an arbitrary date that is not the first day of the month:

{{ $d := "2022-02-05" | time.AsTime }}
{{ $d.AddDate 0 1 -1 | time.Format "2006-01-02" }} --> 2022-03-04
{{ $d.AddDate 0 1 -1 | time.Format "02" }} --> 04

If you really need to use an arbitrary date, use my previous examples, substituting the now function with an arbitrary time.Time value:

{{ $d := time.AsTime "2022-02-05" }}

{{/* $fdocm = first day of current month */}}
{{ $fdocm := $d.AddDate 0 0 (add 1 (sub 0 $d.Day) | int) }} 

{{/* $ldocm = last day of current month */}}
{{ $ldocm := $d.AddDate 0 1 (sub 0 $d.Day | int) }}
1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.