mfish
mfish

Reputation: 11

How to convert time.Time object to formatted string using .Format in golang?

I'm currently attempting to fetch a time.Time object from my SQL database and convert the retrieved value to a formatted string that looks like so:

TIME_FORMAT := "%Y-%m-%dT%H:%M:%S"

This is the format I have used to do the same thing in Python, but I know it is not correct for go. I have already grabbed the value from the DB, and now just need to format it. Please note I have defined ccc.Ia_date as interface{} type because it is possible that this value in the DB could be null. Here is a clip of my code:

fmt.Println(reflect.TypeOf(ccc.Ia_date))  //gives me time.Time
t := ccc.Ia_date //which prints as: 2016-11-16 21:06:39 +0000 +0000
fmt.Println(t.Format())

and I get the following error:

t.Format undefined (type interface {} is interface with no methods)

Am I missing an import? Or is this just not possible using interface types? If so, what alternatives do I have to accept null values from the DB? (I have already seen the related answer to Golang: convert time.Time to string - I tried that solution but I'm not grabbing time.Now and that's the only difference I see)

Upvotes: 0

Views: 3823

Answers (2)

Kaedys
Kaedys

Reputation: 10128

You have multiple issues. First off, if ccc.Ia_date is an interface{}, you must type-assert it to a time.Time before you can use any methods of a time.Time. You can do this using the two-argument type-assertion form to avoid panics:

t, ok := ccc.Ia_date.(time.Time)
if !ok {
    // wrong type or nil value, handle it
}
t.Format(timeFormat)

You also need to define your format string. The format string is defined as a standardized date and time, that being Mon Jan 2 15:04:05 -0700 MST 2006. So for your format, you want:

time_format := "2006-01-02T15:04:05"
t.Format(timeFormat)

However, this lacks a timezone. It is also nearly identical to RFC3339 ("2006-01-02T15:04:05Z07:00"), which you can use instead:

t.Format(time.RFC3339)

Upvotes: 0

icza
icza

Reputation: 417512

If you have an interface{} value holding a time.time value, you may use type assertion to obtain the wrapped time.Time:

if t, ok := ccc.Ia_date.(time.Time); ok {
    // here t is of type time.Time, and so you can call its Format() method:
    fmt.Println(t.Format(layout))
} else {
    // ccc.Ia_date is not of type time.Time, or it is nil
}

Note that it would be easier to just use a pointer *time.Time if you want to allow nil, and so you don't need to use type assertion. See this answer for more details: Golang JSON omitempty With time.Time Field

If ccc.Ia_date would be of type *time.Time:

if ccc.Ia_date != nil {
    fmt.Println(ccc.Ia_date.Format(layout))
}

And the layout string for your desired format is:

layout := "2006-01-02T15:04:05"

Upvotes: 1

Related Questions