Introduction to the

Dealing with time can be a headache at any given time. With so many different time formats, the nuances of time zones, daylight saving time and leap seconds are harder to deal with. So in the program, we usually rely on the standard library or third-party library for processing time. Dateparse, which I’ll introduce today, focuses on a very small area of time processing — parsing date-time format strings.

Quick to use

The code in this article uses Go Modules.

Create directory and initialize:

$ mkdir dateparse && cd dateparse
$ go mod init github.com/darjun/go-daily-lib/dateparse
Copy the code

To install the Dateparse library:

$ go get -u github.com/araddon/dateparse
Copy the code

Use:

package main

import (
  "fmt"
  "log"
  "github.com/araddon/dateparse"
)

func main(a) {
  t1, err := dateparse.ParseAny("3/1/2014")
  iferr ! =nil {
    log.Fatal(err)
  }
  fmt.Println(t1.Format("The 2006-01-02 15:04:05"))

  t2, err := dateparse.ParseAny("mm/dd/yyyy")
  iferr ! =nil {
    log.Fatal(err)
  }
  fmt.Println(t2.Format("The 2006-01-02 15:04:05"))}Copy the code

The ParseAny() method takes a date-time string, parses it, and returns a value of type time.time. If the string passed in is not recognized by the Dateparse library, an error is returned. The above program runs output:

$ go run main.go
2014- 03- 01 00:00:00
2021/06/24 14:52:39 Could not find format for "mm/dd/yyyy"
exit status 1
Copy the code

Notice that when we write the date “3/1/2014”, it can be interpreted as March 1, 2014, or it can be interpreted as January 3, 2014. This is ambiguous because DateParse defaults to mm/ DD/YYYY, which is March 1, 2014. We can also fail this ambiguous string parsing using the ParseStrict() function:

func main(a) {
  t, err := dateparse.ParseStrict("3/1/2014")
  iferr ! =nil {
    log.Fatal(err)
  }
  fmt.Println(t.Format("The 2006-01-02 15:04:05"))}Copy the code

Run:

$ go run main.go
2021/06/24 14:57:18 This date has ambiguous mm/dd vs dd/mm type format
exit status 1
Copy the code

format

Dateparse supports rich date and time formats, covering almost all common formats. It supports all the formats predefined in the standard library Time:

// src/time/format.go
const (
  ANSIC       = "Mon Jan _2 15:04:05 2006"
  UnixDate    = "Mon Jan _2 15:04:05 MST 2006"
  RubyDate    = "Mon Jan 02 15:04:05 -0700 2006"
  RFC822      = "02 Jan 06 15:04 MST"
  RFC822Z     = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
  RFC850      = "Monday, 02-Jan-06 15:04:05 MST"
  RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST"
  RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
  RFC3339     = "2006-01-02T15:04:05Z07:00"
  RFC3339Nano = "The 2006-01-02 T15:04:05. 999999999 z07:00"
  Kitchen     = "3:04PM"
  // Handy time stamps.
  Stamp      = "Jan _2 15:04:05"
  StampMilli = "Jan _2 15:04:05. 000." "
  StampMicro = "Jan _2 15:04:05. 000000." "
  StampNano  = "Jan _2 15:04:05. 000000000." "
)
Copy the code

See dateParse README for the full format supported.

The time zone

Dateparse supports the parsing of date and time strings in specific time zones. We can get the time zone object by calling the library’s time.loadLocation () method, passing in the time zone identifier string. The time zone identifier string is in formats such as Asia/Shanghai and America/Chicago. It indicates a specific time zone. Shanghai is the former and Los Angeles is the latter. Call the dateparse.parsein () method to pass in the time zone object, which is parsed in the specified time zone. Two time zone objects are predefined in the time package, time.Local for the Local time zone and time.UTC for the UTC time zone. For definitive data on time zones, see IANA.

func main(a) {
  tz1, _ := time.LoadLocation("America/Chicago")
  t1, _ := dateparse.ParseIn("The 2021-06-24 15:50:30", tz1)
  fmt.Println(t1.Local().Format("The 2006-01-02 15:04:05"))

  t2, _ := dateparse.ParseIn("The 2021-06-24 15:50:30", time.Local)
  fmt.Println(t2.Local().Format("The 2006-01-02 15:04:05"))}Copy the code

Run:

$ go run main.go
2021- 06- 25 04:50:30
2021- 06- 24 15:50:30
Copy the code

The value of “June 24, 2021 15:30:30” in the Los Angeles time zone is equal to the value of “June 25, 2021 04:50.30” in the local time zone (Beijing time).

cli

Dateparse also provides a command-line tool for viewing date and time formats very quickly. Installation:

$ go install github.com/araddon/dateparse/dateparse
Copy the code

By default, it will be installed in the $GOPATH PATH. I used to put $GOPATH/bin in the $PATH. So the dateparse command can be used directly.

The dateparse command accepts a string and an optional time zone option:

$ dateparse --timezone="Asia/Shanghai" "The 2021-06-24 06:46:08"

Your Current time.Local zone is CST

Layout String: dateparse.ParseFormat() => 2006- 01. 15:04:05

Your Using time.Local set to location=Asia/Shanghai CST

+-------------+---------------------------+-------------------------------+-------------------------------------+
| method      | Zone Source               | Parsed                        | Parsed: t.In(time.UTC)              |
+-------------+---------------------------+-------------------------------+-------------------------------------+
| ParseAny    | time.Local = nil          | 2021- 06- 24 06:46:08 +0000 UTC | 2021- 06- 24 06:46:08 +0000 UTC day=4 |
| ParseAny    | time.Local = timezone arg | 2021- 06- 24 06:46:08 +0000 UTC | 2021- 06- 24 06:46:08 +0000 UTC day=4 |
| ParseAny    | time.Local = time.UTC     | 2021- 06- 24 06:46:08 +0000 UTC | 2021- 06- 24 06:46:08 +0000 UTC day=4 |
| ParseIn     | time.Local = nil          | 2021- 06- 24 06:46:08 +0000 UTC | 2021- 06- 24 06:46:08 +0000 UTC       |
| ParseIn     | time.Local = timezone arg | 2021- 06- 24 06:46:08 +0800 CST | 2021- 06- 23 22:46:08 +0000 UTC       |
| ParseIn     | time.Local = time.UTC     | 2021- 06- 24 06:46:08 +0000 UTC | 2021- 06- 24 06:46:08 +0000 UTC       |
| ParseLocal  | time.Local = nil          | 2021- 06- 24 06:46:08 +0000 UTC | 2021- 06- 24 06:46:08 +0000 UTC       |
| ParseLocal  | time.Local = timezone arg | 2021- 06- 24 06:46:08 +0800 CST | 2021- 06- 23 22:46:08 +0000 UTC       |
| ParseLocal  | time.Local = time.UTC     | 2021- 06- 24 06:46:08 +0000 UTC | 2021- 06- 24 06:46:08 +0000 UTC       |
| ParseStrict | time.Local = nil          | 2021- 06- 24 06:46:08 +0000 UTC | 2021- 06- 24 06:46:08 +0000 UTC       |
| ParseStrict | time.Local = timezone arg | 2021- 06- 24 06:46:08 +0000 UTC | 2021- 06- 24 06:46:08 +0000 UTC       |
| ParseStrict | time.Local = time.UTC     | 2021- 06- 24 06:46:08 +0000 UTC | 2021- 06- 24 06:46:08 +0000 UTC       |
+-------------+---------------------------+-------------------------------+-------------------------------------+
Copy the code

Outputs the current local time zone, the format string (which can be used to generate date-time strings in the same format), and a table. The inside of the form data is investigated ParseAny/ParseIn/ParseLocal/ParseStrict cut with the result of in different time zones.

The method column represents the method called, the Zone Source column represents the value set to the local time Zone, and the Parsed column is the result of the Format() method call to the time.time object returned by calling ParseAny() on the date-time string. Parsed: The T.INN (time.UTC) column converts the returned time.time object to UTC time before calling the Format() method.

Since ParseAny/ParseStrict does not consider the local time zone and parses the string in UTC, the last two columns of the six lines are the same.

The second line of ParseIn sets time.Local to the time zone we set through the command line option, above I set it to Asia/Shanghai, corresponding to the UTC time difference of 8 hours. So is ParseLocal.

The dateparse command line can be viewed as follows:

func main(a) {
  parsers := map[string]parser{
    "ParseAny":    parseAny,
    "ParseIn":     parseIn,
    "ParseLocal":  parseLocal,
    "ParseStrict": parseStrict,
  }

  for name, parser := range parsers {
    time.Local = nil
    table.AddRow(name, "time.Local = nil", parser(datestr, nil.false), parser(datestr, nil.true))
    iftimezone ! ="" {
      time.Local = loc
      table.AddRow(name, "time.Local = timezone arg", parser(datestr, loc, false), parser(datestr, loc, true))
    }
    time.Local = time.UTC
    table.AddRow(name, "time.Local = time.UTC", parser(datestr, time.UTC, false), parser(datestr, time.UTC, true))}}func parseIn(datestr string, loc *time.Location, utc bool) string {
  t, err := dateparse.ParseIn(datestr, loc)
  iferr ! =nil {
    return err.Error()
  }
  if utc {
    return t.In(time.UTC).String()
  }
  return t.String()
}
Copy the code

Note that the output local time zone is CST, which can represent different time zones:

Central Standard Time (USA) UT- 6:00
Central Standard Time (Australia) UT+9:30
China Standard Time UT+8:00
Cuba Standard Time UT4 -:00
Copy the code

CST can stand for the standard time of the United States, Australia, China and Cuba.

conclusion

Dateparse makes it easy to parse out time objects and layouts from date and time strings. The Dateparse command line is a great tool for quickly viewing and converting time zones.

If you find a fun and useful Go library, please Go to GitHub and submit issue😄

reference

  1. Dateparse GitHub:github.com/araddon/dat…
  2. GitHub: github.com/darjun/go-d…

I

My blog is darjun.github. IO

Welcome to follow my wechat public account [GoUpUp], learn together, progress together ~