因
最近公司技术转型到GO语言,语言外行的我看到项目一堆日期格式化都是采用
2006-01-02 15:04:05
充斥大量篇幅,阅读极为不爽,没办法这是那GO语言那3个大佬敲定设计go语言IDEA,人家自然期望在自己语言里纪念这个日期,也无可厚非,你以后有机会写编程语言,写个xxxnb才能调用函数都没人拿你啥办法
Talk is cheap,咱还是考虑怎么从变成习惯上解决掉这个不爽的感觉,本篇的核心就是狸猫换太子, 顺便说一下,本文是一个通用解决的办法可以cover一切模版诸如:yyyy-MM-dd yyyy/MM/dd .etc
果
以简洁使用方便为目的,构造如下轮子,使用起来还是蛮香的,具体使用可以看如下的用例
package main
import (
"errors"
"fmt"
"strconv"
"strings"
"time"
)
const (
DASH = "-"
UNDERLINE = "_"
DOT = ","
EQUALS = "="
SLASH = "/"
BACK_SLASH = "\\"
SPACE = " "
COLON = ":"
EMPTY = ""
)
var standDateTimeTemplate = "2006%s01%s02 15%s04%s05"
func GetStrByTime(time time.Time) string {
// yyyy-MM-dd HH:mm:ss
split := getStrByTimeWithSplit(DASH, COLON)
return getStrWithFormat(time, split)
}
func GetStrByTimeWithFormat(time time.Time, dateSpilt, timeSpilt interface{}) string {
split := getStrByTimeWithSplit(dateSpilt, timeSpilt)
return getStrWithFormat(time, split)
}
/**
* 获取精确到毫秒的日期格式
*/
func GetMilliStrByTimeWithFormat(time time.Time, dateSpilt, timeSpilt interface{}) string {
split := getStrByTimeWithSplit(dateSpilt, timeSpilt)
split += ".000"
return getStrWithFormat(time, split)
}
func getStrWithFormat(time time.Time, format string) string {
return time.Format(format)
}
func getStrByTimeWithSplit(dateSpilt, timeSpilt interface{}) string {
hasDate := dateSpilt != nil
hasTime := timeSpilt != nil
standDateTimeTemplateArr := strings.Split(standDateTimeTemplate, SPACE)
result := EMPTY
if hasDate {
result += strings.ReplaceAll(standDateTimeTemplateArr[0], "%s", dateSpilt.(string))
}
if hasTime {
if hasDate {
result += SPACE
}
result += strings.ReplaceAll(standDateTimeTemplateArr[1], "%s", timeSpilt.(string))
}
if result == EMPTY {
return getStrByTimeWithSplit(DASH, COLON)
}
return result
}
func isValid(str string) (error, []string, int){
if str == EMPTY {
return nil, nil, 0
}
dateTimeStr := strings.Split(str, SPACE)
total := len(dateTimeStr)
if total == 2 {
dateLen := len(dateTimeStr[0])
if dateLen & 1 != 0 {
return errors.New("invalid date str:" + dateTimeStr[0]), nil, 0
}
timeLen := len(dateTimeStr[1])
if timeLen & 1 != 0 {
return errors.New("invalid date str:" + dateTimeStr[1]), nil, 0
}
} else {
// 年月 月日 时分 分秒
partLen := len(str)
if (partLen & 1) != 0 && partLen != 5{
return errors.New("invalid date str:" + str), nil, 0
}
}
return nil, dateTimeStr, total
}
/**
* 根据日期字符串转time
* tip:该方法效率高于<code> GetTimeByStrWithFormat </code> 推荐使用
*/
func GetTimeWithStr(str string, dateSplit, timeSpilt interface{}) (dateTime time.Time, err error){
err, _, _ = isValid(str)
if nil != err{
return time.Time{}, err
}
split := getStrByTimeWithSplit(dateSplit, timeSpilt)
dateTime, err = time.ParseInLocation(split, str, time.Local)
return
}
func GetTimeByStrWithFormat(str string) (dateTime time.Time, err error){
deferException()
err, dateTimeStr, length := isValid(str)
if nil != err {
return time.Time{}, err
}
var timeSplit, dateSplit interface{}
format := ""
// 尝试解析前四位,如果能解析成功 则为年月日 否则为时分秒
predictYear := str[2:3]
_, err = strconv.ParseInt(predictYear, 10, 0)
if nil != err {
dateSplit = nil
timeSplit = predictYear
} else {
dateSplit = str[4:5]
if 1 == length {
timeSplit = nil
} else {
timeSplit = dateTimeStr[1][2:3]
}
}
// 解析遇到异常统一处理
format = getStrByTimeWithSplit(dateSplit, timeSplit)
location, _ := time.LoadLocation("Asia/ShangHai")
dateTime, err = time.ParseInLocation(format, str,location )
return
}
func hh() {
deferException()
a := 1
b := 0
fmt.Println(a / b)
}
func deferException() {
defer func() {
err := recover()
if err != nil {
fmt.Println("catch exception:", err)
}
}()
}
// 测试
func main() {
// time 转任意格式时间
fmt.Println(GetStrByTime(time.Now()))
fmt.Println(GetStrByTimeWithFormat(time.Now(), "#", nil))
// 任意格式时间 转 time
str, err := GetTimeWithStr("2023/03/21 13\\09\\44", "/", "\\")
fmt.Println(str, err)
// 任意格式
format1, err := GetTimeByStrWithFormat("2023:03:21 22/33/03")
fmt.Println(format1, err)
format3, err := GetTimeByStrWithFormat("22/33/03")
fmt.Println(format3, err)
format4, err := GetTimeByStrWithFormat("2023:03:21")
fmt.Println(format4, err)
// 合法性验证 + 友好性提示
format2, err := GetTimeByStrWithFormat("2023:03:21 22;33;3")
fmt.Println(format2, err)
2023-03-21 19:28:09
2023#03#21
2023-03-21 13:09:44 +0800 CST <nil>
2023-03-21 22:33:03 +0800 CST <nil>
0000-01-01 22:33:03 +0805 LMT <nil>
2023-03-21 00:00:00 +0800 CST <nil>
0001-01-01 00:00:00 +0000 UTC invalid date str:22;33;3
}
终
刚结束GO还有很多不熟悉,如果读者有更简便的方法,也欢迎评论分享,后续GO自研的工具会迁移到git,敬请关注。
曲终人不散~