golang 日期时间字符串处理支持多种格式(应对日期反序列化问题)

问题:前端输入的日期格式为:yyyy-mm-dd,yyyy-m-d。时间格式为:hh:mm:ss,h:m:s,h,hh。总之,输入的格式不一定固定。

解决办法:写一个日期时间字符串处理函数,将不规范的字符串格式统一为一种格式供go反序列化为time。

方法如下:

// 格式化日期字符串
func FormatTimeString(t string) string {
	var ret = ""
	timestr := strings.ReplaceAll(t, "/", "-")
	arr := strings.Split(timestr, " ")
	if len(arr) == 1 || len(arr) == 0 {
		ret = strings.Join([]string{arr[0], "00:00:00"}, " ")
	} else {
		switch strings.Count(arr[1], ":") {
		case 0:
			ret = strings.Join([]string{arr[0], strings.Join([]string{arr[1], ":00:00"}, "")}, " ")
			break
		case 1:
			ret = strings.Join([]string{arr[0], strings.Join([]string{arr[1], ":00"}, "")}, " ")
			break
		default:
			ret = timestr
			break
		}
	}
	return ret
}

 整体的代码如下:

package lib

import (
	"encoding/json"
	"fmt"
	"strings"
	"time"

	"github.com/astaxie/beego/orm"
)

type Time struct {
	time.Time
}

const TimeFormat = "2006-1-2 15:4:5"

// MarshalJSON 序列化为JSON
func (t Time) MarshalJSON() ([]byte, error) {
	if t.IsZero() {
		return []byte("\"\""), nil
	}
	stamp := fmt.Sprintf("\"%s\"", t.Format(TimeFormat))
	return []byte(stamp), nil
}

// UnmarshalJSON json反序列化为time
func (t *Time) UnmarshalJSON(data []byte) error {
	var err error
	if len(data) >= 10 {
		t.Time, err = time.ParseInLocation(TimeFormat, FormatTimeString(string(data)), time.Local)
		//t.Time,err = time.Parse(TimeFormat,string(data))
	} else {
		t.Time = time.Time{}
	}
	return err
}

// String 重写String方法
func (t *Time) String() string {
	data, _ := json.Marshal(t)
	return string(data)
}

// FieldType 数据类型
func (t *Time) FieldType() int {
	return orm.TypeDateTimeField

}

// SetRaw 读取数据库值
func (t *Time) SetRaw(value interface{}) error {
	switch value.(type) {
	case time.Time:
		t.Time = value.(time.Time)
	}
	return nil
}

// RawValue 写入数据库
func (t *Time) RawValue() interface{} {
	str := t.Format(TimeFormat)
	if str == "0001-01-01 00:00:00" {
		return nil
	}
	return str
}

// 格式化日期字符串
func FormatTimeString(t string) string {
	var ret = ""
	timestr := strings.ReplaceAll(t, "/", "-")
	arr := strings.Split(timestr, " ")
	if len(arr) == 1 || len(arr) == 0 {
		ret = strings.Join([]string{arr[0], "00:00:00"}, " ")
	} else {
		switch strings.Count(arr[1], ":") {
		case 0:
			ret = strings.Join([]string{arr[0], strings.Join([]string{arr[1], ":00:00"}, "")}, " ")
			break
		case 1:
			ret = strings.Join([]string{arr[0], strings.Join([]string{arr[1], ":00"}, "")}, " ")
			break
		default:
			ret = timestr
			break
		}
	}
	return ret
}

 经测试:TimeFormat = "2006-01-02 15:04:05"只能适配"yyyy-mm-dd hh:mm:ss"这种格式,不能适配月日小时分钟秒不带0的情形(如:2020-6-1)。而TimeFormat = "2006-1-2 15:4:5",这种可以适配带0和不带0两种情形。

 

 日期时间作为查询数据库条件尤其是拼接sql类型的,个人不建议model中的字段用time,多了反序列化步骤

posted @ 2020-06-20 17:33  追逐者——Eagle  阅读(2692)  评论(0编辑  收藏  举报