猿问

Golang - 从 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 语句闰年检查以选择使用哪个开关块,同时在 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

}


杨__羊羊
浏览 188回答 1
1回答

郎朗坤

您可以使用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 = 100var timeOfDay float64 = 70000.5t = 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 UTC2020-04-10 19:26:40.5 +0000 UTCUnix: 1586546800UnixNano: 1586546800500000000
随时随地看视频慕课网APP

相关分类

Go
我要回答