How to convert time interval in days to human readable form?

592 views
Skip to first unread message

Constantine Vassilev

unread,
Jan 24, 2020, 12:06:12 PM1/24/20
to golang-nuts
I have the following task:

1) a number representing days.
2) how to convert it to human readable form?

Like this:
11 years 3 months 5 days

The actual calculations are:

4095 days = 136.5 months = 11.375 years


Christian Mauduit

unread,
Jan 24, 2020, 12:12:43 PM1/24/20
to golan...@googlegroups.com
If the only input you have is a number of days, as opposed to a start
date and a finish date, it is not possible to convert it in years/months
as the length of the years, as well as the length of the years, vary
over time. Years can range from 365 to 366 days. Months can range from
28 to 31 days.

As a side note, I am not sure this is strictly Go related.

Have a nice day,

Christian.
> --
> You received this message because you are subscribed to the Google
> Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to golang-nuts...@googlegroups.com
> <mailto:golang-nuts...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/4534a893-73f1-495a-be64-1992a3b4819f%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/4534a893-73f1-495a-be64-1992a3b4819f%40googlegroups.com?utm_medium=email&utm_source=footer>.

--
Christian Mauduit __/\__ ___
uf...@ufoot.org \~ ~ / (`_ \ ___
https://ufoot.org /_o _\ \ \_/ _ \_
int q = (2 * b) || !(2 * b); \/ \___/ \__)

Constantine Vassilev

unread,
Jan 24, 2020, 12:20:26 PM1/24/20
to golang-nuts
I've the start-end date, then how to do that?

Michael Jones

unread,
Jan 24, 2020, 1:11:23 PM1/24/20
to Constantine Vassilev, golang-nuts
well, if you have the start and end dates (sy/sm/sd, ey/em/ed), then you can do it directly.

the number of complete years is ey-sy+1 if em>sm or em==sm && ed>=sd, one less otherwise
(i think this captures the edge conditions correctly)

same for months (irrespective of the number of days in each), and same for days, simplified since hours, minutes, and seconds are not being used.

you do not need to do a calendrical base conversion (with the issues Christian shared) now that we realize that you have the start and end details.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/70cc09a4-0c57-4683-b7b1-de45afcdff6d%40googlegroups.com.


--
Michael T. Jones
michae...@gmail.com

Jason E. Aten

unread,
Jan 24, 2020, 11:04:28 PM1/24/20
to golang-nuts
On Friday, January 24, 2020 at 12:20:26 PM UTC-5, Constantine Vassilev wrote:
I've the start-end date, then how to do that?

Look at the time package (https://golang.org/pkg/time/). In particular, time.Date() https://golang.org/pkg/time/#Date is your friend for making a time.Time for any date. 

Also "4d63.com/tz" package (https://github.com/leighmcculloch/go-tz) is useful for being portable to windows, where Go's timezones are missing/broken by default (https://github.com/golang/go/issues/21881 ). 

You don't have to use UTC if you know the time.Location in the following example. 

import "time"

// Date represents a UTC time zone day
type Date struct {
    Year  int 
    Month int 
    Day   int 
}

// ToGoTime turns the date into UTC time.Time, at the 0 hrs 0 min 0 second start of the day.
func (d *Date) ToGoTime() time.Time {
    return time.Date(d.Year, time.Month(d.Month), d.Day, 0, 0, 0, 0, time.UTC)
}

func DaysBetweenAminusB(a, b *Date) int {
    return int(int64(a.ToGoTime().Sub(b.ToGoTime())) / int64(time.Hour*24))

Display of a time.Time is a simple matter of choosing one of the formats in time (see the Constants section at the top), and using Format() https://golang.org/pkg/time/#Time.Format

e.g.

import "4d63.com/tz"
import "fmt"
import "time"

var d Date
var NYC *time.Location
NYC, err = tz.LoadLocation("America/New_York")
if err != nil {panic(err)}

hr := 12 // noon
min := 0
sec := 0
msec := 0

tm := time.Date(d.Year, time.Month(d.Month), d.Day, hr, min, sec, msec*1e6, NYC)

fmt.Printf("%v", tm.In(NYC).Format(time.RFC3339Nano))

Jason E. Aten

unread,
Jan 24, 2020, 11:08:33 PM1/24/20
to golang-nuts
Also note if you need extreme accuracy, that if you are crossing a daylight saving time adjustment boundary, then the integer division above can be off. If that is a problem, you may want to divide in float64 space and then round instead.

Jason E. Aten

unread,
Jan 24, 2020, 11:12:27 PM1/24/20
to golang-nuts
Finally, simple time.Durations know how to print themselves directly, and time.Sub() produces a Duration.

So if you have 

var tm1, tm2 time.Time

you can do

fmt.Printf("difference = %v\n", tm2.Sub(tm1)) // subtraction yields a time.Dur
Reply all
Reply to author
Forward
0 new messages