github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/commons/times/time.go (about) 1 /* 2 * Copyright 2023 Wang Min Xiang 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 18 package times 19 20 import ( 21 "database/sql/driver" 22 "fmt" 23 "reflect" 24 "time" 25 ) 26 27 func TimeNow() Time { 28 return TimeOf(time.Now()) 29 } 30 31 func NewTime(hour int, min int, sec int) Time { 32 return Time{ 33 Hour: hour, 34 Minutes: min, 35 Second: sec, 36 } 37 } 38 39 func TimeOf(t time.Time) Time { 40 return NewTime(t.Hour(), t.Minute(), t.Second()) 41 } 42 43 type Time struct { 44 Hour int 45 Minutes int 46 Second int 47 } 48 49 func (t *Time) UnmarshalJSON(p []byte) error { 50 if p == nil || len(p) < 3 { 51 return nil 52 } 53 p = p[1 : len(p)-1] 54 v, parseErr := time.Parse(time.TimeOnly, string(p)) 55 if parseErr != nil { 56 return fmt.Errorf("unmarshal %s failed, layout of date must be 15:04:05, %v", string(p), parseErr) 57 } 58 t.Hour = v.Hour() 59 t.Minutes = v.Minute() 60 t.Second = v.Second() 61 return nil 62 } 63 64 func (t Time) MarshalJSON() ([]byte, error) { 65 return []byte(fmt.Sprintf("\"%s\"", t.ToTime().Format(time.TimeOnly))), nil 66 } 67 68 func (t Time) ToTime() time.Time { 69 if t.Hour < 0 || t.Hour > 23 { 70 t.Hour = 0 71 } 72 if t.Minutes < 0 || t.Minutes > 59 { 73 t.Minutes = 0 74 } 75 if t.Second < 0 || t.Second > 59 { 76 t.Second = 0 77 } 78 return time.Date(1, 1, 1, t.Hour, t.Minutes, t.Second, 0, time.Local) 79 } 80 81 func (t Time) IsZero() (ok bool) { 82 ok = t.Hour == 0 && t.Minutes == 0 && t.Second == 0 83 return 84 } 85 86 func (t Time) String() string { 87 return t.ToTime().Format(time.TimeOnly) 88 } 89 90 func (t *Time) Scan(src interface{}) error { 91 if src == nil { 92 return nil 93 } 94 x := "" 95 switch src.(type) { 96 case string: 97 x = src.(string) 98 break 99 case []byte: 100 x = string(src.([]byte)) 101 break 102 case time.Time: 103 v := src.(time.Time) 104 t.Hour = v.Hour() 105 t.Minutes = v.Minute() 106 t.Second = v.Second() 107 return nil 108 default: 109 return fmt.Errorf("fns: scan time raw value failed for %v is not supported", reflect.TypeOf(src).String()) 110 } 111 if x == "" { 112 return nil 113 } 114 v, parseErr := time.Parse(time.TimeOnly, x) 115 if parseErr != nil { 116 return fmt.Errorf("fns: scan time date value failed, parse %s failed, %v", x, parseErr) 117 } 118 t.Hour = v.Hour() 119 t.Minutes = v.Minute() 120 t.Second = v.Second() 121 return nil 122 } 123 124 func (t Time) Value() (driver.Value, error) { 125 if t.IsZero() { 126 return nil, nil 127 } 128 return t.String(), nil 129 }