github.com/hirochachacha/plua@v0.0.0-20170217012138-c82f520cc725/stdlib/os/date.go (about) 1 package os 2 3 import ( 4 "bytes" 5 "fmt" 6 "strconv" 7 "strings" 8 "time" 9 10 "github.com/hirochachacha/plua/object" 11 ) 12 13 var formatFuncs = map[byte]func(time.Time) string{ 14 'a': func(t time.Time) string { 15 return t.Format("Mon") 16 }, 17 'A': func(t time.Time) string { 18 return t.Format("Monday") 19 }, 20 'b': func(t time.Time) string { 21 return t.Format("Jan") 22 }, 23 'B': func(t time.Time) string { 24 return t.Format("January") 25 }, 26 'c': func(t time.Time) string { 27 return t.Format("Mon Jan 2 15:04:05 MST 2006") 28 }, 29 'd': func(t time.Time) string { 30 return t.Format("02") 31 }, 32 'F': func(t time.Time) string { 33 return t.Format("2006-01-02") 34 }, 35 'H': func(t time.Time) string { 36 return t.Format("15") 37 }, 38 'I': func(t time.Time) string { 39 return t.Format("03") 40 }, 41 'j': func(t time.Time) string { 42 return fmt.Sprintf("%03d", t.YearDay()) 43 }, 44 'm': func(t time.Time) string { 45 return t.Format("01") 46 }, 47 'M': func(t time.Time) string { 48 return t.Format("04") 49 }, 50 'p': func(t time.Time) string { 51 return t.Format("PM") 52 }, 53 'S': func(t time.Time) string { 54 return t.Format("05") 55 }, 56 // 'U': func(t time.Time) string { 57 // }, 58 'w': func(t time.Time) string { 59 return strconv.Itoa(int(t.Weekday())) 60 }, 61 'W': func(t time.Time) string { 62 _, week := t.ISOWeek() 63 return fmt.Sprintf("%02d", week) 64 }, 65 'x': func(t time.Time) string { 66 return t.Format("Mon Jan 2") 67 }, 68 'X': func(t time.Time) string { 69 return t.Format("15:04:05") 70 }, 71 'y': func(t time.Time) string { 72 return t.Format("06") 73 }, 74 'Y': func(t time.Time) string { 75 return t.Format("2006") 76 }, 77 'Z': func(t time.Time) string { 78 return t.Format("MST") 79 }, 80 '%': func(t time.Time) string { 81 return "%" 82 }, 83 } 84 85 func dateFormat(th object.Thread, format string, t time.Time) (string, *object.RuntimeError) { 86 var buf bytes.Buffer 87 88 var start int 89 var end int 90 for { 91 end = strings.IndexRune(format[start:], '%') 92 if end == -1 { 93 buf.WriteString(format[start:]) 94 break 95 } 96 97 end += start 98 99 if end == len(format)-1 { 100 return "", object.NewRuntimeError("invalid conversion specifier '%'") 101 } 102 103 buf.WriteString(format[start:end]) 104 105 if fn, ok := formatFuncs[format[end+1]]; ok { 106 buf.WriteString(fn(t)) 107 } else { 108 return "", object.NewRuntimeError("invalid conversion specifier '%" + string(format[end+1]) + "'") 109 } 110 111 if end == len(format)-2 { 112 break 113 } 114 115 start = end + 2 116 } 117 118 return buf.String(), nil 119 } 120 121 func updateTable(th object.Thread, tab object.Table, t time.Time) { 122 // suggested algorithm at http://play.golang.org/p/JvHUk1NjO5 123 124 _, n := t.Zone() 125 _, w := time.Date(t.Year(), 1, 1, 0, 0, 0, 0, t.Location()).Zone() 126 _, s := time.Date(t.Year(), 1, 1, 0, 0, 0, 0, t.Location()).Zone() 127 128 if w > s { 129 w, s = s, w 130 } 131 132 isdst := w != s && n != w 133 134 tab.Set(object.String("isdst"), object.Boolean(isdst)) 135 136 tab.Set(object.String("wday"), object.Integer(int(t.Weekday()+1))) 137 tab.Set(object.String("year"), object.Integer(t.Year())) 138 tab.Set(object.String("sec"), object.Integer(t.Second())) 139 tab.Set(object.String("month"), object.Integer(int(t.Month()))) 140 tab.Set(object.String("day"), object.Integer(t.Day())) 141 tab.Set(object.String("hour"), object.Integer(t.Hour())) 142 tab.Set(object.String("yday"), object.Integer(int(t.YearDay()))) 143 tab.Set(object.String("min"), object.Integer(t.Minute())) 144 }