Golang - 从 YearDay int32 中查找月份和日期
Golang - Find month and day of month from YearDay int32
我有一个固定的数据结构,其中包含 YearDay 和 TimeOfDay 字段。 YearDay 是当年过去的天数,TimeOfDay 是当天过去的秒数(最多 86400)。 YearDay 是一个 int32,而 TimeOfDay 是一个 float64。
我想将其转换为 time.Now().UnixNano() 形式,但不确定如何转换。时间模块有一个 YearDay(),但没有给定 yearDay (int32)(可能是一年)的反函数来给我一个月中的月份和日期。
理想情况下,我想以某种方式解析
d := time.Date(time.Year(), month, day, hour, min, sec, ms, time.UTC)
月、日、时、分、秒、毫秒以某种方式预先确定,或者我可以轻松转换为我想要的任何形式的等价物(但主要是 UnixNano())。
我最好的想象是一个复杂的 switch 语句,它减去 31、28(29)、30、31 ... 并查看 int 何时最终为负数以找到月份和日期,但它必须是两个带有闰年检查的 switch 语句以选择要使用的 switch 块,同时在 TimeOfDay 上进行几个余数计算。有没有更简单更干净的方法?
编辑:我在玩弄它时最终实现了以下功能,但我肯定会使用 Icza 的解决方案。很高兴知道日子会溢出来。谢谢!
func findMonthAndDay(yearDay int32) (int32, int32) {
year := time.Now().Year()
isLeapYear := year%400 == 0 || year%4 == 0 && year%100 != 0 // Calculates if current year is leapyear
// Determines which array to send to for loop
var monthsOfYear [12]int32
if isLeapYear {
monthsOfYear = [12]int32{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
} else {
monthsOfYear = [12]int32{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
}
var currentMonth int32
var currentDayInMonth int32
// Loop through array of months
for i := range monthsOfYear {
// If yearDay - next month #OfDays positive, not correct month
if yearDay-monthsOfYear[i] > 0 {
// Subtract month #OfDays and continue
yearDay = yearDay - monthsOfYear[i]
} else {
currentMonth = int32(i + 1) // Month found (+1 due to index at 0)
currentDayInMonth = yearDay // Remainder of YearDay is day in month
break
}
}
return currentMonth, currentDayInMonth
}
您可以使用 Time.AddDate()
to add the number of days to a time.Time
值。添加天数大于31是可以的,实现归一化结果。
并将 TimeOfDay
转换为 time.Duration
and use Time.Add()
以添加它。当转换为time.Duration
时,我们可以将它乘以1e9
得到纳秒数,所以小数秒将被保留。
示例:
t := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
fmt.Println(t)
var yearDay int32 = 100
var timeOfDay float64 = 70000.5
t = t.AddDate(0, 0, int(yearDay))
t = t.Add(time.Duration(timeOfDay * 1e9))
fmt.Println(t)
fmt.Println("Unix:", t.Unix())
fmt.Println("UnixNano:", t.UnixNano())
输出(在 Go Playground 上尝试):
2020-01-01 00:00:00 +0000 UTC
2020-04-10 19:26:40.5 +0000 UTC
Unix: 1586546800
UnixNano: 1586546800500000000
我有一个固定的数据结构,其中包含 YearDay 和 TimeOfDay 字段。 YearDay 是当年过去的天数,TimeOfDay 是当天过去的秒数(最多 86400)。 YearDay 是一个 int32,而 TimeOfDay 是一个 float64。
我想将其转换为 time.Now().UnixNano() 形式,但不确定如何转换。时间模块有一个 YearDay(),但没有给定 yearDay (int32)(可能是一年)的反函数来给我一个月中的月份和日期。
理想情况下,我想以某种方式解析
d := time.Date(time.Year(), month, day, hour, min, sec, ms, time.UTC)
月、日、时、分、秒、毫秒以某种方式预先确定,或者我可以轻松转换为我想要的任何形式的等价物(但主要是 UnixNano())。
我最好的想象是一个复杂的 switch 语句,它减去 31、28(29)、30、31 ... 并查看 int 何时最终为负数以找到月份和日期,但它必须是两个带有闰年检查的 switch 语句以选择要使用的 switch 块,同时在 TimeOfDay 上进行几个余数计算。有没有更简单更干净的方法?
编辑:我在玩弄它时最终实现了以下功能,但我肯定会使用 Icza 的解决方案。很高兴知道日子会溢出来。谢谢!
func findMonthAndDay(yearDay int32) (int32, int32) {
year := time.Now().Year()
isLeapYear := year%400 == 0 || year%4 == 0 && year%100 != 0 // Calculates if current year is leapyear
// Determines which array to send to for loop
var monthsOfYear [12]int32
if isLeapYear {
monthsOfYear = [12]int32{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
} else {
monthsOfYear = [12]int32{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
}
var currentMonth int32
var currentDayInMonth int32
// Loop through array of months
for i := range monthsOfYear {
// If yearDay - next month #OfDays positive, not correct month
if yearDay-monthsOfYear[i] > 0 {
// Subtract month #OfDays and continue
yearDay = yearDay - monthsOfYear[i]
} else {
currentMonth = int32(i + 1) // Month found (+1 due to index at 0)
currentDayInMonth = yearDay // Remainder of YearDay is day in month
break
}
}
return currentMonth, currentDayInMonth
}
您可以使用 Time.AddDate()
to add the number of days to a time.Time
值。添加天数大于31是可以的,实现归一化结果。
并将 TimeOfDay
转换为 time.Duration
and use Time.Add()
以添加它。当转换为time.Duration
时,我们可以将它乘以1e9
得到纳秒数,所以小数秒将被保留。
示例:
t := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
fmt.Println(t)
var yearDay int32 = 100
var timeOfDay float64 = 70000.5
t = t.AddDate(0, 0, int(yearDay))
t = t.Add(time.Duration(timeOfDay * 1e9))
fmt.Println(t)
fmt.Println("Unix:", t.Unix())
fmt.Println("UnixNano:", t.UnixNano())
输出(在 Go Playground 上尝试):
2020-01-01 00:00:00 +0000 UTC
2020-04-10 19:26:40.5 +0000 UTC
Unix: 1586546800
UnixNano: 1586546800500000000