我想要获得当月的第一天和最后一天。您可以添加日期和小时但不是月份,我想从下个月减去一天以获得本月的最后一天。像这样的东西:
package main
import (
"fmt"
"time"
)
func main() {
date := time.Now()
nextMonth := date.Add(time.Month)
LastDay := nextMonth.Add(-time.Hour * 24)
fmt.Println(LastDay)
}
你现在可以使用库,它非常简单:
now.BeginningOfMonth() // 2013-11-01 00:00:00 Fri
now.EndOfMonth() // 2013-11-30 23:59:59.999999999 Sat
请看这里详细信息:https://github.com/jinzhu/now
time.Month
是一种类型,而不是一个值,所以你不能Add
它。此外,你的逻辑是错误的,因为如果你添加一个月并减去一天,你没有到月底,你会在下个月中旬得到一些东西。如果今天是4月24日,你将获得5月23日。
以下代码将执行您正在寻找的内容:
package main
import (
"time"
"fmt"
)
func main() {
now := time.Now()
currentYear, currentMonth, _ := now.Date()
currentLocation := now.Location()
firstOfMonth := time.Date(currentYear, currentMonth, 1, 0, 0, 0, 0, currentLocation)
lastOfMonth := firstOfMonth.AddDate(0, 1, -1)
fmt.Println(firstOfMonth)
fmt.Println(lastOfMonth)
}
@Apin's answer是危险的,因为现在的lib会做出许多错误的假设(它也让我陷入困境)。 现在的lib不考虑夏令时和许多其他事情:https://github.com/jinzhu/now/issues/13
这就是我这样做的方式:
t := time.Now()
firstday := time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, time.Local)
lastday := firstday.AddDate(0, 1, 0).Add(time.Nanosecond * -1)
import "time"
func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
Date返回对应的Time
yyyy-mm-dd hh:mm:ss + nsec nanoseconds
在给定位置的那个时间的适当区域。
月,日,小时,分钟,秒和nsec值可能超出其通常范围,并将在转换期间进行标准化。例如,10月32日转换为11月1日。
夏令时转换会跳过或重复次数。例如,在美国,2011年3月13日凌晨2:15从未发生过,而2011年11月6日凌晨1点15分发生了两次。在这种情况下,时区的选择以及时间的选择并不明确。日期返回在转换中涉及的两个区域之一中正确的时间,但不保证哪个。
如果loc为nil,则日期会发生混乱。
超出其通常范围的月和日值将被标准化。例如,对于月份时间间隔的第一天和最后一天,
package main
import (
"fmt"
"os"
"time"
)
func monthInterval(t time.Time) (firstDay, lastDay time.Time) {
y, m, _ := t.Date()
loc := t.Location()
firstDay = time.Date(y, m, 1, 0, 0, 0, 0, loc)
lastDay = time.Date(y, m+1, 1, 0, 0, 0, -1, loc)
return firstDay, lastDay
}
func main() {
t := time.Now()
fmt.Println(t.Round(0))
first, last := monthInterval(t)
fmt.Println(first)
fmt.Println(last)
dstLoc, err := time.LoadLocation("America/Los_Angeles")
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
// Sunday, March 12, 2017, 2:00:00 am to Sunday, March 12, 2017, 3:00:00 am
dstStart := time.Date(2017, 03, 12, 2+1, 0, 0, 0, dstLoc)
// Sunday, November 5, 2017, 2:00:00 am to Sunday, November 5, 2017, 1:00:00 am
dstEnd := time.Date(2017, 11, 5, 2-1, 0, 0, 0, dstLoc)
t = dstStart
fmt.Println()
fmt.Println(t)
first, last = monthInterval(t)
fmt.Println(first)
fmt.Println(last)
t = dstEnd.Add(time.Hour)
fmt.Println()
fmt.Println(t)
first, last = monthInterval(t)
fmt.Println(first)
fmt.Println(last)
}
输出:
2017-10-27 05:45:08.197312082 -0400 EDT
2017-10-01 00:00:00 -0400 EDT
2017-10-31 23:59:59.999999999 -0400 EDT
2017-03-12 03:00:00 -0700 PDT
2017-03-01 00:00:00 -0800 PST
2017-03-31 23:59:59.999999999 -0700 PDT
2017-11-05 01:00:00 -0800 PST
2017-11-01 00:00:00 -0700 PDT
2017-11-30 23:59:59.999999999 -0800 PST
我会这样做:
// LastDayOfMonth returns 28-31 - the last day in the month of the time object
// passed in to the function
func LastDayOfMonth(t time.Time) int {
firstDay := time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, time.UTC)
lastDay := firstDay.AddDate(0, 1, 0).Add(-time.Nanosecond)
return lastDay.Day()
}
一个
不确定什么时候AddDate(...)
被添加到time.Time
,但很可能它是在这个问题有黄金时间之后添加的:)
这是与time.Time.AddDate(...)
实现相同的另一种方式 -
func BeginningOfMonth(date time.Time) (time.Time) {
return date.AddDate(0, 0, -date.Day() + 1)
}
func EndOfMonth(date time.Time) (time.Time) {
return date.AddDate(0, 1, -date.Day())
}
然后你可以使用today := time.Now()
并将其传递给一个/两个函数,如eom := EndOfMonth(today)
,以获得适当的日期。
如果时间,夏令时等很重要,那么在获得日期之后,将这些细节装饰在它上面应该非常简单。
最后,这是一个游乐场链接,你可以玩它 - https://play.golang.org/p/DxnGuqh6g4k
goutils提供了许多有用的功能工具。 goutils
beginningOfTMonth:=time.TimeBeginningOfMonth(t)
endOfTMonth:=time.TimeEndOfMonth(t)
beginningOfTWeek:=time.TimeBeginningOfWeek(t)
endOfTWeek:=time.TimeEndOfWeek(t)