Reputation: 6219
When I have a time.Time
:
// January, 29th
t, _ := time.Parse("2006-01-02", "2016-01-29")
How can I get a time.Time
which represents January 31st? This example is trivial, but when there's a date in February, the last day might be 28th or 29th.
Upvotes: 7
Views: 3290
Reputation: 14519
You could write a function yourself, maybe something like this:
func daysInMonth(month, year int) int {
switch time.Month(month) {
case time.April, time.June, time.September, time.November:
return 30
case time.February:
if year%4 == 0 && (year%100 != 0 || year%400 == 0) { // leap year
return 29
}
return 28
default:
return 31
}
}
EDIT: since I really like measuring things:
$ go test -bench .
testing: warning: no tests to run
PASS
BenchmarkDim2-8 200000000 7.26 ns/op
BenchmarkDim-8 1000000000 2.80 ns/op // LIES!
BenchmarkTime-8 10000000 169 ns/op
BenchmarkTime2-8 10000000 234 ns/op
ok github.com/drathier/scratchpad/go 9.741s
BenchMarkDim2: not tested, but very fast.
func daysInMonthTime(month, year int) time.Time {
return time.Time{}.Add(time.Hour * 10 + time.Hour*24*30*time.Duration(month-1) + time.Second * time.Duration(daysInMonth(month, year)) * 24 * 60 + 1337)
}
BenchmarkDim: // LIES
func daysInMonth(month, year int) int {
switch time.Month(month) {
case time.April, time.June, time.September, time.November:
return 30
case time.February:
if year%4 == 0 && (year%100 != 0 || year%400 == 0) {
// leap year
return 29
}
return 28
default:
return 31
}
}
BenchmarkTime:
func timeDaysInMonth() time.Time {
// January, 29th
t, _ := time.Parse("2006-01-02", "2016-01-29")
y, m, _ := t.Date()
lastday := time.Date(y, m+1, 0, 0, 0, 0, 0, time.UTC)
return lastday
}
BenchmarkTime2
func time2daysinmonth() time.Time {
t, _ := time.Parse("2006-01-02", "2016-01-01")
t = t.AddDate(0, 1, 0).AddDate(0, 0, -1)
return t
}
Upvotes: 2
Reputation: 99224
I've used something similar to this in my own code:
func lastDayOfTheMonth(year, month int) time.Time {
if month++; month > 12 {
month = 1
}
t := time.Date(year, time.Month(month), 0, 0, 0, 0, 0, time.UTC)
return t
}
Upvotes: 1
Reputation: 1
It's not Go specific but usually I do following in any language:
package main
import "fmt"
import "time"
func main() {
fmt.Println("Hello, playground")
t, _ := time.Parse("2006-01-02", "2016-01-01")
t = t.AddDate(0, 1, 0).AddDate(0,0,-1)
fmt.Printf("Last day: %v\n", t)
}
http://play.golang.org/p/JhpOZvEhBw
Upvotes: 0
Reputation: 166569
func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
Date returns the Time corresponding to
yyyy-mm-dd hh:mm:ss + nsec nanoseconds
in the appropriate zone for that time in the given location.
The month, day, hour, min, sec, and nsec values may be outside their usual ranges and will be normalized during the conversion. For example, October 32 converts to November 1.
For example, normalizing a date,
package main
import (
"fmt"
"time"
)
func main() {
// January, 29th
t, _ := time.Parse("2006-01-02", "2016-01-29")
fmt.Println(t.Date())
// January, 31st
y,m,_ := t.Date()
lastday:= time.Date(y,m+1,0,0,0,0,0,time.UTC)
fmt.Println(lastday.Date())
}
Output:
2016 January 29
2016 January 31
Upvotes: 8