github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/ztime/transform.go (about) 1 package ztime 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "strings" 8 "time" 9 10 "github.com/sohaha/zlsgo/zstring" 11 ) 12 13 const ( 14 timePattern = `(\d{4}[-/\.]\d{1,2}[-/\.]\d{1,2})[:\sT-]*(\d{0,2}:{0,1}\d{0,2}:{0,1}\d{0,2}){0,1}\.{0,1}(\d{0,9})([\sZ]{0,1})([\+-]{0,1})([:\d]*)` 15 ) 16 17 var ( 18 TimeTpl = "2006-01-02 15:04:05" 19 formatKeyTpl = map[byte]string{ 20 'd': "02", 21 'D': "Mon", 22 'w': "Monday", 23 'N': "Monday", 24 'S': "02", 25 'l': "Monday", 26 'F': "January", 27 'm': "01", 28 'M': "Jan", 29 'n': "1", 30 'Y': "2006", 31 'y': "06", 32 'a': "pm", 33 'A': "PM", 34 'g': "3", 35 'h': "03", 36 'H': "15", 37 'i': "04", 38 's': "05", 39 'O': "-0700", 40 'P': "-07:00", 41 'T': "MST", 42 'u': "000000", 43 'c': "2006-01-02T15:04:05-07:00", 44 'r': "Mon, 02 Jan 06 15:04 MST", 45 } 46 GetLocationName = func(zone int) string { 47 switch zone { 48 case 8: 49 return "Asia/Shanghai" 50 } 51 return "UTC" 52 } 53 ) 54 55 type TimeEngine struct { 56 zone *time.Location 57 } 58 59 // Zone eastEightTimeZone 60 func Zone(zone ...int) *time.Location { 61 if len(zone) > 0 { 62 return time.FixedZone(GetLocationName(zone[0]), zone[0]*3600) 63 } 64 return time.Local 65 } 66 67 // FormatTlp format template 68 func FormatTlp(format string) string { 69 runes := []rune(format) 70 buffer := bytes.NewBuffer(nil) 71 for i := 0; i < len(runes); i++ { 72 switch runes[i] { 73 case '\\': 74 if i < len(runes)-1 { 75 buffer.WriteRune(runes[i+1]) 76 i += 1 77 continue 78 } else { 79 return buffer.String() 80 } 81 default: 82 if runes[i] > 255 { 83 buffer.WriteRune(runes[i]) 84 break 85 } 86 if f, ok := formatKeyTpl[byte(runes[i])]; ok { 87 buffer.WriteString(f) 88 } else { 89 buffer.WriteRune(runes[i]) 90 } 91 } 92 } 93 return buffer.String() 94 } 95 96 // New new timeEngine 97 func New(zone ...int) *TimeEngine { 98 e := &TimeEngine{} 99 timezone := Zone(zone...) 100 if timezone != time.Local { 101 e.zone = timezone 102 } 103 return e 104 } 105 106 // SetTimeZone SetTimeZone 107 func (e *TimeEngine) SetTimeZone(zone int) *TimeEngine { 108 e.zone = Zone(zone) 109 return e 110 } 111 112 // GetTimeZone GetTimeZone 113 func (e *TimeEngine) GetTimeZone() *time.Location { 114 if e.zone == nil { 115 return time.Local 116 } 117 return e.zone 118 } 119 120 func (e *TimeEngine) In(t time.Time) time.Time { 121 if e.zone == nil { 122 return t 123 } 124 return t.In(e.zone) 125 } 126 127 // FormatTime string format of return time 128 func (e *TimeEngine) FormatTime(t time.Time, format ...string) string { 129 t = e.In(t) 130 tpl := TimeTpl 131 if len(format) > 0 { 132 tpl = FormatTlp(format[0]) 133 } 134 return t.Format(tpl) 135 } 136 137 // FormatTimestamp convert UNIX time to time string 138 func (e *TimeEngine) FormatTimestamp(timestamp int64, format ...string) string { 139 if timestamp <= 9999999999 { 140 return e.FormatTime(e.Unix(timestamp), format...) 141 } 142 if timestamp <= 9999999999999 { 143 timestamp = timestamp * 1000 144 } 145 return e.FormatTime(e.UnixMicro(timestamp), format...) 146 } 147 148 // Unix int to time 149 func (e *TimeEngine) Unix(tt int64) time.Time { 150 return e.In(time.Unix(tt, 0)) 151 } 152 153 // UnixMicro int to time 154 func (e *TimeEngine) UnixMicro(tt int64) time.Time { 155 return e.In(time.Unix(tt/1e6, (tt%1e6)*1e3)) 156 } 157 158 // Parse Parse 159 func (e *TimeEngine) Parse(str string, format ...string) (t time.Time, err error) { 160 if len(format) > 0 { 161 return time.ParseInLocation(FormatTlp(format[0]), str, e.GetTimeZone()) 162 } 163 164 var year, month, day, hour, min, sec string 165 match, err := zstring.RegexExtract(timePattern, str) 166 if err != nil { 167 return 168 } 169 matchLen := len(match) 170 if matchLen == 0 { 171 err = errors.New("cannot parse") 172 return 173 } 174 if matchLen > 1 && match[1] != "" { 175 for k, v := range match { 176 match[k] = strings.TrimSpace(v) 177 } 178 arr := make([]string, 3) 179 for _, v := range []string{"-", "/", "."} { 180 arr = strings.Split(match[1], v) 181 if len(arr) >= 3 { 182 break 183 } 184 } 185 if len(arr) < 3 { 186 err = errors.New("cannot parse date") 187 return 188 } 189 year = arr[0] 190 month = zstring.Pad(arr[1], 2, "0", zstring.PadLeft) 191 day = zstring.Pad(arr[2], 2, "0", zstring.PadLeft) 192 } 193 194 if len(match[2]) > 0 { 195 s := strings.Replace(match[2], ":", "", -1) 196 if len(s) < 6 { 197 s += strings.Repeat("0", 6-len(s)) 198 } 199 hour = zstring.Pad(s[0:2], 2, "0", zstring.PadLeft) 200 min = zstring.Pad(s[2:4], 2, "0", zstring.PadLeft) 201 sec = zstring.Pad(s[4:6], 2, "0", zstring.PadLeft) 202 return time.ParseInLocation(TimeTpl, year+"-"+month+"-"+day+" "+hour+":"+min+":"+sec, e.GetTimeZone()) 203 } 204 return time.ParseInLocation("2006-01-02", year+"-"+month+"-"+day, e.GetTimeZone()) 205 } 206 207 func (e *TimeEngine) Week(t time.Time) int { 208 week := e.In(t).Weekday().String() 209 switch week { 210 case "Monday": 211 return 1 212 case "Tuesday": 213 return 2 214 case "Wednesday": 215 return 3 216 case "Thursday": 217 return 4 218 case "Friday": 219 return 5 220 case "Saturday": 221 return 6 222 // case "Sunday": 223 default: 224 return 0 225 } 226 } 227 228 // MonthRange gets the start and end UNIX times for the specified year and month 229 func (e *TimeEngine) MonthRange(year int, month int) (beginTime, endTime int64, err error) { 230 var monthStr string 231 t := e.In(time.Now()) 232 233 if year == 0 { 234 year = t.Year() 235 } 236 237 if month == 0 { 238 month = int(t.Month()) 239 } 240 if month <= 9 { 241 monthStr = fmt.Sprintf("0%d", month) 242 } else { 243 monthStr = fmt.Sprint(month) 244 } 245 yearStr := fmt.Sprint(year) 246 str := yearStr + "-" + monthStr + "-01 00:00:00" 247 begin, err := e.Parse(str) 248 if err != nil { 249 return 250 } 251 beginTime = begin.Unix() 252 month = int(begin.Month()) 253 day := 30 254 if month == 2 { 255 day = 28 256 } else if month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 { 257 day = 31 258 } 259 260 str = yearStr + "-" + monthStr + "-" + fmt.Sprint(day) + " 23:59:59" 261 end, _ := e.Parse(str) 262 endTime = end.Unix() 263 return 264 }