<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go 每日一庫(kù)之 dateparse

          共 6893字,需瀏覽 14分鐘

           ·

          2021-10-08 21:26

          簡(jiǎn)介

          不管什么時(shí)候,處理時(shí)間總是讓人頭疼的一件事情。因?yàn)闀r(shí)間格式太多樣化了,再加上時(shí)區(qū),夏令時(shí),閏秒這些細(xì)枝末節(jié)處理起來更是困難。所以在程序中,涉及時(shí)間的處理我們一般借助于標(biāo)準(zhǔn)庫(kù)或第三方提供的時(shí)間庫(kù)。今天要介紹的dateparse專注于一個(gè)很小的時(shí)間處理領(lǐng)域——解析日期時(shí)間格式的字符串。

          快速使用

          本文代碼使用 Go Modules。

          創(chuàng)建目錄并初始化:

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

          安裝dateparse庫(kù):

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

          使用:

          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()方法接受一個(gè)日期時(shí)間字符串,解析該字符串,返回time.Time類型的值。如果傳入的字符串dateparse庫(kù)無法識(shí)別,則返回一個(gè)錯(cuò)誤。上面程序運(yùn)行輸出:

          $?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

          需要注意,當(dāng)我們寫出"3/1/2014"這個(gè)時(shí)間的時(shí)候,可以解釋為2014年3月1日,也可以解釋為2014年1月3日。這就存在二義性,dateparse默認(rèn)采用mm/dd/yyyy這種格式,也就是2014年3月1日。我們也可以使用ParseStrict()函數(shù)讓這種具有二義性的字符串解析失敗:

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

          運(yùn)行:

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

          格式

          dateparse支持豐富的日期時(shí)間格式,基本囊括了所有常用的格式。它支持標(biāo)準(zhǔn)庫(kù)time中預(yù)定義的所有格式:

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

          支持的完整格式查看dateparse README。

          時(shí)區(qū)

          dateparse支持在特定時(shí)區(qū)解析日期時(shí)間字符串。我們可以通過調(diào)用標(biāo)準(zhǔn)庫(kù)的time.LoadLocation()方法,傳入時(shí)區(qū)標(biāo)識(shí)字符串來獲得時(shí)區(qū)對(duì)象。時(shí)區(qū)標(biāo)識(shí)字符串是類似Asia/ShanghaiAmerica/Chicago這樣的格式,它表示一個(gè)具體的時(shí)區(qū),前者上海,后者洛杉磯。調(diào)用dateparse.ParseIn()方法傳入時(shí)區(qū)對(duì)象,在指定時(shí)區(qū)中解析。time包中還預(yù)定義了兩個(gè)時(shí)區(qū)對(duì)象,time.Local表示本地時(shí)區(qū),time.UTC表示 UTC 時(shí)區(qū)。時(shí)區(qū)的權(quán)威數(shù)據(jù)請(qǐng)看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"))
          }

          運(yùn)行:

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

          美國(guó)洛杉磯時(shí)區(qū)的"2021年6月24日 15時(shí)30分30秒"等于本地時(shí)區(qū)(北京時(shí)間)的"2021年6月25日 04時(shí)50分30秒"。

          cli

          dateparse還提供了一個(gè)命令行工具,用于極快地查看日期時(shí)間格式。安裝:

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

          默認(rèn)會(huì)安裝在$GOPATH路徑下,我習(xí)慣上把$GOPATH/bin放到$PATH中。所以dateparse命令可以直接使用。

          dateparse命令接收一個(gè)字符串,和一個(gè)可選的時(shí)區(qū)選項(xiàng):

          $?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???????|
          +-------------+---------------------------+-------------------------------+-------------------------------------+

          輸出當(dāng)前本地時(shí)區(qū),格式字符串(可用于生成同樣格式的日期時(shí)間字符串)和一個(gè)表格。表格里面的數(shù)據(jù)是分別對(duì)ParseAny/ParseIn/ParseLocal/ParseStrict在不同的時(shí)區(qū)下調(diào)用的結(jié)果。

          method列表示調(diào)用的方法,Zone Source列表示將本地時(shí)區(qū)設(shè)置的值,Parsed列是以日期時(shí)間字符串調(diào)用ParseAny()返回的time.Time對(duì)象的Format()方法調(diào)用結(jié)果,Parsed: t.In(time.UTC)列在返回的time.Time對(duì)象調(diào)用Format()方法前將其轉(zhuǎn)為 UTC 時(shí)間。

          由于ParseAny/ParseStrict不會(huì)考慮本地時(shí)區(qū),都是在 UTC 下解析字符串,所以這 6 行的最后兩列結(jié)果都一樣。

          ParseIn的第二行,將time.Local設(shè)置為我們通過命令行選項(xiàng)設(shè)置的時(shí)區(qū),上面我設(shè)置為Asia/Shanghai,對(duì)應(yīng)的 UTC 時(shí)間相差 8 小時(shí)。ParseLocal也是如此。

          下面是dateparse命令行的部分源碼,可以對(duì)照查看:

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

          注意輸出的本地時(shí)區(qū)為 CST,它可以代表不同的時(shí)區(qū):

          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 可以同時(shí)表示美國(guó)、澳大利亞、中國(guó)和古巴四個(gè)國(guó)家的標(biāo)準(zhǔn)時(shí)間。

          總結(jié)

          使用dateparse可以很方便地從日期時(shí)間字符串中解析出時(shí)間對(duì)象和格式(layout)。同時(shí)dateparse命令行可以快速的查看和轉(zhuǎn)換相應(yīng)時(shí)區(qū)的時(shí)間,是一個(gè)非常不錯(cuò)的小工具。

          大家如果發(fā)現(xiàn)好玩、好用的 Go 語(yǔ)言庫(kù),歡迎到 Go 每日一庫(kù) GitHub 上提交 issue??

          參考

          1. dateparse GitHub:github.com/araddon/dateparse
          2. Go 每日一庫(kù) GitHub:https://github.com/darjun/go-daily-lib


          推薦閱讀


          福利

          我為大家整理了一份從入門到進(jìn)階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進(jìn)階看什么。關(guān)注公眾號(hào) 「polarisxu」,回復(fù)?ebook?獲取;還可以回復(fù)「進(jìn)群」,和數(shù)萬(wàn) Gopher 交流學(xué)習(xí)。

          瀏覽 44
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久岛国电影免费观看软件 | 无码人妻一区二区三区四区老鸭窝 | 欧亚毛片| 激情性爱视频网站 | 欧美v精品 |