2016-04-24 308 views
3

我正在嘗試獲取當前月份的第一天和最後一天。您可以添加日期和時間,但不是月份,我想這是從下個月開始減去一天以獲得本月的最後一天。事情是這樣的:在Go/Golang中獲取本月的第一天和最後一天?

package main 

import (
    "fmt" 
    "time" 
) 

func main() { 

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

    fmt.Println(LastDay) 

} 
+0

'LastDay'不會是正確的,如果有,或從DST在最後一天的過渡在當地時區的月份。 –

回答

2

您可以使用現在庫,它很簡單:

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

請大家查看詳情:https://github.com/jinzhu/now

+0

如果你不想使用這個庫,你至少可以從它的方式中學習(你可以複製你需要的部分):https://github.com/jinzhu/now/blob/master/now。去 – fiatjaf

+0

錯誤警告:[now package](https://github.com/jinzhu/now)在夏令時轉換期間沒有提供正確的結果。它錯誤地假定一天中總是有24小時:'func(now * Now)BeginningOfMonth()time.Time':'* 24 * time.Hour'。 – peterSO

13

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

0

goutils提供了許多有用的func工具。 goutils

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


beginningOfTWeek:=goutils.TimeBeginningOfWeek(t) 
endOfTWeek:=goutils.TimeEndOfWeek(t) 
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() 
} 

一個

3

@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

我爲你添加了一個BUG ALERT評論給[@ Apin's answer](https://stackoverflow.com/a/36830416/221700)。 – peterSO

2

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 
相關問題