go多个时间区间之间(交集,并集, 差集)等操作包分享
项目地址
项目介绍
Period 是一个使用 Go 语言编的项目,主要用于处理和操作时间段。它提供了一系列的方法,如并集、交集、差集等,以便于用户对时间段进行各种操作。
⚠️ 警告:当前,Go(1.21.x) 语言还不支持枚举类型。如果 Go 语言在将来版本中支持枚举类型,我们将重构
bounds.go
文件中的方法。
典型应用场景
时间区间可以类比高中集合中的闭区间和开区间。例如,时间区间 [2023-12-09 08:00:00, 2023-12-09 14:23:45) 表示包含开始时间但不包含结束时间。
在生活中可能会遇到这样一个场景:您去大型商场购物,但该商场人流量大,停车位有限,因此一些人只能将车停在附近的马路边。
该马路边的停车收费区间为每天[08:00:00,21:00:00],并且在每天的高峰时段[10:00:00,12:00:00]和下午的[18:00:00,20:00:00]收费更高(4元/小时),其他时间段的收费为2元/小时。
比如说,您从2023-12-09 07:35:30进入该商场附近的马路边停车,然后准备在同一天下午2023-12-09 19:34:20离开。
如果情况更加复杂,马路边的管理者还出台了一项优惠政策:只要车主停车满4小时,就会随机发放一张优惠券。对于电子优惠券而言,它也有自己有效的时间区间范围[2023-12-09 16:30:23,2023-12-09 19:00:00]。
最终,您需要支付的停车费用是多少呢?针对这种情况,我们需要对多个时间区间进行交集、差集、并集等相关操作,并进行计算。
主要功能
- 创建时间段:用户可以创建一个时间段,包括开始时间和结束时间。
- 时间段并集:用户可以计算两个或多个时间段的并集。
- 时间段交集:用户可以计算两个或多个时间段的交集。
- 时间段差集:用户可以计算两个时间段的差集。
如何使用
首先,你需要在你的 Go 项目中引入 Period 项目。你可以在你的 go.mod
文件中添加以下依赖:
require (
github.com/maogou/period v1.0.0
)
然后,你可以在你的代码中引入 Period 项目,并使用它提供的方法。以下是一个简单的示例:
package main
import (
"github.com/maogou/period"
"time"
)
func main() {
p1 := period.Period{
startDate: time.Date(2023, 1, 1, 0, 0, 0, 0, time.Local),
endDate: time.Date(2023, 1, 3, 0, 0, 0, 0, time.Local),
boundaryType: period.IncludeStartExcludeEnd,
}
p2 := period.Period{
startDate: time.Date(2023, 1, 2, 0, 0, 0, 0, time.Local),
endDate: time.Date(2023, 1, 4, 0, 0, 0, 0, time.Local),
boundaryType: period.IncludeStartExcludeEnd,
}
result := p1.Union(p2)
fmt.Println(result)
}
方法
以下是 Period
结构体的主要方法:
GetTimestampInterval()
: 返回时间段的时间戳间隔。Subtract(Period)
: 从当前时间段中减去另一个时间段,返回一个新的时间段。Merge(Period)
: 合并当前时间段和另一个时间段,返回一个新的时间段。Intersect(Period)
: 返回当前时间段和另一个时间段的交集。Overlaps(Period)
: 判断当前时间段是否与另一个时间段重叠。Abuts(Period)
: 判断当前时间段是否与另一个时间段相邻。Contains(Period)
: 判断当前时间段是否包含另一个时间段。Equals(Period)
: 判断当前时间段是否等于另一个时间段。Gap(Period)
: 返回当前时间段和另一个时间段之间的间隙。Diff(Period)
: 返回当前时间段和另一个时间段的差异。Union(Period...)
: 获取当时时间段集合的并集。IsZero()
: 判断当前时间段是否为零。
以下是 Sequence
结构体的主要方法:
NewSequence(Period...)
: 创建一个新的时间段序列。totalTimeDuration()
: 返回时间段序列的总时间长度。GetTotalTimestampInterval()
: 返回时间段序列的总时间戳间隔。Sort(func(Period, Period) bool)
: 根据给定的比较函数对时间段序列进行排序。Contains(Period...)
: 判断时间段序列是否包含给定的时间段。Subtract(Sequence)
: 从当前时间段序列中减去另一个时间段序列,返回一个新的时间段序列。Equals(Sequence)
: 判断当前时间段序列是否等于另一个时间段序列。Unions()
: 返回时间段序列的并集。Gaps()
: 返回时间段序列的间隙。IsEmpty()
: 判断时间段序列是否为空。IndexOf(Period)
: 返回给定时间段在时间段序列中的索引。Count()
: 返回时间段序列的数量。Get(int)
: 返回时间段序列中给定索引的时间段。Set(int, Period)
: 在时间段序列的给定索引处设置时间段。Push(Period...)
: 在时间段序列的末尾添加时间段。Intersections()
: 返回时间段序列的交集。Remove(int)
: 移除时间段序列中给定索引的时间段。Filter(func(Period) bool)
: 根据给定的过滤函数过滤时间段序列。Map(func(Period) Period)
: 根据给定的映射函数映射时间段序列。Every(func(Period, int) bool)
: 判断时间段序列是否每个元素都满足给定的条件。Some(func(Period, int) bool)
: 判断时间段序列是否有元素满足给定的条件。Clear()
: 清空时间段序列。
测试
Period 项目包含一系列的单元测试,以确保代码的质量和功能的正确性。你可以通过运行以下命令来执行这些测试:
go test ./... -v -count=1
代码覆盖率(100%)
我们使用 Go 的内置测试工具来跟踪代码覆盖率。你可以通过以下步骤生成和查看覆盖率报告:
go test ./... -coverprofile=coverage.out && go tool cover -html=coverage.out
贡献
我们欢迎任何形式的贡献,包括但不限于提交问题、提供反馈、提出新的功能建议、改进代码等。如果你有任何问题或建议,欢迎在 GitHub 上提交 issue 或 pull request。
许可证
Period 项目采用 MIT 许可证,详情请参见 LICENSE 文件。
话说,go已经支持枚举了的。搜一下
@deatil 我说的枚举是go原生枚举类型, 可以做函数参数限定等等, 你可以参考一下php的枚举, 我想要的就是php这样的效果,而 你给的示例是一种变现的枚举类型的实现, 但是不能用作参数限定
如果我定义一个函数 func demo(enum xxxx) { //那么我这样写, 我希望xxxx是被枚举参数限定的, 只能是1或者2或者3 这三个值的其中之一 }
www.php.net/manual/zh/language.enu...