Get the first and last day of current month in Go/Golang?

huangapple go评论111阅读模式
英文:

Get the first and last day of current month in Go/Golang?

问题

我正在尝试获取当前月份的第一天和最后一天。您可以添加天数和小时数,但不能添加月份,我想通过从下个月减去一天来获取本月的最后一天。类似这样的代码:

package main

import (
	"fmt"
	"time"
)

func main() {

	date := time.Now()
	nextMonth := date.AddDate(0, 1, 0)
	lastDay := nextMonth.AddDate(0, 0, -1)

	fmt.Println(lastDay)

}

这段代码将打印出本月的最后一天。

英文:

I'm trying to get the first and last day of the current month. You can add days and hours but not the month, which I was thinking of subtracting one day from the next month to get the last day of this month. Something like this:

package main

import (
	"fmt"
	"time"
)

func main() {

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

	fmt.Println(LastDay)

}

答案1

得分: 68

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 链接

英文:

time.Month is a type, not a value, so you can't Add it. Also, your logic is wrong because if you add a month and subtract a day, you aren't getting the end of the month, you're getting something in the middle of next month. If today is 24 April, you'll get 23 May.

The following code will do what you're looking for:

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

答案2

得分: 37

不确定AddDate(...)是何时添加到time.Time的,但很可能是在这个问题的黄金时期之后添加的 Get the first and last day of current month in Go/Golang?

以下是使用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),以获取相应的日期。

如果时间、夏令时等很重要,一旦获取到日期,将这些细节添加上去应该很简单。

最后,这是一个可以在其中进行测试的 playground 链接:https://play.golang.org/p/DxnGuqh6g4k

英文:

Not sure when AddDate(...) was added to time.Time, but quite possibly it was added after this question had its prime time Get the first and last day of current month in Go/Golang?

Here's another way to achieving the same with 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())
}

Then you could use today := time.Now() and pass it over to one/both of the functions like so - eom := EndOfMonth(today) to get the appropriate date.

If time, DST and such are important, it should be pretty straightforward to ornament those details on top of it once you get the date.

Finally, here's a playground link where you can play around with it - https://play.golang.org/p/DxnGuqh6g4k

答案3

得分: 26

你可以使用now库,它非常简单:

now.BeginningOfMonth()    // 2013-11-01 00:00:00 星期五
now.EndOfMonth()          // 2013-11-30 23:59:59.999999999 星期六

请在这里查看详细信息:https://github.com/jinzhu/now

英文:

You can use now library, it really simple :

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

Please take a look here for detail : https://github.com/jinzhu/now

答案4

得分: 24

@Apin的答案是危险的,因为now库做了很多错误的假设(我也被它坑过)。
now库没有考虑夏令时和许多其他事情:
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)
英文:

The @Apin's answer is dangerous because the now lib makes many wrong assumptions (it bit me in the foot too).
The now lib doesn't consider daylight saving times and many other things:
https://github.com/jinzhu/now/issues/13

This is how I'm doing it:

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)

答案5

得分: 5

我会这样做:

// LastDayOfMonth 返回时间对象所在月份的最后一天,范围为28-31
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()
}
英文:

I would do it like this:

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

a

答案6

得分: 5

这也可以是一个解决方案:

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链接

英文:

This can also be a solution:

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)

Output:

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

Click here to try it out:
Playground Link

答案7

得分: 4

> 时间包
>
> import "time"
>
> 函数 Date
>
> func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
>
> Date 函数返回与给定位置中的时间对应的时间。
>
> yyyy-mm-dd hh:mm:ss + nsec 纳秒
>
> 月份、日期、小时、分钟、秒和纳秒的值可能超出其正常范围,在转换过程中将被规范化。例如,10月32日将转换为11月1日。
>
> 夏令时转换会跳过或重复时间。例如,在美国,2011年3月13日凌晨2:15从未发生过,而2011年11月6日凌晨1:15发生了两次。在这种情况下,时区的选择,因此时间是不确定的。Date 函数返回的时间在转换涉及的两个时区中的一个是正确的,但不保证是哪一个。
>
> 如果 loc 为 nil,则 Date 函数会引发 panic。

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

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
英文:

> Package time
>
> import "time"
>
> func Date
>
> 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.
>
> A daylight savings time transition skips or repeats times. For
> example, in the United States, March 13, 2011 2:15am never occurred,
> while November 6, 2011 1:15am occurred twice. In such cases, the
> choice of time zone, and therefore the time, is not well-defined. Date
> returns a time that is correct in one of the two zones involved in the
> transition, but it does not guarantee which.
>
> Date panics if loc is nil.

Month and day values outside their usual ranges will be normalized. For example, for the first and last day of the month time interval,

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

Output:

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

答案8

得分: 2

goutils提供了许多有用的函数工具。goutils

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


beginningOfTWeek := time.TimeBeginningOfWeek(t)
endOfTWeek := time.TimeEndOfWeek(t)
英文:

goutils provides many useful func tools. goutils

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


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

答案9

得分: -1

dd := time.Now()
firstDayOfCurrentMonth := time.Now().AddDate(0, 0, -dd.Day()+1)
lastDayOfCurrentMonth := firstDayOfCurrentMonth.AddDate(0, 1, -1)

解释:

dd.Day 将给出特定日期的天数,例如:2010年3月4日,它将给出 04 作为天数。

AddDate 返回与将给定的年数、月数和天数添加到 t 后对应的时间。例如:
AddDate(-1, 2, 3) 应用于2011年1月1日,返回2010年3月4日。

AddDate 以与 Date 相同的方式对其结果进行规范化,因此,例如,在10月31日上加一个月会得到12月1日,这是11月31日的规范化形式。

英文:
dd := time.Now()
firstDayOfCurrentMonth := time.Now().AddDate(0, 0, -dd.Day()+1)
lastDayOfCurrentMonth := firstDayOfCurrentMonth.AddDate(0, 1, -1)

Explaination:

dd.Day will give the day from particular date ex: March 4, 2010. it will give 04 as day.

AddDate returns the time corresponding to adding the given number of years, months, and days to t. For example:
AddDate(-1, 2, 3) applied to January 1, 2011 returns March 4, 2010.

AddDate normalizes its result in the same way that Date does, so, for example, adding one month to October 31 yields December 1, the normalized form for November 31.

huangapple
  • 本文由 发表于 2016年4月25日 07:49:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/36830212.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定