developer747
developer747

Reputation: 15928

Go parse time to string and back

I am trying to do something in Go that is very simple in languages like Java

I want to parse current time to string and then parse it back to time.

This is the code I tried but as can be seen here it gives unexpected results.

I am facing two problems

  1. time.Now().String() gives a wrong date
  2. If I cast the time to string and cast it back to time, it gives a totally different date.

What is the right (and easy) way to do this?

        p := fmt.Println
startStr := time.Now().String()   //2009-11-10 23:00:00 +0000 UTC m=+0.000000001
p(startStr)

startTime, _ := time.Parse(
    "2009-11-10 23:00:00 +0000 UTC m=+0.000000001",
    startStr)

p(startTime)             //0001-01-01 00:00:00 +0000 UTC

Upvotes: 1

Views: 8052

Answers (3)

nguyenhoai890
nguyenhoai890

Reputation: 1219

The time in the playground is fixed, it is always the date and time of the Go announcement.

https://github.com/golang/go/issues/10663

So to play with time correctly, you need to run it on your local.

About the parsing time to string or back, you have to pass the format of time string: For example:

package main

import (
    "fmt"
    "time"
)

func main() {
    current := time.Now()
    fmt.Println("Init Time:", current.String())
    timeCustomFormatStr := current.Format("2006-01-02 15:04:05 -0700")
    fmt.Println("Custom format", timeCustomFormatStr)
    parsedTime, err := time.Parse("2006-01-02 15:04:05 -0700",timeCustomFormatStr)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("parsedTime From Custom:", parsedTime)

    timeFormatRFC3339 := current.Format(time.RFC3339)
    fmt.Println("RFC3339 format", timeFormatRFC3339)

    parsedTimeRFC3339, err := time.Parse(time.RFC3339,timeFormatRFC3339)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("parsedTime From Custom:", parsedTimeRFC3339)
}

Ref: 1 https://golang.org/pkg/time/#Time.Format

Upvotes: 0

Robert Nubel
Robert Nubel

Reputation: 7522

Unlike some other languages, Go does not treat String() as a de facto marshaling method -- instead, it's meant just to print the value out for debugging purposes. You could parse back from that format into a Time if you used a proper format string; however, a proper format string must be for the exact time of Mon Jan 2 15:04:05 MST 2006, not any time; but the format that String() prints out isn't captured by a constant within the Time package so it's probably not worth doing.

Instead, however, what you're trying to do may be better captured by the MarshalText and UnmarshalText methods:

startStr, _ := time.Now().MarshalText()
fmt.Println(string(startStr)) // 2009-11-10T23:00:00Z

startTime := new(time.Time)
startTime.UnmarshalText(startStr)

fmt.Println(startTime) // 2009-11-10 23:00:00 +0000 UTC

Upvotes: 3

Shang Jian Ding
Shang Jian Ding

Reputation: 2126

time.Now().String() is meant for debugging only (see go doc).

You should instead use time.Format().

For example:

    p := fmt.Println
    now := time.Now().Format(time.RFC3339)
    p(now)

    parsed, _ := time.Parse(time.RFC3339, now)
    p(parsed.Format(time.RFC3339))

produces:

2009-11-10T23:00:00Z
2009-11-10T23:00:00Z

Your other concern regarding time.Now().String() gives a wrong date is likely due to where you're running the code. e.g. if you're running in "The Go Playgounrd", then the time won't be accurate. You should run it on your own computer, and assuming your computer has the correct time, then you should get the right time printed.

Upvotes: 7

Related Questions