| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- // Copyright 2019 Yunion
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package timeutils
- import (
- "fmt"
- "strings"
- "time"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/util/regutils"
- )
- func UtcNow() time.Time {
- return time.Now().UTC()
- }
- func Utcify(now time.Time) time.Time {
- if now.IsZero() {
- val := time.Now().UTC()
- return val
- } else {
- return now.UTC()
- }
- }
- func Localify(now time.Time) time.Time {
- if now.IsZero() {
- return time.Now().Local()
- }
- return now.Local()
- }
- const (
- IsoTimeFormat = "2006-01-02T15:04:05Z07:00"
- IsoNoSecondTimeFormat = "2006-01-02T15:04Z07:00"
- FullIsoTimeFormat = "2006-01-02T15:04:05.000000Z07:00"
- FullIsoNanoTimeFormat = "2006-01-02T15:04:05.000000000Z07:00"
- MysqlTimeFormat = "2006-01-02 15:04:05"
- ClickhouseTimeFormat = "2006-01-02 15:04:05 +0000 UTC"
- NormalTimeFormat = "2006-01-02T15:04:05"
- FullNormalTimeFormat = "2006-01-02T15:04:05.000000"
- CompactTimeFormat = "20060102150405"
- DateFormat = "2006-01-02"
- ShortDateFormat = "20060102"
- DateExcelFormat = "01-02-06"
- MonthFormat = "2006-01"
- ShortMonthFormat = "200601"
- ZStackTimeFormat = "Jan 2, 2006 15:04:05 PM"
- IsoTimeFormat2 = "2006-01-02 15:04:05Z07:00"
- IsoNoSecondTimeFormat2 = "2006-01-02 15:04Z07:00"
- FullIsoNanoTimeFormat2 = "2006-01-02 15:04:05.000000000Z07:00"
- FullIsoNanoTimeFormat3 = "2006-01-02 15:04:05.000000000"
- RFC2882Format = time.RFC1123
- CephTimeFormat = "Mon Jan _2 15:04:05 2006"
- )
- func IsoTime(now time.Time) string {
- return Utcify(now).Format(IsoTimeFormat)
- }
- func IsoNoSecondTime(now time.Time) string {
- return Utcify(now).Format(IsoNoSecondTimeFormat)
- }
- func FullIsoTime(now time.Time) string {
- return Utcify(now).Format(FullIsoTimeFormat)
- }
- func FullIsoNanoTime(now time.Time) string {
- return Utcify(now).Format(FullIsoNanoTimeFormat)
- }
- func MysqlTime(now time.Time) string {
- return Utcify(now).Format(MysqlTimeFormat)
- }
- func ClickhouseTime(now time.Time) string {
- return Utcify(now).Format(ClickhouseTimeFormat)
- }
- func CompactTime(now time.Time) string {
- return Utcify(now).Format(CompactTimeFormat)
- }
- func RFC2882Time(now time.Time) string {
- return Utcify(now).Format(RFC2882Format)
- }
- func CephTime(now time.Time) string {
- return Utcify(now).Format(CephTimeFormat)
- }
- func DateStr(now time.Time) string {
- return Utcify(now).Format(DateFormat)
- }
- func ShortDate(now time.Time) string {
- return Utcify(now).Format(ShortDateFormat)
- }
- func DateExcelStr(now time.Time) string {
- return Utcify(now).Format(DateExcelFormat)
- }
- func MonthStr(now time.Time) string {
- return Utcify(now).Format(MonthFormat)
- }
- func ShortMonth(now time.Time) string {
- return Utcify(now).Format(ShortMonthFormat)
- }
- func ZStackTime(now time.Time) string {
- return Localify(now).Format(ZStackTimeFormat)
- }
- func ParseIsoTime(str string) (time.Time, error) {
- return time.Parse(IsoTimeFormat, str)
- }
- func ParseIsoTime2(str string) (time.Time, error) {
- return time.Parse(IsoTimeFormat2, str)
- }
- func ParseIsoNoSecondTime(str string) (time.Time, error) {
- return time.Parse(IsoNoSecondTimeFormat, str)
- }
- func ParseIsoNoSecondTime2(str string) (time.Time, error) {
- return time.Parse(IsoNoSecondTimeFormat2, str)
- }
- func toFullIsoNanoTimeFormat(str string) string {
- // 2019-09-17T20:50:17.66667134+08:00
- // 2019-11-19T18:54:48.084-08:00
- subsecStr := str[20:]
- pos := -1
- for _, s := range []byte{'Z', '+', '-'} {
- pos = strings.IndexByte(subsecStr, s)
- if pos >= 0 {
- break
- }
- }
- if pos < 0 { //避免-1越界
- pos = len(subsecStr)
- }
- leftOver := subsecStr[pos:]
- subsecStr = subsecStr[:pos]
- for len(subsecStr) < 9 {
- subsecStr += "0"
- }
- return str[:20] + subsecStr + leftOver
- }
- func ParseFullIsoTime(str string) (time.Time, error) {
- return time.Parse(FullIsoNanoTimeFormat, toFullIsoNanoTimeFormat(str))
- }
- func ParseFullIsoTime2(str string) (time.Time, error) {
- return time.Parse(FullIsoNanoTimeFormat2, toFullIsoNanoTimeFormat(str))
- }
- func ParseFullIsoTime3(str string) (time.Time, error) {
- return time.Parse(FullIsoNanoTimeFormat3, toFullIsoNanoTimeFormat(str))
- }
- func ParseMysqlTime(str string) (time.Time, error) {
- return time.Parse(MysqlTimeFormat, str)
- }
- func ParseClickhouseTime(str string) (time.Time, error) {
- return time.Parse(ClickhouseTimeFormat, str)
- }
- func ParseNormalTime(str string) (time.Time, error) {
- return time.Parse(NormalTimeFormat, str)
- }
- func ParseFullNormalTime(str string) (time.Time, error) {
- return time.Parse(FullNormalTimeFormat, str)
- }
- func ParseCompactTime(str string) (time.Time, error) {
- return time.Parse(CompactTimeFormat, str)
- }
- func ParseRFC2882Time(str string) (time.Time, error) {
- return time.Parse(RFC2882Format, str)
- }
- func ParseCephTime(str string) (time.Time, error) {
- return time.Parse(CephTimeFormat, str)
- }
- func ParseDate(str string) (time.Time, error) {
- return time.Parse(DateFormat, str)
- }
- func ParseShortDate(str string) (time.Time, error) {
- return time.Parse(ShortDateFormat, str)
- }
- func ParseDateExcel(str string) (time.Time, error) {
- return time.Parse(DateExcelFormat, str)
- }
- func ParseZStackDate(str string) (time.Time, error) {
- return time.ParseInLocation(ZStackTimeFormat, str, time.Local)
- }
- func ParseTimeStr(str string) (time.Time, error) {
- str = strings.TrimSpace(str)
- if regutils.MatchFullISOTime(str) {
- return ParseFullIsoTime(str)
- } else if regutils.MatchISOTime(str) {
- return ParseIsoTime(str)
- } else if regutils.MatchISONoSecondTime(str) {
- return ParseIsoNoSecondTime(str)
- } else if regutils.MatchFullISOTime2(str) {
- return ParseFullIsoTime2(str)
- } else if regutils.MatchFullISOTime3(str) {
- return ParseFullIsoTime3(str)
- } else if regutils.MatchISOTime2(str) {
- return ParseIsoTime2(str)
- } else if regutils.MatchISONoSecondTime2(str) {
- return ParseIsoNoSecondTime2(str)
- } else if regutils.MatchMySQLTime(str) {
- return ParseMysqlTime(str)
- } else if regutils.MatchClickhouseTime(str) {
- return ParseClickhouseTime(str)
- } else if regutils.MatchNormalTime(str) {
- return ParseNormalTime(str)
- } else if regutils.MatchFullNormalTime(str) {
- return ParseFullNormalTime(str)
- } else if regutils.MatchRFC2882Time(str) {
- return ParseRFC2882Time(str)
- } else if regutils.MatchCephTime(str) {
- return ParseCephTime(str)
- } else if regutils.MatchCompactTime(str) {
- return ParseCompactTime(str)
- } else if regutils.MatchDate(str) {
- return ParseDate(str)
- } else if regutils.MatchDateCompact(str) {
- return ParseShortDate(str)
- } else if regutils.MatchDateExcel(str) {
- return ParseDateExcel(str)
- } else if regutils.MatchZStackTime(str) {
- return ParseZStackDate(str)
- } else {
- return time.Time{}, fmt.Errorf("unknown time format %s", str)
- }
- }
- func ParseTimeStrInLocation(str string, loc *time.Location) (time.Time, error) {
- utcTm, err := ParseTimeStr(str)
- if err != nil {
- return utcTm, errors.Wrap(err, "ParseTimeStr")
- }
- if loc == nil {
- loc, _ = time.LoadLocation("Local")
- }
- _, offset := utcTm.In(loc).Zone()
- return utcTm.Add(-time.Duration(offset) * time.Second), nil
- }
- func ParseTimeStrInTimeZone(str string, tz string) (time.Time, error) {
- if len(tz) == 0 {
- tz = "Local"
- }
- loc, err := time.LoadLocation(tz)
- if err != nil {
- return time.Time{}, errors.Wrap(err, "LoadLocation")
- }
- return ParseTimeStrInLocation(str, loc)
- }
- func TimeZoneOffset(tz string) (int, error) {
- if len(tz) == 0 {
- tz = "Local"
- }
- loc, err := time.LoadLocation(tz)
- if err != nil {
- return 0, errors.Wrap(err, "LoadLocation")
- }
- _, offset := time.Now().In(loc).Zone()
- return offset, nil
- }
|