time.Since() with months and years

前端 未结 5 1668
悲哀的现实
悲哀的现实 2020-12-01 11:20

I am trying to convert a timestamp like this:

2015-06-27T09:34:22+00:00

to a time since format so it would say like 9 months ago 1 day 2 ho

5条回答
  •  隐瞒了意图╮
    2020-12-01 11:37

    The solution proposed by izca is great, but it misses one thing. If you add the following example, you can see the effect:

    a = time.Date(2015, 1, 11, 0, 0, 0, 0, time.UTC)
    b = time.Date(2015, 3, 10, 0, 0, 0, 0, time.UTC)
    fmt.Println(diff(a, b))
    // Expected: 0 1 27 0 0 0
    // Actual output: 0 1 30 0 0 0
    

    playground

    The code is calculating the remaining days of the next incomplete month based on the total days of the first month (y1,M1), but it needs to be computed from the previous month of the later date month (y2,M2-1).

    The final code is as follows:

    package main
    
    import (
        "fmt"
        "time"
    )
    
    
    func DaysIn(year int, month time.Month) int {
        return time.Date(year, month+1, 0, 0, 0, 0, 0, time.UTC).Day()
    }
    
    func Elapsed(from, to time.Time) (inverted bool, years, months, days, hours, minutes, seconds, nanoseconds int) {
        if from.Location() != to.Location() {
            to = to.In(to.Location())
        }
    
        inverted = false
        if from.After(to) {
            inverted = true
            from, to = to, from
        }
    
        y1, M1, d1 := from.Date()
        y2, M2, d2 := to.Date()
    
        h1, m1, s1 := from.Clock()
        h2, m2, s2 := to.Clock()
    
        ns1, ns2 := from.Nanosecond(), to.Nanosecond()
    
        years = y2 - y1
        months = int(M2 - M1)
        days = d2 - d1
    
        hours = h2 - h1
        minutes = m2 - m1
        seconds = s2 - s1
        nanoseconds = ns2 - ns1
    
        if nanoseconds < 0 {
            nanoseconds += 1e9
            seconds--
        }
        if seconds < 0 {
            seconds += 60
            minutes--
        }
        if minutes < 0 {
            minutes += 60
            hours--
        }
        if hours < 0 {
            hours += 24
            days--
        }
        if days < 0 {
            days += DaysIn(y2, M2-1)
            months--
        }
        if months < 0 {
            months += 12
            years--
        }
        return
    }
    
    func main() {
        var a, b time.Time
        a = 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(Elapsed(a, b)) // Expected: false 1 1 1 1 1 1
    
        a = 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(Elapsed(a, b)) // Expected: false 0 0 30 0 0 0
    
        a = 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(Elapsed(a, b)) // Expected: false 0 0 28 0 0 0
    
        a = 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(Elapsed(a, b)) // Expected: false 0 11 1 0 0 0
    
        a = time.Date(2015, 1, 11, 0, 0, 0, 0, time.UTC)
        b = time.Date(2015, 3, 10, 0, 0, 0, 0, time.UTC)
        fmt.Println(Elapsed(a, b)) // Expected: false 0 1 27 0 0 0
    }
    

    playground

提交回复
热议问题