Go 日期时间包装器:15条更便捷的时间处理

简介: Go 日期时间包装器:15条更便捷的时间处理

在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秒


上述函数接受一个持续时间,返回一个格式化的字符串,以便更友好地显示。这对于向用户呈现持续时间时非常实用。


通过使用这些高级实用函数,我们扩展了日期时间包装器的功能,为开发人员提供了一套全面的工具来处理各种与时间相关的操作。这些函数可以轻松集成到您的代码库中,简化了复杂的日期和时间操作,无论是构建计划应用程序、生成报告,还是处理各种时间敏感的任务。

相关文章
|
2月前
|
Serverless Go
Go to Learn Go之时间日期
Go to Learn Go之时间日期
38 8
|
6月前
|
安全 Unix Go
Golang深入浅出之-Go语言中的时间与日期处理:time包详解
【4月更文挑战第26天】Go语言的`time`包提供处理日期和时间的功能,包括`time.Time`类型、时间戳、格式化与解析。本文讨论了核心概念、常见问题(如时区处理、格式字符串混淆、超时控制和并发安全)及解决方法。推荐使用`time.LoadLocation`管理时区,熟悉时间格式规则,用`context`精确控制超时,并注意并发安全。文中通过代码示例展示了如何获取格式化时间、计算时间差以及创建定时任务。学习和应用这些知识可提高程序的健壮性和准确性。
217 2
|
6月前
|
Go Unix 开发者
Go语言time库,时间和日期相关的操作方法
Go语言time库,时间和日期相关的操作方法
94 0
Go语言time库,时间和日期相关的操作方法
|
Java Go
Go 编程 | 连载 32 - 时间与日期
Go 编程 | 连载 32 - 时间与日期
Go 编程 | 连载 32 - 时间与日期
|
Unix 程序员 Go
Go 时间和日期函数详解(1)| 学习笔记
快速学习 Go 时间和日期函数详解(1)
315 0
Go 时间和日期函数详解(1)| 学习笔记
|
Unix Go 开发者
Go 时间和日期函数详解(2) | 学习笔记
快速学习 Go 时间和日期函数详解(2)
130 0
|
SQL 开发框架 .NET
go语言模板(template)中日期格式化
go语言模板(template)中日期格式化
395 0
【Go语言入门100题】042 日期格式化 (5 分) Go语言|Golang
L1-042 日期格式化 (5 分) Go语言|Golang 世界上不同国家有不同的写日期的习惯。比如美国人习惯写成“月-日-年”,而中国人习惯写成“年-月-日”。下面请你写个程序,自动把读入的美国格式的日期改写成中国习惯的日期。
453 0
|
7天前
|
存储 前端开发 Go
Go语言中的数组
在 Go 语言中,数组是一种固定长度的、相同类型元素的序列。数组声明时长度已确定,不可改变,支持多种初始化方式,如使用 `var` 关键字、短变量声明、省略号 `...` 推断长度等。数组内存布局连续,可通过索引高效访问。遍历数组常用 `for` 循环和 `range` 关键字。
|
4天前
|
存储 安全 算法
Go语言是如何支持多线程的
【10月更文挑战第21】Go语言是如何支持多线程的
101 72