在Golang中如何根据日期获取当月的周数?
解决Go中获取日期当月周数的问题
你的现有代码在处理跨ISO年份的月份时会出错(比如1月初或12月末),因为当日期的ISO周年份与当月第一天的ISO周年份不同时,直接相减会得到错误结果。以下是两种可靠的实现方案:
方案一:基于ISO周规则(周一为周起始)
直接通过日期计算,避免依赖ISO周的年份问题:
import "time" func WeekInMonth(t time.Time) int { loc := t.Location() // 获取当月第一天 firstDay := time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, loc) // 转换为ISO星期值(1=周一,7=周日) firstWeekday := firstDay.Weekday() isoFirst := int(firstWeekday) if isoFirst == 0 { // time.Sunday对应0,转换为ISO的7 isoFirst = 7 } // 当前日期是当月第几天 dayOfMonth := t.Day() // 计算距离当月第一天的天数差 daysDiff := dayOfMonth - 1 // 计算周数:(天数差 + 第一天到周一的偏移) /7 +1 return (daysDiff + isoFirst - 1)/7 + 1 }
测试验证
- 2022年12月16日:返回
3,符合预期(1-4日第1周,5-11日第2周,12-18日第3周) - 2023年1月1日:返回
1 - 2023年1月2日:返回
2
方案二:自定义周起始(以周日为例)
如果你的业务要求周日为一周的起始,可使用以下实现:
import "time" func WeekInMonthSundayStart(t time.Time) int { loc := t.Location() firstDay := time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, loc) // time.Weekday()返回0=周日,1=周一...6=周六 firstWeekday := int(firstDay.Weekday()) dayOfMonth := t.Day() daysDiff := dayOfMonth - 1 // 计算周数:(天数差 + 第一天到周日的剩余天数)/7 +1 return (daysDiff + (7 - firstWeekday))/7 + 1 }
修复原有代码的跨年份问题
如果你坚持使用ISOWeek方法,需要处理周年份不同的情况:
import "time" import "fmt" func main() { now := time.Now() loc := now.Location() beginningOfTheMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, loc) currentYear, thisWeek := now.ISOWeek() beginYear, beginningWeek := beginningOfTheMonth.ISOWeek() var weekInMonth int if currentYear == beginYear { weekInMonth = 1 + thisWeek - beginningWeek } else { // 判断起始年份的最后一周是52还是53周 _, lastWeekOfBeginYear := time.Date(beginYear, 12, 28, 0, 0, 0, 0, loc).ISOWeek() weekInMonth = 1 + thisWeek + (lastWeekOfBeginYear - beginningWeek) } fmt.Printf("%d week in the month", weekInMonth) }
该代码会自动处理跨ISO年份的情况,比如2023年1月2日这类日期,能正确返回2。
内容的提问来源于stack exchange,提问作者Ikhsan Arfian Nugraha
相关产品推荐
相关产品推荐

