获取time.Time中的月份的最后一天。

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

Get last day in month of time.Time

问题

当我有一个time.Time时:

// 1月29日
t, _ := time.Parse("2006-01-02", "2016-01-29")

我如何得到一个代表1月31日的time.Time?这个例子很简单,但是当有一个日期在二月时,最后一天可能是28号或29号。

英文:

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.

答案1

得分: 8

> 时间包
>
> func 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日。

例如,规范化日期:

package main

import (
	"fmt"
	"time"
)

func main() {
	// 1月29日
	t, _ := time.Parse("2006-01-02", "2016-01-29")
	fmt.Println(t.Date())
	// 1月31日
	y,m,_ := t.Date()
	lastday:= time.Date(y,m+1,0,0,0,0,0,time.UTC)
	fmt.Println(lastday.Date())
}

输出结果:

2016年1月29日
2016年1月31日
英文:

> Package 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.

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

答案2

得分: 2

你可以自己编写一个函数,可能是这样的:

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) { // 闰年
            return 29
        }
        return 28
    default:
        return 31
    }
}

编辑:因为我真的很喜欢测量事物:

$ go test -bench .
testing: warning: no tests to run
PASS
BenchmarkDim2-8         200000000                7.26 ns/op
BenchmarkDim-8          1000000000               2.80 ns/op // 谎言!
BenchmarkTime-8         10000000               169 ns/op
BenchmarkTime2-8        10000000               234 ns/op
ok      github.com/drathier/scratchpad/go       9.741s

BenchMarkDim2:未经测试,但非常快。

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:谎言

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) {
            // 闰年
            return 29
        }
        return 28
    default:
        return 31
    }
}

BenchmarkTime:

func timeDaysInMonth() time.Time {
    // 1月29日
    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
}
英文:

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
}

答案3

得分: 1

我已经在我的代码中使用了类似的内容:

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
}

playground

英文:

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
}

<kbd>playground</kbd>

答案4

得分: 0

这是一个通用的方法,不仅适用于Go语言,通常我在任何语言中都会这样做:

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

英文:

It's not Go specific but usually I do following in any language:

package main

import &quot;fmt&quot;
import &quot;time&quot;

func main() {
	fmt.Println(&quot;Hello, playground&quot;)
	
	t, _ := time.Parse(&quot;2006-01-02&quot;, &quot;2016-01-01&quot;)
	t = t.AddDate(0, 1, 0).AddDate(0,0,-1)
	fmt.Printf(&quot;Last day: %v\n&quot;, t)
}

http://play.golang.org/p/JhpOZvEhBw

huangapple
  • 本文由 发表于 2016年2月4日 00:32:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/35182556.html
匿名

发表评论

匿名网友

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

确定