# Golang : Human readable time elapsed format such as 5 days ago

Tags : golang date-time-stamp future-past-date ago elapsed human-readable

**Problem:**

You need to convert a date time stamp such as this `02 March 1992 10:10:50`

into a human readable format such as `5 minutes ago`

, `3 years ago`

or `10 days in future`

. Also, you need to get the elapsed time from past date and amount of time to reach a future date.

How to do that?

**Solution:**

The code that follows should do the job. Basically, it takes the year, month, day, hour, minute and second differences between now and the given date time stamp. The function in the code example does not depend on `time.Since()`

or `time.Until()`

as these functions return the elapsed duration in nanoseconds instead of individual year, month, day, etc..

Here you go!

```
package main
import (
"fmt"
"math"
"strconv"
"time"
)
func RoundTime(input float64) int {
var result float64
if input < 0 {
result = math.Ceil(input - 0.5)
} else {
result = math.Floor(input + 0.5)
}
// only interested in integer, ignore fractional
i, _ := math.Modf(result)
return int(i)
}
func TimeElapsed(inputDate string, full bool) string {
var precise [8]string // this an array, not slice
var text string
var future bool // our crystal ball
layOut := "02/01/2006 15:04:05" // dd/mm/yyyy hh:mm:ss
formattedDate, err := time.Parse(layOut, inputDate)
if err != nil {
panic(err)
}
// get years, months and days
// and get hours, minutes, seconds
now := time.Now()
year2, month2, day2 := now.Date()
hour2, minute2, second2 := now.Clock()
year1, month1, day1 := formattedDate.Date()
hour1, minute1, second1 := formattedDate.Clock()
// are we forecasting the future?
if (year2 - year1) < 0 {
future = true
}
if (month2 - month1) < 0 {
future = true
}
if (day2 - day1) < 0 {
future = true
}
if (hour2 - hour1) < 0 {
future = true
}
if (minute2 - minute1) < 0 {
future = true
}
if (second2 - second1) < 0 {
future = true
}
// convert negative to positive numbers
year := math.Abs(float64(int(year2 - year1)))
month := math.Abs(float64(int(month2 - month1)))
day := math.Abs(float64(int(day2 - day1)))
hour := math.Abs(float64(int(hour2 - hour1)))
minute := math.Abs(float64(int(minute2 - minute1)))
second := math.Abs(float64(int(second2 - second1)))
week := math.Floor(day / 7)
// Ouch!, no if-else short hand - see https://golang.org/doc/faq#Does_Go_have_a_ternary_form
if year > 0 {
if int(year) == 1 {
precise[0] = strconv.Itoa(int(year)) + " year"
} else {
precise[0] = strconv.Itoa(int(year)) + " years"
}
}
if month > 0 {
if int(month) == 1 {
precise[1] = strconv.Itoa(int(month)) + " month"
} else {
precise[1] = strconv.Itoa(int(month)) + " months"
}
}
if week > 0 {
if int(week) == 1 {
precise[2] = strconv.Itoa(int(week)) + " week"
} else {
precise[2] = strconv.Itoa(int(week)) + " weeks"
}
}
if day > 0 {
if int(day) == 1 {
precise[3] = strconv.Itoa(int(day)) + " day"
} else {
precise[3] = strconv.Itoa(int(day)) + " days"
}
}
if hour > 0 {
if int(hour) == 1 {
precise[4] = strconv.Itoa(int(hour)) + " hour"
} else {
precise[4] = strconv.Itoa(int(hour)) + " hours"
}
}
if minute > 0 {
if int(minute) == 1 {
precise[5] = strconv.Itoa(int(minute)) + " minute"
} else {
precise[5] = strconv.Itoa(int(minute)) + " minutes"
}
}
if second > 0 {
if int(second) == 1 {
precise[6] = strconv.Itoa(int(second)) + " second"
} else {
precise[6] = strconv.Itoa(int(second)) + " seconds"
}
}
for _, v := range precise {
if v != "" {
// no comma after second
if v[len(v)-5:len(v)-1] != "cond" {
precise[7] += v + ", "
} else {
precise[7] += v
}
}
}
if !future {
text = " ago."
} else {
text = " in future."
}
if full {
return precise[7] + text
} else {
// return the first non-empty position
for k, v := range precise {
if v != "" {
return precise[k] + text
}
}
}
return "invalid date"
}
func main() {
fmt.Println("The date time stamp now is : ", time.Now())
fmt.Println("02 March 1992 10:10 full=true is : ", TimeElapsed("02/03/1992 10:10:10", true))
fmt.Println("02 March 1992 10:10 full=false is : ", TimeElapsed("02/03/1992 10:10:10", false))
fmt.Println("06 May 2020 17:33 full=false is : ", TimeElapsed("06/05/2020 17:33:10", false))
fmt.Println("06 May 2020 17:33 full=true is : ", TimeElapsed("06/05/2020 17:33:10", true))
fmt.Println("06 May 2017 17:33 full=false is : ", TimeElapsed("06/05/2017 17:33:10", false))
fmt.Println("06 May 2017 17:33 full=true is : ", TimeElapsed("06/05/2017 17:33:10", true))
}
```

Sample output:

The date time stamp now is : 2017-05-06 20:46:22.391247331 +0800 MYT

02 March 1992 10:10 full=true is : 25 years, 2 months, 4 days, 10 hours, 36 minutes, 12 seconds ago.

02 March 1992 10:10 full=false is : 25 years ago.

06 May 2020 17:33 full=false is : 3 years in future.

06 May 2020 17:33 full=true is : 3 years, 3 hours, 13 minutes, 12 seconds in future.

06 May 2017 17:33 full=false is : 3 hours ago.

06 May 2017 17:33 full=true is : 3 hours, 13 minutes, 12 seconds ago.

Happy time traveling!

**References:**

#### See also : Golang : Get local time and equivalent time in different time zone

Tags : golang date-time-stamp future-past-date ago elapsed human-readable

##### By Adam Ng

IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.