Go dateparse of one library per day

Time:2021-11-20

brief introduction

No matter when, processing time is always a headache. Because the time format is too diverse, plus time zone, daylight saving time and leap seconds, it is more difficult to deal with these details. Therefore, when dealing with time in the program, we usually use the standard library or the time library provided by a third party. What to introduce todaydateparseFocus on a very small area of time processing — parsing strings in date time format.

Quick 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

installdateparseLibrary:

$ 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 time string, parses the string, and returnstime.TimeValue of type. If the incoming stringdateparseIf the library is not recognized, an error is returned. Operation 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 of “3 / 1 / 2014”, it can be interpreted asMarch 1, 2014, can also be interpreted asJanuary 3, 2014。 There is ambiguity,dateparseDefault usemm/dd/yyyyThis format, that isMarch 1, 2014。 We can also useParseStrict()The function failed to parse this ambiguous string:

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"))
}

function:

$ 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

dateparseIt supports rich date and time formats, basically including all commonly used formats. It supports standard librariestimeAll predefined formats in:

// 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"
)

See dateparse readme for the full supported formats.

time zone

dateparseSupports parsing date time strings in a specific time zone. We can call thetime.LoadLocation()Method to obtain the time zone object by passing in the time zone identification string. The time zone identification string is similarAsia/ShanghaiAmerica/ChicagoIn this format, it represents a specific time zone, the former Shanghai and the latter Los Angeles. calldateparse.ParseIn()Method to pass in a time zone object and resolve it in the specified time zone.timeTwo time zone objects are also predefined in the package,time.LocalRepresents the local time zone,time.UTCRepresents the UTC time zone. Please refer to IANA for the authoritative data of time zone.

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"))
}

function:

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

“15:30:30 on June 24, 2021” in Los Angeles time zone is equal to “04:50:30 on June 25, 2021” in local time zone (Beijing time).

cli

dateparseA command-line tool is also provided to view date and time formats very quickly. Installation:

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

Installed by default$GOPATHUnder the path, I’m used to$GOPATH/binput to$PATHYes. thereforedateparseCommands can be used directly.

dateparseThe 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, format string (which can be used to generate date time string in the same format) and a table. The data in the table are correct respectivelyParseAny/ParseIn/ParseLocal/ParseStrictThe result of calling in different time zones.

methodList the methods called,Zone SourceThe list shows the values set to the local time zone,ParsedColumn is called as a datetime stringParseAny()Returnedtime.TimeObjectFormat()Method call results,Parsed: t.In(time.UTC)Listed in the returnedtime.TimeObject callFormat()Method to UTC time.

becauseParseAny/ParseStrictThe local time zone will not be considered. The strings are parsed in UTC, so the results in the last two columns of these six lines are the same.

ParseInThe second line of willtime.LocalSet it to the time zone we set through the command line option. Above, I set it toAsia/Shanghai, the corresponding UTC time differs by 8 hours.ParseLocalThe same is true.

Here isdateparseSome of the source code of the command line 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 represent the standard time of the United States, Australia, China and Cuba at the same time.

summary

usedateparseThe time object and layout can be easily parsed from the date time string. meanwhiledateparseThe command line can quickly view and convert the time of the corresponding time zone. It is a very good gadget.

If you find a fun and easy-to-use go language library, you are welcome to submit an issue on GitHub, the daily library of go

reference resources

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

I

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

Welcome to my WeChat official account, GoUpUp, learn together and make progress together.