★关注公众号【爱发白日梦的后端】分享技术干货、读书笔记、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力!
”
在Go编程中,处理日期和时间是一项常见任务,涉及到精确性和灵活性。尽管Go的标准库提供了时间包(time
)用于处理时间相关操作,但在某些情况下,我们需要额外的实用函数来简化这些任务。本文将介绍一系列实用函数,它们充当time
包的包装器,提供了更便捷的操作方式。
func?StartOfMonth(date?time.Time)?time.Time?{
?return?time.Date(date.Year(),?date.Month(),?1,?0,?0,?0,?0,?date.Location())
}
//?output:
2024-01-01?00:00:00?+0800?CST
上述函数接受一个日期,返回该日期所在月份的第一天。例如,StartOfMonth(time.Now())
将返回当前月份的第一天的时间戳。
func?EndOfMonth(date?time.Time)?time.Time?{
?firstDayOfNextMonth?:=?StartOfMonth(date).AddDate(0,?1,?0)
?return?firstDayOfNextMonth.Add(-time.Second)
}
//?output:
2024-01-31?23:59:59?+0800?CST
上述函数接受一个日期,返回该日期所在月份的最后一天的最后一秒。通过结合StartOfMonth
函数,我们确保了准确的计算。
func?StartOfDayOfWeek(date?time.Time)?time.Time?{
?daysSinceSunday?:=?int(date.Weekday())
?return?date.AddDate(0,?0,?-daysSinceSunday+1)
}
//?output:
2024-01-15?00:19:42.869678?+0800?CST
上述函数接受一个日期,返回该日期所在周的第一天。
func?EndOfDayOfWeek(date?time.Time)?time.Time?{
?daysUntilSaturday?:=?7?-?int(date.Weekday())
?return?date.AddDate(0,?0,?daysUntilSaturday)
}
//?output:
2024-01-21?00:22:06.955558?+0800?CST
上述函数接受一个日期,返回该日期所在周的最后一天。
func?StartAndEndOfWeeksOfMonth(year,?month?int)?[]struct{?Start,?End?time.Time?}?{
?startOfMonth?:=?time.Date(year,?time.Month(month),?1,?0,?0,?0,?0,?time.UTC)
?weeks?:=?make([]struct{?Start,?End?time.Time?},?0)
?for?current?:=?startOfMonth;?current.Month()?==?time.Month(month);?current?=?current.AddDate(0,?0,?7)?{
??startOfWeek?:=?StartOfDayOfWeek(current)
??endOfWeek?:=?EndOfDayOfWeek(current)
??if?endOfWeek.Month()?!=?time.Month(month)?{
???endOfWeek?=?EndOfMonth(current)
??}
??weeks?=?append(weeks,?struct{?Start,?End?time.Time?}{startOfWeek,?endOfWeek})
?}
?return?weeks
}
//?output:
[
?{2024-01-01?00:00:00?+0000?UTC?2024-01-07?00:00:00?+0000?UTC}?
?{2024-01-08?00:00:00?+0000?UTC?2024-01-14?00:00:00?+0000?UTC}?
?{2024-01-15?00:00:00?+0000?UTC?2024-01-21?00:00:00?+0000?UTC}?
?{2024-01-22?00:00:00?+0000?UTC?2024-01-28?00:00:00?+0000?UTC}?
?{2024-01-29?00:00:00?+0000?UTC?2024-01-31?23:59:59?+0000?UTC}
]
上述函数接受年份和月份,返回一个包含给定月份中每周的开始日和结束日的切片。通过调用前述的获取每周开始日和结束日的函数,我们得到了全面的每周视图。
func?WeekNumberInMonth(date?time.Time)?int?{
?startOfMonth?:=?StartOfMonth(date)
?_,?week?:=?date.ISOWeek()
?_,?startWeek?:=?startOfMonth.ISOWeek()
?return?week?-?startWeek?+?1
}
//?output:
3
上述函数接受一个日期,返回该日期所在月份的相对周数。通过利用ISO周数的概念,我们实现了简便的计算。
func?StartOfYear(date?time.Time)?time.Time?{
?return?time.Date(date.Year(),?time.January,?1,?0,?0,?0,?0,?date.Location())
}
//?output:
2024-01-01?00:00:00?+0800?CST
上述函数接受一个日期,返回该日期所在年份的第一天。
func?EndOfYear(date?time.Time)?time.Time?{
?startOfNextYear?:=?StartOfYear(date).AddDate(1,?0,?0)
?return?startOfNextYear.Add(-time.Second)
}
//?output:
2024-12-31?23:59:59?+0800?CST
上述函数接受一个日期,返回该日期所在年份的最后一天的最后一秒。
func?StartOfQuarter(date?time.Time)?time.Time?{
?//?you?can?directly?use?0,?1,?2,?3?quarter
?quarter?:=?(int(date.Month())?-?1)?/?3
?startMonth?:=?time.Month(quarter*3?+?1)
?return?time.Date(date.Year(),?startMonth,?1,?0,?0,?0,?0,?date.Location())
}
//?output:
2024-01-01?00:00:00?+0800?CST
上述函数接受一个日期,返回该日期所在季度的第一天。
func?EndOfQuarter(date?time.Time)?time.Time?{
?startOfNextQuarter?:=?StartOfQuarter(date).AddDate(0,?3,?0)
?return?startOfNextQuarter.Add(-time.Second)
}
//?output:
2024-03-31?23:59:59?+0800?CST
上述函数接受一个日期,返回该日期所在季度的最后一天的最后一秒。
func?CurrentWeekRange(timeZone?string)?(startOfWeek,?endOfWeek?time.Time)?{
?loc,?_?:=?time.LoadLocation(timeZone)
?now?:=?time.Now().In(loc)
?startOfWeek?=?StartOfDayOfWeek(now)
?endOfWeek?=?EndOfDayOfWeek(now)
?return?startOfWeek,?endOfWeek
}
//?output:
2024-01-15?00:37:18.812985?+0800?CST?2024-01-21?00:37:18.812985?+0800?CST
上述函数接受一个时区字符串,返回该时区中当前周的开始时间和结束时间。通过调用前述的获取每周开始日和结束日的函数,我们获得了当前周的范围。
func?DurationBetween(start,?end?time.Time)?time.Duration?{
?return?end.Sub(start)
}
//?output:
10.000000101s
上述函数接受两个日期,返回它们之间的持续时间。这个函数在测量两个事件之间经过的时间时非常有用。
func?GetDatesForDayOfWeek(year,?month?int,?day?time.Weekday)?[]time.Time?{
?var?dates?[]time.Time
?firstDayOfMonth?:=?time.Date(year,?time.Month(month),?1,?0,?0,?0,?0,?time.UTC)
?diff?:=?int(day)?-?int(firstDayOfMonth.Weekday())
?if?diff?<?0?{
??diff?+=?7
?}
?firstDay?:=?firstDayOfMonth.AddDate(0,?0,?diff)
?for?current?:=?firstDay;?current.Month()?==?time.Month(month);?current?=?current.AddDate(0,?0,?7)?{
??dates?=?append(dates,?current)
?}
?return?dates
}
//?output:
[2024-01-05?00:00:00?+0000?UTC?2024-01-12?00:00:00?+0000?UTC?2024-01-19?00:00:00?+0000?UTC?2024-01-26?00:00:00?+0000?UTC]
上述函数接受年份、月份和目标星期几,返回给定月份中指定日期的所有出现情况。这为获取一个月中特定日期的出现提供了通用的解决方案。
func?AddBusinessDays(startDate?time.Time,?daysToAdd?int)?time.Time?{
?currentDate?:=?startDate
?for?i?:=?0;?i?<?daysToAdd;?{
??currentDate?=?currentDate.AddDate(0,?0,?1)
??if?currentDate.Weekday()?!=?time.Saturday?&&?currentDate.Weekday()?!=?time.Sunday?{
???i++
??}
?}
?return?currentDate
}
//?output:
2024-03-01?00:46:38.131747?+0800?CST
上述函数接受一个起始日期和要添加的工作日数,返回加上指定工作日后的日期。这对于处理只涉及工作日的应用程序非常有用。
func?FormatDuration(duration?time.Duration)?string?{
?days?:=?int(duration.Hours()?/?24)
?hours?:=?int(duration.Hours())?%?24
?minutes?:=?int(duration.Minutes())?%?60
?seconds?:=?int(duration.Seconds())?%?60
?return?fmt.Sprintf("%d天?%02d小时?%02d分?%02d秒",?days,?hours,?minutes,?seconds)
}
//?output:
3天?04小时?15分?30秒
上述函数接受一个持续时间,返回一个格式化的字符串,以便更友好地显示。这对于向用户呈现持续时间时非常实用。
通过使用这些高级实用函数,我们扩展了日期时间包装器的功能,为开发人员提供了一套全面的工具来处理各种与时间相关的操作。这些函数可以轻松集成到您的代码库中,简化了复杂的日期和时间操作,无论是构建计划应用程序、生成报告,还是处理各种时间敏感的任务。