github.com/whatap/golib@v0.0.22/util/dateutil/DateTimeHelper.go (about) 1 package dateutil 2 3 import ( 4 "bytes" 5 "fmt" 6 "strconv" 7 "sync" 8 "time" 9 ) 10 11 const ( 12 MILLIS_PER_SECOND = 1000 13 MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND 14 MILLIS_PER_FIVE_MINUTE = 5 * 60 * MILLIS_PER_SECOND 15 MILLIS_PER_TEN_MINUTE = 10 * MILLIS_PER_MINUTE 16 MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE 17 MILLIS_PER_DAY = 24 * MILLIS_PER_HOUR 18 ) 19 20 type Day struct { 21 yyyy int 22 mm int 23 dd int 24 date string 25 wday string 26 time int64 27 } 28 type DateTimeHelper struct { 29 BASE_TIME int64 30 table [][][]*Day 31 dateTable []*Day 32 LAST_DATE int 33 } 34 35 var wday = []string{"Mon", "Tue", "Wed", "Thr", "Fri", "Sat", "Sun"} 36 var mdayLen = []int{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 37 38 func newDateTimeHelper(location string) *DateTimeHelper { 39 d := new(DateTimeHelper) 40 d.BASE_TIME = 0 41 d.table = make([][][]*Day, 100) 42 d.dateTable = make([]*Day, 40000) 43 d.LAST_DATE = 0 44 45 // BASE_TIME 생성 location 이 없을 경우 time.UTC 로 설정. 46 if location != "" { 47 loc, _ := time.LoadLocation(location) 48 //t, _ := time.ParseInLocation(time.RFC3339, "2001-01-01T00:00:00Z", loc) 49 t := time.Date(2000, time.January, 1, 0, 0, 0, 0, loc) 50 d.BASE_TIME = t.Unix() * 1000 51 } else { 52 //t, _ := time.Parse(time.RFC3339, "2001-01-01T00:00:00Z") 53 t := time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC) 54 d.BASE_TIME = t.Unix() * 1000 55 } 56 d.open() 57 58 return d 59 } 60 61 var lock sync.Mutex 62 var _table = make(map[string]*DateTimeHelper) 63 64 func getDateTimeHelper(timezone string) *DateTimeHelper { 65 lock.Lock() 66 defer lock.Unlock() 67 68 helper := _table[timezone] 69 if helper == nil { 70 helper = newDateTimeHelper(timezone) 71 _table[timezone] = helper 72 } 73 return helper 74 } 75 76 func (this *DateTimeHelper) open() { 77 mtime := this.BASE_TIME 78 seq := 0 79 wdayIdx := 5 // 20000101:Saturday 80 for year := 0; year < 100; year += 1 { 81 this.table[year] = make([][]*Day, 12) 82 for mm := 0; mm < 12; mm++ { 83 monLen := mdayLen[mm] 84 if mm == 1 && isYun(year) { 85 monLen++ 86 } 87 this.table[year][mm] = make([]*Day, monLen) 88 for dd := 0; dd < monLen; dd++ { 89 yyyyMMdd := fmt.Sprintf("%d%02d%02d", (year + 2000), mm+1, dd+1) 90 this.dateTable[seq] = new(Day) 91 this.dateTable[seq].date = yyyyMMdd 92 this.dateTable[seq].yyyy = year + 2000 93 this.dateTable[seq].mm = mm + 1 94 this.dateTable[seq].dd = dd + 1 95 this.dateTable[seq].wday = wday[wdayIdx] 96 this.dateTable[seq].time = mtime 97 this.table[year][mm][dd] = this.dateTable[seq] 98 99 if wdayIdx == 6 { 100 wdayIdx = 0 101 } else { 102 wdayIdx += 1 103 } 104 seq += 1 105 mtime += MILLIS_PER_DAY 106 } 107 } 108 } 109 } 110 func isYun(year int) bool { 111 if (year%4 == 0 && year%100 != 0) || year%400 == 0 { 112 return true 113 } else { 114 return false 115 } 116 } 117 func (this *DateTimeHelper) getYmdTime(yyyyMMdd string) int64 { 118 if yyyyMMdd == "" { 119 return 0 120 } 121 year, _ := strconv.Atoi(yyyyMMdd[0:4]) 122 mm, _ := strconv.Atoi(yyyyMMdd[4:6]) 123 dd, _ := strconv.Atoi(yyyyMMdd[6:8]) 124 if year >= 2100 { 125 return this.table[99][11][30].time + MILLIS_PER_DAY 126 } 127 if year < 2000 { 128 return this.BASE_TIME 129 } 130 return this.table[year-2000][mm-1][dd-1].time 131 } 132 func (this *DateTimeHelper) getWeekDay(yyyyMMdd string) string { 133 if yyyyMMdd == "" { 134 return "" 135 } 136 year, _ := strconv.Atoi(yyyyMMdd[0:4]) 137 mm, _ := strconv.Atoi(yyyyMMdd[4:6]) 138 dd, _ := strconv.Atoi(yyyyMMdd[6:8]) 139 if year >= 2100 { 140 return this.table[99][11][30].wday 141 } 142 if year < 2000 { 143 return this.table[0][0][0].wday 144 } 145 return this.table[year-2000][mm-1][dd-1].wday 146 } 147 func (this *DateTimeHelper) hhmmTo(date string) int64 { 148 if date == "" { 149 return 0 150 } 151 h, _ := strconv.Atoi(date[0:2]) 152 m, _ := strconv.Atoi(date[2:4]) 153 return int64(h*MILLIS_PER_HOUR + m*MILLIS_PER_MINUTE) 154 } 155 func (this *DateTimeHelper) yyyymmdd(time int64) string { 156 idx := int((time - this.BASE_TIME) / MILLIS_PER_DAY) 157 if idx < 0 { 158 idx = 0 159 } 160 return this.dateTable[idx].date 161 } 162 func (this *DateTimeHelper) weekday(time int64) string { 163 idx := int((time - this.BASE_TIME) / MILLIS_PER_DAY) 164 if idx < 0 { 165 idx = 0 166 } 167 return this.dateTable[idx].wday 168 } 169 func (this *DateTimeHelper) datetime(time int64) string { 170 if time < this.BASE_TIME { 171 return "20000101 00:00:00" 172 } 173 idx := (int)((time - this.BASE_TIME) / MILLIS_PER_DAY) 174 dtime := (int)((time - this.BASE_TIME) % MILLIS_PER_DAY) 175 hh := (int)(dtime / MILLIS_PER_HOUR) 176 dtime = (int)(dtime % MILLIS_PER_HOUR) 177 mm := (int)(dtime / MILLIS_PER_MINUTE) 178 dtime = (int)(dtime % MILLIS_PER_MINUTE) 179 ss := (int)(dtime / MILLIS_PER_SECOND) 180 181 var buffer bytes.Buffer 182 buffer.WriteString(this.dateTable[idx].date) 183 buffer.WriteString(" ") 184 buffer.WriteString(mk2(hh)) 185 buffer.WriteString(":") 186 buffer.WriteString(mk2(mm)) 187 buffer.WriteString(":") 188 buffer.WriteString(mk2(ss)) 189 return buffer.String() 190 } 191 func (this *DateTimeHelper) timestamp(time int64) string { 192 if time < this.BASE_TIME { 193 return "20000101 00:00:00" 194 } 195 idx := (int)((time - this.BASE_TIME) / MILLIS_PER_DAY) 196 dtime := (int)((time - this.BASE_TIME) % MILLIS_PER_DAY) 197 hh := (int)(dtime / MILLIS_PER_HOUR) 198 dtime = (int)(dtime % MILLIS_PER_HOUR) 199 mm := (int)(dtime / MILLIS_PER_MINUTE) 200 dtime = (int)(dtime % MILLIS_PER_MINUTE) 201 ss := (int)(dtime / MILLIS_PER_SECOND) 202 sss := (int)(dtime % 1000) 203 204 var buffer bytes.Buffer 205 buffer.WriteString(this.dateTable[idx].date) 206 buffer.WriteString(" ") 207 buffer.WriteString(mk2(hh)) 208 buffer.WriteString(":") 209 buffer.WriteString(mk2(mm)) 210 buffer.WriteString(":") 211 buffer.WriteString(mk2(ss)) 212 buffer.WriteString(".") 213 buffer.WriteString(mk2(sss)) 214 return buffer.String() 215 } 216 func (this *DateTimeHelper) getDateMillis(time int64) int { 217 if time < this.BASE_TIME { 218 return 0 219 } 220 dtime := (time - this.BASE_TIME) % MILLIS_PER_DAY 221 return int(dtime) 222 } 223 func (this *DateTimeHelper) getDateStartTime(time int64) int64 { 224 if time < this.BASE_TIME { 225 return 0 226 } 227 dtime := (time - this.BASE_TIME) % MILLIS_PER_DAY 228 return time - dtime 229 } 230 func (this *DateTimeHelper) getHour(time int64) int { 231 return this.getDateMillis(time) / MILLIS_PER_HOUR 232 } 233 func (this *DateTimeHelper) getMM(time int64) int { 234 dtime := this.getDateMillis(time) % MILLIS_PER_HOUR 235 return (dtime / MILLIS_PER_MINUTE) 236 } 237 func (this *DateTimeHelper) getTimeUnit(time int64) int64 { 238 return (time - this.BASE_TIME) 239 } 240 func (this *DateTimeHelper) getDateUnit(time int64) int64 { 241 return (time - this.BASE_TIME) / MILLIS_PER_DAY 242 } 243 func (this *DateTimeHelper) getTenMinUnit(time int64) int64 { 244 return (time - this.BASE_TIME) / MILLIS_PER_TEN_MINUTE 245 } 246 func (this *DateTimeHelper) getFiveMinUnit(time int64) int64 { 247 return (time - this.BASE_TIME) / MILLIS_PER_FIVE_MINUTE 248 } 249 func (this *DateTimeHelper) getMinUnit(time int64) int64 { 250 return (time - this.BASE_TIME) / MILLIS_PER_MINUTE 251 } 252 func (this *DateTimeHelper) getHourUnit(time int64) int64 { 253 return (time - this.BASE_TIME) / MILLIS_PER_HOUR 254 } 255 func (this *DateTimeHelper) reverseHourUnit(unit int64) int64 { 256 return (unit * MILLIS_PER_HOUR) + this.BASE_TIME 257 } 258 func (this *DateTimeHelper) reverseUnit(unit int64, millis int64) int64 { 259 return (unit * millis) + this.BASE_TIME 260 } 261 262 func mk2(n int) string { 263 switch n { 264 case 0, 1, 2, 3, 4, 5, 6, 7, 8, 9: 265 return "0" + strconv.Itoa(n) 266 } 267 return strconv.Itoa(n) 268 } 269 func mk3(n int) string { 270 switch n { 271 case 0, 1, 2, 3, 4, 5, 6, 7, 8, 9: 272 return "00" + strconv.Itoa(n) 273 } 274 if n < 100 { 275 return "0" + strconv.Itoa(n) 276 } else { 277 return strconv.Itoa(n) 278 } 279 } 280 func (this *DateTimeHelper) ymdhms(time int64) string { 281 if time < this.BASE_TIME { 282 return "20000101000000" 283 } 284 idx := (int)((time - this.BASE_TIME) / MILLIS_PER_DAY) 285 dtime := (int)((time - this.BASE_TIME) % MILLIS_PER_DAY) 286 hh := (int)(dtime / MILLIS_PER_HOUR) 287 dtime = (int)(dtime % MILLIS_PER_HOUR) 288 mm := (int)(dtime / MILLIS_PER_MINUTE) 289 dtime = (int)(dtime % MILLIS_PER_MINUTE) 290 ss := (int)(dtime / MILLIS_PER_SECOND) 291 //sss := (int)(dtime % 1000) 292 293 var buffer bytes.Buffer 294 buffer.WriteString(this.dateTable[idx].date) 295 buffer.WriteString(mk2(hh)) 296 buffer.WriteString(mk2(mm)) 297 buffer.WriteString(mk2(ss)) 298 return buffer.String() 299 } 300 func (this *DateTimeHelper) getYear(time int64, delta int) int64 { 301 if time < this.BASE_TIME { 302 return this.BASE_TIME 303 } 304 idx := (int)((time - this.BASE_TIME) / MILLIS_PER_DAY) 305 year := this.dateTable[idx].yyyy + delta 306 mm := this.dateTable[idx].mm 307 dd := this.dateTable[idx].dd 308 if year < 2000 { 309 return this.BASE_TIME 310 } 311 if year > 2100 { 312 return this.dateTable[this.LAST_DATE].time 313 } 314 315 dtime := (time - this.BASE_TIME) % MILLIS_PER_DAY 316 317 return this.table[year-2000][mm-1][dd-1].time + dtime 318 } 319 func (this *DateTimeHelper) getMonth(time int64, delta int) int64 { 320 if time < this.BASE_TIME { 321 return this.BASE_TIME 322 } 323 idx := (int)((time - this.BASE_TIME) / MILLIS_PER_DAY) 324 year := this.dateTable[idx].yyyy 325 mm := this.dateTable[idx].mm 326 dd := this.dateTable[idx].dd 327 delta = delta + mm - 1 328 deltaYear := delta / 12 329 deltaMM := delta % 12 330 if deltaMM < 0 { 331 deltaYear-- 332 deltaMM = 12 + deltaMM 333 } 334 year += deltaYear 335 mm = deltaMM + 1 336 if year < 2000 { 337 return this.BASE_TIME 338 } 339 if year > 2100 { 340 return this.dateTable[this.LAST_DATE].time 341 } 342 343 dtime := (time - this.BASE_TIME) % MILLIS_PER_DAY 344 return this.table[year-2000][mm-1][dd-1].time + dtime 345 } 346 func (this *DateTimeHelper) getDate(time int64, delta int) int64 { 347 if time < this.BASE_TIME { 348 return this.BASE_TIME 349 } 350 idx := (int)((time - this.BASE_TIME) / MILLIS_PER_DAY) 351 dtime := (time - this.BASE_TIME) % MILLIS_PER_DAY 352 idx += delta 353 if idx < 0 { 354 return this.BASE_TIME 355 } 356 if idx >= this.LAST_DATE { 357 return this.dateTable[this.LAST_DATE].time 358 } 359 return this.dateTable[idx].time + dtime 360 } 361 func (this *DateTimeHelper) logtime(time int64) string { 362 if time < this.BASE_TIME { 363 return "00:00:00.000" 364 } 365 //idx := (int)((time - this.BASE_TIME) / MILLIS_PER_DAY) 366 dtime := (int)((time - this.BASE_TIME) % MILLIS_PER_DAY) 367 hh := (int)(dtime / MILLIS_PER_HOUR) 368 dtime = (int)(dtime % MILLIS_PER_HOUR) 369 mm := (int)(dtime / MILLIS_PER_MINUTE) 370 dtime = (int)(dtime % MILLIS_PER_MINUTE) 371 ss := (int)(dtime / MILLIS_PER_SECOND) 372 sss := (int)(dtime % 1000) 373 374 var buffer bytes.Buffer 375 buffer.WriteString(mk2(hh)) 376 buffer.WriteString(":") 377 buffer.WriteString(mk2(mm)) 378 buffer.WriteString(":") 379 buffer.WriteString(mk2(ss)) 380 buffer.WriteString(".") 381 buffer.WriteString(mk2(sss)) 382 return buffer.String() 383 } 384 func (this *DateTimeHelper) hhmmss(time int64) string { 385 if time < this.BASE_TIME { 386 return "000000" 387 } 388 dtime := (int)((time - this.BASE_TIME) % MILLIS_PER_DAY) 389 hh := (int)(dtime / MILLIS_PER_HOUR) 390 dtime = (int)(dtime % MILLIS_PER_HOUR) 391 mm := (int)(dtime / MILLIS_PER_MINUTE) 392 dtime = (int)(dtime % MILLIS_PER_MINUTE) 393 ss := (int)(dtime / MILLIS_PER_SECOND) 394 return fmt.Sprintf("%02d%02d%02d", hh, mm, ss) 395 } 396 func (this *DateTimeHelper) hhmm(time int64) string { 397 if time < this.BASE_TIME { 398 return "0000" 399 } 400 dtime := (int)((time - this.BASE_TIME) % MILLIS_PER_DAY) 401 hh := (int)(dtime / MILLIS_PER_HOUR) 402 dtime = (int)(dtime % MILLIS_PER_HOUR) 403 mm := (int)(dtime / MILLIS_PER_MINUTE) 404 return fmt.Sprintf("%02d%02d", hh, mm) 405 }