当前位置: 首页 > news >正文

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 quarterquarter := (int(date.Month()) - 1) / 3startMonth := 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.TimefirstDayOfMonth := 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 := startDatefor 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()) % 24minutes := int(duration.Minutes()) % 60seconds := int(duration.Seconds()) % 60return fmt.Sprintf("%d天 %02d小时 %02d分 %02d秒", days, hours, minutes, seconds)
}
// output:
3天 04小时 15分 30秒

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

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

相关文章:

  • (学习日记)2024.01.19
  • C++:史上最坑小游戏
  • 【RabbitMQ】快速入门及基本使用
  • C#,字符串匹配(模式搜索)有限自动机(Finite Automata)算法的源代码
  • 配置中心原理和选型
  • Python文件自动化处理
  • vue 解决el-table 表体数据发生变化时,未重新渲染问题
  • 代码随想录算法训练53 | 动态规划part14
  • 带你学C语言-指针(4)
  • cetos7搭建部署k8s 版本1.28
  • Docker进阶篇-安装MySQL主从复制
  • nestjs之provider的provide取值的几种方式
  • 设计模式篇章(4)——十一种行为型模式
  • Unity之射线检测
  • 【河海大学论文LaTeX+VSCode全指南】
  • hexo+github搭建个人博客
  • JavaScript 如何正确处理 Unicode 编码问题!
  • [LeetCode] Wiggle Sort
  • [笔记] php常见简单功能及函数
  • 78. Subsets
  • java正则表式的使用
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • js作用域和this的理解
  • PAT A1120
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 关于List、List?、ListObject的区别
  • 回顾 Swift 多平台移植进度 #2
  • 机器学习学习笔记一
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 说说动画卡顿的解决方案
  • 智能合约Solidity教程-事件和日志(一)
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • 《天龙八部3D》Unity技术方案揭秘
  • 1.Ext JS 建立web开发工程
  • kubernetes资源对象--ingress
  • 组复制官方翻译九、Group Replication Technical Details
  • #pragma 指令
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (二十一)devops持续集成开发——使用jenkins的Docker Pipeline插件完成docker项目的pipeline流水线发布
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .net CHARTING图表控件下载地址
  • .NET Standard 的管理策略
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .NET 中 GetProcess 相关方法的性能
  • .NET设计模式(8):适配器模式(Adapter Pattern)