List the number of days in current date/month

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

List the number of days in current date/month

问题

如何列出当前日期/月份的天数?例如:一月有31天,所以从1到31逐个列出。

英文:

How to list the number of the days in the current date/month? Exp: January have 31 day so 1 2 3 4 till 31

答案1

得分: 2

保持简单。


Go的时间包会对日期进行规范化:

月份、日期、小时、分钟、秒和纳秒的值可能超出其通常范围,并在转换过程中进行规范化。例如,10月32日会转换为11月1日。


获取一个月的天数

func DaysInMonth(t time.Time) int {
    y, m, _ := t.Date()
    return time.Date(y, m+1, 0, 0, 0, 0, 0, time.UTC).Day()
}

获取一个月中的日期列表

func ListDaysInMonth(t time.Time) []int {
    days := make([]int, DaysInMonth(t))
    for i := range days {
        days[i] = i + 1
    }
    return days
}
英文:

Keep things simple.


The Go time package normalizes dates:

> 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 the number of days in a month

func DaysInMonth(t time.Time) int {
	y, m, _ := t.Date()
	return time.Date(y, m+1, 0, 0, 0, 0, 0, time.UTC).Day()
}

For a list of days in a month

func ListDaysInMonth(t time.Time) []int {
    days := make([]int, DaysInMonth(t))
    for i := range days {
	    days[i] = i + 1
    }
    return days
}

答案2

得分: 1

一个月中的日期总是从1到给定月份的天数。因此,主要任务是确定给定月份的天数。

time包没有提供这样的功能,但你可以使用以下技巧:

// y1年M1月的最大天数
t := time.Date(y1, M1, 32, 0, 0, 0, 0, time.UTC)
daysInMonth := 32 - t.Day()

这个逻辑的原理是,第32天大于任何一个月的最大天数。它会自动归一化(多余的天数滚动到下个月,并且天数递减正确)。当我们用归一化后的天数从32中减去时,我们得到的就是该月的最后一天。

这段代码摘自答案https://stackoverflow.com/questions/36530251/time-since-with-months-and-years/36531443#36531443。

下面是一个小助手函数,它根据给定的time.Time返回一个月的天数作为[]int

func daysInMonth(t time.Time) []int {
    t = time.Date(t.Year(), t.Month(), 32, 0, 0, 0, 0, time.UTC)
    daysInMonth := 32 - t.Day()
    days := make([]int, daysInMonth)
    for i := range days {
        days[i] = i + 1
    }
    return days
}

进行测试:

fmt.Println(daysInMonth(time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)))
fmt.Println(daysInMonth(time.Date(2022, 2, 1, 0, 0, 0, 0, time.UTC)))
fmt.Println(daysInMonth(time.Date(2020, 2, 1, 0, 0, 0, 0, time.UTC)))

输出结果(在Go Playground上尝试):

[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31]
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28]
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29]

另一种性能较差的选择是将日期回滚到该月的第一天,然后开始添加天数,直到月份发生变化。代码如下:

func daysInMonth(t time.Time) []int {
    var days []int

    // 回滚到第1天
    t = time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, time.UTC)
    m := t.Month()
    for t.Month() == m {
        days = append(days, t.Day())
        t = t.AddDate(0, 0, 1)
    }

    return days
}

这将输出相同的结果。在Go Playground上尝试这个版本。

由于所有的月份至少有28天,我们可以优化上面的解决方案,将日期滚动到第29天,然后开始检查和递增:

func daysInMonth(t time.Time) []int {
    days := make([]int, 28, 31)
    for i := range days {
        days[i] = i + 1
    }

    m := t.Month()
    // 滚动到第29天
    t = time.Date(t.Year(), t.Month(), 29, 0, 0, 0, 0, time.UTC)
    for t.Month() == m {
        days = append(days, t.Day())
        t = t.AddDate(0, 0, 1)
    }

    return days
}

Go Playground上尝试这个版本。

英文:

The days in a month always range from 1 to the number of days in the given month. So the main task is to determine the number of days in a given month.

The time package does not expose such functionality, but you may use the following trick:

// Max days in year y1, month M1
t := time.Date(y1, M1, 32, 0, 0, 0, 0, time.UTC)
daysInMonth := 32 - t.Day()

The logic behind this is that the day 32 is bigger than the max day in any month. It will get automatically normalized (extra days rolled to the next month and day decremented properly). And when we subtract day we have after normalization from 32, we get exactly what the last day was in the month.

This snippet is taken from the answer https://stackoverflow.com/questions/36530251/time-since-with-months-and-years/36531443#36531443.

So here's a little helper that returns the days of a month as []int for a given time.Time:

func daysInMonth(t time.Time) []int {
    t = time.Date(t.Year(), t.Month(), 32, 0, 0, 0, 0, time.UTC)
    daysInMonth := 32 - t.Day()
    days := make([]int, daysInMonth)
    for i := range days {
        days[i] = i + 1
    }
    return days
}

Testing it:

fmt.Println(daysInMonth(time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)))
fmt.Println(daysInMonth(time.Date(2022, 2, 1, 0, 0, 0, 0, time.UTC)))
fmt.Println(daysInMonth(time.Date(2020, 2, 1, 0, 0, 0, 0, time.UTC)))

Output (try it on the Go Playground):

[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31]
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28]
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29]

Another, less peformant option is to roll back the date to the first of the month, and start adding days until the month changes. This is how it could look like:

func daysInMonth(t time.Time) []int {
	var days []int

	// Roll back to day 1
	t = time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, time.UTC)
	m := t.Month()
	for t.Month() == m {
		days = append(days, t.Day())
		t = t.AddDate(0, 0, 1)
	}

	return days
}

This will output the same. Try this one on the Go Playground.

Since all months contain at least 28 days, we can optimize the above solution to roll to day 29, and start checking and incrementing from there:

func daysInMonth(t time.Time) []int {
	days := make([]int, 28, 31)
	for i := range days {
		days[i] = i + 1
	}

	m := t.Month()
	// Roll to day 29
	t = time.Date(t.Year(), t.Month(), 29, 0, 0, 0, 0, time.UTC)
	for t.Month() == m {
		days = append(days, t.Day())
		t = t.AddDate(0, 0, 1)
	}

	return days
}

Try this one on the Go Playground.

答案3

得分: -1

有很多方法可以完成这个任务,因为我们主要处理的是常量,只需要处理二月份是否是闰年(29天)。

package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println(list_of_days())
}

func list_of_days() []int {
	non_leap_year := map[string]int{
		"January":   31,
		"February":  28,
		"March":     31,
		"April":     30,
		"May":       31,
		"June":      30,
		"July":      31,
		"August":    31,
		"September": 30,
		"October":   31,
		"November":  30,
		"December":  31,
	}

	leap_year := map[string]int{
		"January":   31,
		"February":  29,
		"March":     31,
		"April":     30,
		"May":       31,
		"June":      30,
		"July":      31,
		"August":    31,
		"September": 30,
		"October":   31,
		"November":  30,
		"December":  31,
	}
	//获取当前月份
	year, month, _ := time.Now().Date()

	//处理闰年
	no_of_days := 0
	if year%4 == 0 && year%100 != 0 || year%400 == 0 {
		no_of_days = leap_year[month.String()]
	} else {
		no_of_days = non_leap_year[month.String()]
	}

	days := make([]int, no_of_days)
	for i := range days {
		days[i] = i + 1
	}
	return days
}
英文:

There are many ways to get it done, as we are dealing with constants mostly, and we just need to handle February if it's a Leap Year( 29 days).

package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(list_of_days())
}
func list_of_days() []int {
non_leap_year := map[string]int{
"January":   31,
"February":  28,
"March":     31,
"April":     30,
"May":       31,
"June":      30,
"July":      31,
"August":    31,
"September": 30,
"October":   31,
"November":  30,
"December":  31,
}
leap_year := map[string]int{
"January":   31,
"February":  29,
"March":     31,
"April":     30,
"May":       31,
"June":      30,
"July":      31,
"August":    31,
"September": 30,
"October":   31,
"November":  30,
"December":  31,
}
//get the current month
year, month, _ := time.Now().Date()
//handle leap year
no_of_days := 0
if year%4 == 0 && year%100 != 0 || year%400 == 0 {
no_of_days = leap_year[month.String()]
} else {
no_of_days = non_leap_year[month.String()]
}
days := make([]int, no_of_days)
for i := range days {
days[i] = i + 1
}
return days
}

huangapple
  • 本文由 发表于 2022年9月28日 19:44:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/73880828.html
匿名

发表评论

匿名网友

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

确定