栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

time.Since()与月和年

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

time.Since()与月和年

前言:
我在中发布了此实用程序

github.com/icza/gox
,请参见
timex.Diff()


就像一年中的日子(le年)一样,一个月中的日子取决于日期。

如果

time.Since()
用于获取自一个
time.Time
值以来的经过时间,或者
time.Time
使用该
Time.Sub()
方法计算两个值之间的差,则结果为a
time.Duration
,它会丢失时间上下文(
Duration
正好是以纳秒为单位的时间差)。这意味着您不能根据一个
Duration
值准确无误地计算出年,月等的差异。

正确的解决方案必须在时间范围内计算差异。您可以计算每个字段(年,月,日,小时,分钟,秒)的差异,然后将结果归一化为没有任何负值。

Time
如果不期望它们之间的关系,也建议交换这些值。

归一化表示如果值是负数,则将该字段的最大值加1,然后将下一个字段减1。例如,如果

seconds
是负数,则将
60
其加减
minutes
1。例如,当归一化天数之差时要注意的一件事(每月的天数),则必须应用适当月份中的天数。这个小技巧很容易计算出:

// Max days in year y1, month M1t := time.Date(y1, M1, 32, 0, 0, 0, 0, time.UTC)daysInMonth := 32 - t.Day()

这背后的逻辑是,该天

32
大于任何月份的最大天数。它将自动归一化(额外的天数滚动到下个月,并且天数适当减少)。当我们从32减去归一化后的天时,我们确切地得到了该月的最后一天。

时区处理:

仅当我们传递的两个时间值都在同一时区(

time.Location
)时,差异计算才会给出正确的结果。我们将检查合并到函数中:如果不是这种情况,则使用以下
Time.In()
方法将时间值之一“转换”为与另一个时间值相同的位置:

if a.Location() != b.Location() {    b = b.In(a.Location())}

这是一个计算年,月,日,小时,分钟,秒之间差异的解决方案:

func diff(a, b time.Time) (year, month, day, hour, min, sec int) {    if a.Location() != b.Location() {        b = b.In(a.Location())    }    if a.After(b) {        a, b = b, a    }    y1, M1, d1 := a.Date()    y2, M2, d2 := b.Date()    h1, m1, s1 := a.Clock()    h2, m2, s2 := b.Clock()    year = int(y2 - y1)    month = int(M2 - M1)    day = int(d2 - d1)    hour = int(h2 - h1)    min = int(m2 - m1)    sec = int(s2 - s1)    // Normalize negative values    if sec < 0 {        sec += 60        min--    }    if min < 0 {        min += 60        hour--    }    if hour < 0 {        hour += 24        day--    }    if day < 0 {        // days in month:        t := time.Date(y1, M1, 32, 0, 0, 0, 0, time.UTC)        day += 32 - t.Day()        month--    }    if month < 0 {        month += 12        year--    }    return}

一些测试:

var a, b time.Timea = time.Date(2015, 5, 1, 0, 0, 0, 0, time.UTC)b = time.Date(2016, 6, 2, 1, 1, 1, 1, time.UTC)fmt.Println(diff(a, b)) // Expected: 1 1 1 1 1 1a = time.Date(2016, 1, 2, 0, 0, 0, 0, time.UTC)b = time.Date(2016, 2, 1, 0, 0, 0, 0, time.UTC)fmt.Println(diff(a, b)) // Expected: 0 0 30 0 0 0a = time.Date(2016, 2, 2, 0, 0, 0, 0, time.UTC)b = time.Date(2016, 3, 1, 0, 0, 0, 0, time.UTC)fmt.Println(diff(a, b)) // Expected: 0 0 28 0 0 0a = time.Date(2015, 2, 11, 0, 0, 0, 0, time.UTC)b = time.Date(2016, 1, 12, 0, 0, 0, 0, time.UTC)fmt.Println(diff(a, b)) // Expected: 0 11 1 0 0 0

输出是预期的:

1 1 1 1 1 10 0 30 0 0 00 0 28 0 0 00 11 1 0 0 0

在Go Playground上尝试一下。

要计算您的年龄,请执行以下操作:

// Your birthday: let's say it's January 2nd, 1980, 3:30 AMbirthday := time.Date(1980, 1, 2, 3, 30, 0, 0, time.UTC)year, month, day, hour, min, sec := diff(birthday, time.Now())fmt.Printf("You are %d years, %d months, %d days, %d hours, %d mins and %d seconds old.",    year, month, day, hour, min, sec)

输出示例:

You are 36 years, 3 months, 8 days, 11 hours, 57 mins and 41 seconds old.

Go游乐场时间开始的不可思议的日期/时间是:

2009-11-10 23:00:00 UTC

这是Go首次宣布的时间。让我们计算Go的年龄:

goAnnounced := time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC)year, month, day, hour, min, sec := diff(goAnnounced, time.Now())fmt.Printf("Go was announced "+    "%d years, %d months, %d days, %d hours, %d mins and %d seconds ago.",    year, month, day, hour, min, sec)

输出:

Go was announced 6 years, 4 months, 29 days, 16 hours, 53 mins and 31 seconds ago.


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/413073.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号