获取Go / Golang当月的第一天和最后一天?

时间:2016-04-24 23:49:02

标签: date go time

我正试图获得当月的第一天和最后一天。您可以添加日期和小时但不是月份,我想从下个月减去一天以获得本月的最后一天。像这样:

package main

import (
    "fmt"
    "time"
)

func main() {

    date := time.Now()
    nextMonth := date.Add(time.Month)
    LastDay := nextMonth.Add(-time.Hour * 24)

    fmt.Println(LastDay)

}

8 个答案:

答案 0 :(得分:21)

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)
}

Playground link

答案 1 :(得分:9)

@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)

答案 2 :(得分:6)

您可以使用 now 库,这非常简单:

now.BeginningOfMonth()    // 2013-11-01 00:00:00 Fri
now.EndOfMonth()          // 2013-11-30 23:59:59.999999999 Sat

请详细了解https://github.com/jinzhu/now

答案 3 :(得分:4)

  

Package time

import "time" 
     

func Date

func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) 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为零,则日期会发生恐慌。

超出其通常范围的月和日值将被标准化。例如,对于月份时间间隔的第一天和最后一天,

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

答案 4 :(得分:2)

这也可以解决:

currentTimestamp := time.Now().UTC()
currentYear, currentMonth, _ := currentTimestamp.Date()
currentLocation := currentTimestamp.Location()

firstOfMonth := time.Date(currentYear, currentMonth, 1, 0, 0, 0, 0, currentLocation)
lastOfMonth := time.Date(currentYear, currentMonth+1, 0, 23, 59, 59, 999999999, currentLocation)

fmt.Println(firstOfMonth)
fmt.Println(lastOfMonth)

输出:

firstOfMonth: 2019-11-01 00:00:00 +0000 UTC
lastOfMonth: 2019-11-30 23:59:59.999999999 +0000 UTC

单击此处进行尝试: Playground Link

答案 5 :(得分:0)

goutils提供了许多有用的功能工具。 goutils

beginningOfTMonth:=goutils.TimeBeginningOfMonth(t)
endOfTMonth:=goutils.TimeEndOfMonth(t)


beginningOfTWeek:=goutils.TimeBeginningOfWeek(t)
endOfTWeek:=goutils.TimeEndOfWeek(t)

答案 6 :(得分:0)

我会这样做:

// 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()
}

答案 7 :(得分:0)

不确定何时将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)以获取适当的日期。

如果时间,夏令时(DST)等很重要,那么一旦获得日期,在这些细节上装饰这些细节应该非常简单。

最后,这是一个游乐场链接,您可以在其中玩耍-https://play.golang.org/p/DxnGuqh6g4k