我有一个固定的数据结构,该结构具有字段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最终为负数时才能找到月份和日期,但是它必须是两个带有进行year年检查以选择要使用的开关块,同时在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()
将天数添加到 time.Time
值中。可以添加大于31的天数,实现将结果标准化。
并将TimeOfDay
转换为 time.Duration
并使用 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