3

Introduction

No matter when, processing time is always a headache. Because the time format is too diversified, coupled with the time zone, daylight saving time, leap seconds, these minutiae are more difficult to deal with. Therefore, in the program, we generally use the standard library or the time library provided by the third party to deal with the time. dateparse will introduce today focuses on a very small area of time processing-parsing date and time format strings.

Quick to use

The code in this article uses Go Modules.

Create a directory and initialize:

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

Install the dateparse library:

$ go get -u github.com/araddon/dateparse

use:

package main

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

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

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

ParseAny() method accepts a date and time string, parses the string, and returns a value of type time.Time If the incoming string dateparse not recognized by the library, an error will be returned. The output of the above program:

$ 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

It should be noted that when we write the time "3/1/2014", it can be interpreted as March 1, 2014 , or January 3, 2014 . That there is ambiguity, dateparse defaults mm/dd/yyyy this format, which is 2014 Nian 3 Yue 1 Ri . We can also use the ParseStrict() function to make this ambiguous string parsing fail:

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

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

format

dateparse supports rich date and time formats, basically covering all commonly used formats. It supports all formats predefined in the 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 = "2006-01-02T15:04:05.999999999Z07: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"
)

For the full format supported, see dateparse README .

Time zone

dateparse supports parsing date and time strings in a specific time zone. We can get the time zone object by calling the time.LoadLocation() method of the standard library and passing in the time zone identification string. The time zone identification string is in Asia/Shanghai and America/Chicago , which represents a specific time zone, the former is Shanghai and the latter is Los Angeles. Call the dateparse.ParseIn() method to pass in the time zone object and parse it in the specified time zone. time package also predefines two time zone objects. time.Local represents the local time zone, and time.UTC represents the UTC time zone. For authoritative data on time zones, please see IANA .

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

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

run:

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

"15:30:30 on June 24, 2021" in the Los Angeles time zone of the United States is equal to "04:50:30 on June 25, 2021" in the local time zone (Beijing time).

cli

dateparse also provides a command line tool for viewing the date and time format extremely quickly. installation:

$ go install github.com/araddon/dateparse/dateparse

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

dateparse command receives a string and an optional time zone option:

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

Your Current time.Local zone is CST

Layout String: dateparse.ParseFormat() => 2006-01-02 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       |
+-------------+---------------------------+-------------------------------+-------------------------------------+

Output the current local time zone, a format string (can be used to generate a date and time string in the same format) and a table. The data in the table is ParseAny/ParseIn/ParseLocal/ParseStrict in different time zones.

method column represents a method call, Zone Source column represents the value of the local time zone, Parsed column is datetime string called a ParseAny() returned time.Time object Format() result of a call, Parsed: t.In(time.UTC) listed in the returned time.Time calling object Format() former method thereof Converted to UTC time.

Since ParseAny/ParseStrict does not consider the local time zone, the string is parsed in UTC, so the results in the last two columns of these 6 rows are the same.

ParseIn the second line of time.Local , set 060da7eb04f9d8 to the time zone we set through the command line option. I set it to Asia/Shanghai above, which corresponds to a UTC time difference of 8 hours. ParseLocal is true for 060da7eb04f9dc.

The following is dateparse command line, which can be viewed by comparison:

func main() {
  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))
    if timezone != "" {
      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)
  if err != nil {
    return err.Error()
  }
  if utc {
    return t.In(time.UTC).String()
  }
  return t.String()
}

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 UT-4:00

CST can simultaneously represent the standard time of the four countries of the United States, Australia, China and Cuba.

to sum up

Using dateparse can easily parse the time object and format (layout) from the date and time string. At the same time, the dateparse command line can quickly view and convert the time in the corresponding time zone, which is a very good small tool.

If you find a fun and useful Go language library, welcome to submit an issue on the Go Daily Library GitHub😄

reference

  1. dateparse GitHub:github.com/araddon/dateparse
  2. Go daily one library GitHub: https://github.com/darjun/go-daily-lib

I

My blog: https://darjun.github.io

Welcome to follow my WeChat public account [GoUpUp], learn together and make progress together~


darjun
2.9k 声望356 粉丝