github.com/whatap/golib@v0.0.22/util/dateutil/DateFormat.go (about) 1 package dateutil 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "strconv" 8 "time" 9 ) 10 11 const ( 12 DATEFORMAT_YEAR = 'y' 13 DATEFORMAT_MONTH = 'm' 14 DATEFORMAT_DAY = 'd' 15 DATEFORMAT_HOUR = 'H' 16 DATEFORMAT_MINUTE = 'M' 17 DATEFORMAT_SECOND = 'S' 18 DATEFORMAT_MILLISECOND = 's' 19 ) 20 21 type DateFormat struct { 22 formatStr []rune 23 dateStr string 24 date map[rune]int 25 } 26 27 func NewDateFormat(formatStr string) *DateFormat { 28 p := new(DateFormat) 29 p.formatStr = []rune(formatStr) 30 p.date = make(map[rune]int) 31 return p 32 } 33 34 func (this *DateFormat) Format() string { 35 return this.format(time.Now()) 36 } 37 func (this *DateFormat) FormatTime(t time.Time) string { 38 return this.format(t) 39 } 40 41 func (this *DateFormat) format(t time.Time) string { 42 ret := this.formatStr 43 var buf bytes.Buffer 44 for _, ch := range ret { 45 switch ch { 46 case DATEFORMAT_YEAR: 47 buf.WriteString(LPadInt(t.Year(), 4)) 48 case DATEFORMAT_MONTH: 49 buf.WriteString(LPadInt(int(t.Month()), 2)) 50 case DATEFORMAT_DAY: 51 buf.WriteString(LPadInt(t.Day(), 2)) 52 case DATEFORMAT_HOUR: 53 buf.WriteString(LPadInt(t.Hour(), 2)) 54 case DATEFORMAT_MINUTE: 55 buf.WriteString(LPadInt(t.Minute(), 2)) 56 case DATEFORMAT_SECOND: 57 buf.WriteString(LPadInt(t.Second(), 2)) 58 case DATEFORMAT_MILLISECOND: 59 buf.WriteString(LPadInt(int((t.UnixNano()/1000000)%1000), 3)) 60 default: 61 buf.WriteRune(ch) 62 } 63 } 64 return buf.String() 65 } 66 67 func (this *DateFormat) Parse(dateStr string) (int64, error) { 68 r := bytes.NewReader([]byte(dateStr)) 69 sz := len(dateStr) 70 now := time.Now() 71 for i, ch := range this.formatStr { 72 if i >= sz { 73 break 74 } 75 switch ch { 76 case DATEFORMAT_YEAR: 77 if v, err := this.ToInt(r, 4); err == nil { 78 this.date[ch] = v 79 } else { 80 return 0, fmt.Errorf("Parse error ch=%s, err=%s ", string(ch), err) 81 } 82 case DATEFORMAT_MONTH: 83 if v, err := this.ToInt(r, 2); err == nil { 84 this.date[ch] = v 85 } else { 86 return 0, fmt.Errorf("Parse error ch=%s, err=%s ", string(ch), err) 87 } 88 case DATEFORMAT_DAY: 89 if v, err := this.ToInt(r, 2); err == nil { 90 this.date[ch] = v 91 } else { 92 return 0, fmt.Errorf("Parse error ch=%s, err=%s ", string(ch), err) 93 } 94 case DATEFORMAT_HOUR: 95 if v, err := this.ToInt(r, 2); err == nil { 96 this.date[ch] = v 97 } else { 98 return 0, fmt.Errorf("Parse error ch=%s, err=%s ", string(ch), err) 99 } 100 case DATEFORMAT_MINUTE: 101 if v, err := this.ToInt(r, 2); err == nil { 102 this.date[ch] = v 103 } else { 104 return 0, fmt.Errorf("Parse error ch=%s, err=%s ", string(ch), err) 105 } 106 case DATEFORMAT_SECOND: 107 if v, err := this.ToInt(r, 2); err == nil { 108 this.date[ch] = v 109 } else { 110 return 0, fmt.Errorf("Parse error ch=%s, err=%s ", string(ch), err) 111 } 112 case DATEFORMAT_MILLISECOND: 113 if v, err := this.ToInt(r, 3); err == nil { 114 this.date[ch] = v 115 } else { 116 return 0, fmt.Errorf("Parse error ch=%s, err=%s ", string(ch), err) 117 } 118 default: 119 r.ReadRune() 120 } 121 } 122 123 // format에 없는 경우, 현재 시간 기준 124 if _, ok := this.date[DATEFORMAT_YEAR]; !ok { 125 this.date[DATEFORMAT_YEAR] = now.Year() 126 } 127 if _, ok := this.date[DATEFORMAT_MONTH]; !ok { 128 this.date[DATEFORMAT_MONTH] = int(now.Month()) 129 } 130 if _, ok := this.date[DATEFORMAT_DAY]; !ok { 131 this.date[DATEFORMAT_DAY] = now.Day() 132 } 133 if _, ok := this.date[DATEFORMAT_HOUR]; !ok { 134 this.date[DATEFORMAT_HOUR] = now.Hour() 135 } 136 if _, ok := this.date[DATEFORMAT_MINUTE]; !ok { 137 this.date[DATEFORMAT_MINUTE] = now.Minute() 138 } 139 if _, ok := this.date[DATEFORMAT_SECOND]; !ok { 140 this.date[DATEFORMAT_SECOND] = now.Second() 141 } 142 if _, ok := this.date[DATEFORMAT_MILLISECOND]; !ok { 143 this.date[DATEFORMAT_MILLISECOND] = int(now.UnixNano() / 1000000 % 1000) 144 } 145 146 d := time.Date(this.date[DATEFORMAT_YEAR], time.Month(this.date[DATEFORMAT_MONTH]), this.date[DATEFORMAT_DAY], this.date[DATEFORMAT_HOUR], 147 this.date[DATEFORMAT_MINUTE], this.date[DATEFORMAT_SECOND], this.date[DATEFORMAT_MILLISECOND]*1000000, time.Now().Location()) 148 tm := d.UnixNano() / 1000000 149 return tm, nil 150 } 151 152 func (this *DateFormat) ToInt(rd *bytes.Reader, size int) (int, error) { 153 buf := make([]byte, size) 154 if n, err := rd.Read(buf); err != nil { 155 if err == io.EOF { 156 return 0, nil 157 } 158 return 0, err 159 } else { 160 if n != size { 161 return 0, fmt.Errorf("Error read size, want=%d, have=%d", size, n) 162 } 163 } 164 165 if v, err := strconv.Atoi(string(buf)); err != nil { 166 return 0, err 167 } else { 168 return v, nil 169 } 170 } 171 172 func padding(n int, ch string) string { 173 buf := bytes.Buffer{} 174 for i := 0; i < n; i++ { 175 buf.WriteString(ch) 176 } 177 return buf.String() 178 } 179 180 func LPadInt(v, size int) string { 181 var ret string 182 ret = fmt.Sprintf("%d", v) 183 if len(ret) > size { 184 return ret 185 } 186 return padding(size-len(ret), "0") + ret 187 }