// Copyright (c) 2015 qianqiusoft.com // Licensed to You under the GNU Affero GPL v3 // See the LICENSE file at git.qianqiusoft.com/qianqiusoft/light-vocation/LICENSE // http://www.gnu.org/licenses/why-affero-gpl.en.html package models import ( "fmt" "strings" "time" // "github.com/astaxie/beego/orm" ) // datetime values like 2006-01-02 15:04:05 type LocalDateTime time.Time const formatDateTime = "2006-01-02 15:04:05" const nilDateTimeStr = "0001-01-01 00:00:00" func NowLocal() LocalDateTime { return LocalDateTime(time.Now()) } func nilDateTime() LocalDateTime { nilDateTime, _ := timeParse(formatDateTime, nilDateTimeStr) //time.ParseInLocation(formatDate, nilDateStr, time.Local) return LocalDateTime(nilDateTime) } func isNilDateTime(tval time.Time) bool { return tval.Format(formatDateTime) == nilDateTimeStr } // Value return the datatime value func (e LocalDateTime) IsNilDateTime() bool { return isNilDateTime(e.Value()) } // Value return the datatime value func (e LocalDateTime) Value() time.Time { return time.Time(e) } // Set set the time.Time to datatime func (e *LocalDateTime) Set(d time.Time) { //fmt.Println("-------------------- LocalDateTime Set ") *e = LocalDateTime(d) } // String return the time's String func (e *LocalDateTime) String() string { return e.Value().String() } // FieldType return the enum TypeDateTimeField //func (e *LocalDateTime) FieldType() int { // return orm.TypeDateTimeField //} // SetRaw convert the string or time.Time to DateTimeField func (e *LocalDateTime) SetRaw(value interface{}) error { //fmt.Println("-------------------- LocalDateTime SetRaw ") if value == nil { *e = nilDateTime() return nil } switch d := value.(type) { case time.Time: //fmt.Println("--------------------time.time val is ", d.Format(formatDateTime)) if isNilDateTime(d) { *e = nilDateTime() } else { e.Set(d) } case string: //fmt.Println("--------------------string val is ", d) v, err := timeParse(d, formatDateTime) if err == nil { e.Set(v) } return err default: return fmt.Errorf(" unknown value `%s`", value) } return nil } // RawValue return the datatime value func (e *LocalDateTime) RawValue() interface{} { //fmt.Println("-------------------- LocalDateTime RawValue ") //fmt.Println("--------------------RawValue val is ", e.Value().Format(formatDateTime)) return e.Value() } // parse time to string with location func timeParse(dateString, format string) (time.Time, error) { // this //tp, err := time.ParseInLocation(format, dateString, orm.DefaultTimeLoc) //return tp, err return time.Now(), nil } func (t *LocalDateTime) UnmarshalJSON(data []byte) (err error) { if data[0] == '"' && data[len(data)-1] == '"' { data = data[1 : len(data)-1] } dataStr := strings.TrimSpace(string(data)) if dataStr == "" { *t = nilDateTime() return nil } var now time.Time if strings.Index(dataStr, "T") > 0 { // there is t with the date string now, err = time.ParseInLocation(time.RFC3339Nano, dataStr, time.Local) if err != nil { now, err = time.ParseInLocation(time.RFC3339, dataStr, time.Local) } // if t date, we format and parse withe utc againt // special special........ if err == nil { now, err = timeParse(now.Format(formatDateTime), formatDateTime) } } else { if len(dataStr) == 19 { if dataStr == "0000-00-00 00:00:00" { dataStr = nilDateTimeStr } } else if len(dataStr) == 10 { // only date dataStr += " 00:00:00" } else if len(dataStr) == 13 { // only hour dataStr += ":00:00" } else if len(dataStr) == 16 { // only hour dataStr += ":00" } //fmt.Println("---------------before json unmarshal ", dataStr) now, err = timeParse(dataStr, formatDateTime) //time.ParseInLocation(formatDateTime, dataStr, time.Local) //fmt.Println("---------------after json unmarshal ", now.Format(formatDateTime)) } *t = LocalDateTime(now) return } func (t LocalDateTime) MarshalJSON() ([]byte, error) { if isNilDateTime(t.Value()) { return []byte{'"', '"'}, nil } b := make([]byte, 0, len(formatDateTime)+2) b = append(b, '"') b = append(b, []byte(time.Time(t).Format(formatDateTime))...) b = append(b, '"') return b, nil } //var _ orm.Fielder = new(LocalDateTime)