123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- package timefmt
- import (
- "git.swzry.com/zry/YAGTF/yagtf/tfelem"
- "regexp"
- "strconv"
- "strings"
- "time"
- )
- const parserTokenBufferSize = 128
- const regexpTimezoneTag = "^Timezone:([+-][0-9]{4})([A-Z]{3})$"
- type TimeElementFactoryFunc func() TimeElement
- type NonDisplayTagFunc func(tp *TimePrinter)
- type FormatParser struct {
- tagList map[string]TimeElementFactoryFunc
- ndTagList map[string]NonDisplayTagFunc
- tzsReg *regexp.Regexp
- }
- func NewFormatParser() *FormatParser {
- f := &FormatParser{
- tagList: make(map[string]TimeElementFactoryFunc),
- ndTagList: make(map[string]NonDisplayTagFunc),
- }
- f.addDefaultElementClasses()
- f.tzsReg, _ = regexp.Compile(regexpTimezoneTag)
- return f
- }
- func (this *FormatParser) AddElementClass(tagname string, ff TimeElementFactoryFunc) {
- this.tagList[tagname] = ff
- }
- func (this *FormatParser) AddTagAlias(alias string, tagname string) {
- v, ok := this.tagList[tagname]
- if ok {
- this.tagList[alias] = v
- }
- }
- func (this *FormatParser) AddNonDisplayTag(tagname string, nf NonDisplayTagFunc) {
- this.ndTagList[tagname] = nf
- }
- func (this *FormatParser) ParseFormatString(tp *TimePrinter, fs string) {
- if len(fs) < 1 {
- return
- }
- if fs[0] == '!' {
- this.parseAdvancedFmt(tp, fs[1:])
- } else {
- this.parseBasicFmt(tp, fs)
- }
- }
- func (this *FormatParser) parseBasicFmt(tp *TimePrinter, fs string) {
- s := fs
- s = strings.Replace(s, "!", "<#000>", -1)
- s = strings.Replace(s, "yyyy", "<#001>", -1)
- s = strings.Replace(s, "yy", "<#002>", -1)
- s = strings.Replace(s, "MM", "<#003>", -1)
- s = strings.Replace(s, "M3", "<#004>", -1)
- s = strings.Replace(s, "M09", "<#005>", -1)
- s = strings.Replace(s, "M9", "<#006>", -1)
- s = strings.Replace(s, "M", "<#007>", -1)
- s = strings.Replace(s, "dd", "<#008>", -1)
- s = strings.Replace(s, "d", "<#009>", -1)
- s = strings.Replace(s, "HH", "<#010>", -1)
- s = strings.Replace(s, "hh", "<#011>", -1)
- s = strings.Replace(s, "H", "<#012>", -1)
- s = strings.Replace(s, "h", "<#013>", -1)
- s = strings.Replace(s, "mm", "<#014>", -1)
- s = strings.Replace(s, "ss", "<#015>", -1)
- s = strings.Replace(s, "E09", "<#016>", -1)
- s = strings.Replace(s, "E9", "<#017>", -1)
- s = strings.Replace(s, "E3", "<#018>", -1)
- s = strings.Replace(s, "A", "<#019>", -1)
- s = strings.Replace(s, "S1", "<#020>", -1)
- s = strings.Replace(s, "S2", "<#021>", -1)
- s = strings.Replace(s, "S3", "<#022>", -1)
- s = strings.Replace(s, "Z", "<#023>", -1)
- s = strings.Replace(s, "z", "<#024>", -1)
- this.parseAdvancedFmt(tp, s)
- }
- func (this *FormatParser) parseAdvancedFmt(tp *TimePrinter, fs string) {
- if len(fs) > 1 {
- if fs[0] == '!' {
- this.parseBasicFmt(tp, fs[1:])
- return
- }
- }
- stat := false
- ba := []byte(fs)
- ptbuf := make([]byte, 0, parserTokenBufferSize)
- for _, v := range ba {
- if stat {
- if v == '>' {
- this.processTag(tp, string(ptbuf))
- ptbuf = make([]byte, 0, parserTokenBufferSize)
- stat = false
- } else {
- ptbuf = append(ptbuf, v)
- }
- } else {
- if v == '<' {
- tp.AddPureText(string(ptbuf))
- ptbuf = make([]byte, 0, parserTokenBufferSize)
- stat = true
- } else {
- ptbuf = append(ptbuf, v)
- }
- }
- }
- }
- func (this *FormatParser) processTimezoneTag(tp *TimePrinter, tzs string, tzname string) {
- sg := 0
- if tzs[0] == '+' {
- sg = 1
- } else if tzs[0] == '-' {
- sg = -1
- } else {
- return
- }
- if len(tzs) != 5 {
- return
- }
- hs := tzs[1:3]
- ms := tzs[3:5]
- hi, err := strconv.Atoi(hs)
- if err != nil {
- return
- }
- mi, err := strconv.Atoi(ms)
- if err != nil {
- return
- }
- ofs := (hi*3600 + mi*60) * sg
- tz := time.FixedZone(tzname, ofs)
- tp.UseTimezone(tz)
- }
- func (this *FormatParser) processTag(tp *TimePrinter, tag string) {
- rrs := this.tzsReg.FindStringSubmatch(tag)
- if len(rrs) == 3 {
- this.processTimezoneTag(tp, rrs[1], rrs[2])
- return
- }
- v1, ok := this.ndTagList[tag]
- if ok {
- v1(tp)
- return
- }
- v2, ok := this.tagList[tag]
- if ok {
- tp.AddElement(v2())
- } else {
- tp.AddPureText("<" + tag + ">")
- }
- }
- func (this *FormatParser) addDefaultElementClasses() {
- this.AddNonDisplayTag("UTC", func(tp *TimePrinter) { tp.UseUTC() })
- this.AddNonDisplayTag("Local", func(tp *TimePrinter) { tp.UseLocalTimezone() })
- this.AddElementClass("year", func() TimeElement { return tfelem.NewYearElement(false) })
- this.AddElementClass("shortYear", func() TimeElement { return tfelem.NewYearElement(true) })
- this.AddElementClass("month", func() TimeElement { return tfelem.NewNumbericMonthElement(true) })
- this.AddElementClass("monthNoFill", func() TimeElement { return tfelem.NewNumbericMonthElement(false) })
- this.AddElementClass("monthAbbr", func() TimeElement { return tfelem.NewEnglishMonthElement(true, false) })
- this.AddElementClass("monthName", func() TimeElement { return tfelem.NewEnglishMonthElement(false, true) })
- this.AddElementClass("monthNameNoFill", func() TimeElement { return tfelem.NewEnglishMonthElement(false, false) })
- this.AddElementClass("day", func() TimeElement { return tfelem.NewDayElement(true) })
- this.AddElementClass("dayNoFill", func() TimeElement { return tfelem.NewDayElement(false) })
- this.AddElementClass("hour24", func() TimeElement { return tfelem.NewHour24hElement(true) })
- this.AddElementClass("hour24NoFill", func() TimeElement { return tfelem.NewHour24hElement(false) })
- this.AddElementClass("hour12", func() TimeElement { return tfelem.NewHour12hElement(true) })
- this.AddElementClass("hour12NoFill", func() TimeElement { return tfelem.NewHour12hElement(false) })
- this.AddElementClass("minute", func() TimeElement { return tfelem.NewMinuteElement() })
- this.AddElementClass("second", func() TimeElement { return tfelem.NewSecondElement() })
- this.AddElementClass("ms", func() TimeElement { return tfelem.NewSecondFloatPartElementWithMilliSec() })
- this.AddElementClass("us", func() TimeElement { return tfelem.NewSecondFloatPartElementWithMicroSec() })
- this.AddElementClass("ns", func() TimeElement { return tfelem.NewSecondFloatPartElementWithNanoSec() })
- this.AddElementClass("weekday", func() TimeElement { return tfelem.NewNumbericWeekDayElement() })
- this.AddElementClass("weekdayAbbr", func() TimeElement { return tfelem.NewEnglishWeekDayElement(true, false) })
- this.AddElementClass("weekdayName", func() TimeElement { return tfelem.NewEnglishWeekDayElement(false, true) })
- this.AddElementClass("weekdayNameNoFill", func() TimeElement { return tfelem.NewEnglishWeekDayElement(false, false) })
- this.AddElementClass("ampm", func() TimeElement { return tfelem.NewAMPMElement() })
- this.AddElementClass("yearweek", func() TimeElement { return tfelem.NewWeekElement(true) })
- this.AddElementClass("yearweekNoFill", func() TimeElement { return tfelem.NewWeekElement(false) })
- this.AddElementClass("yearday", func() TimeElement { return tfelem.NewYearDayElement(true) })
- this.AddElementClass("yeardayNoFill", func() TimeElement { return tfelem.NewYearDayElement(false) })
- this.AddElementClass("timezone", func() TimeElement { return tfelem.NewTimeZoneUTCOffsetElement() })
- this.AddElementClass("timezoneAbbr", func() TimeElement { return tfelem.NewTimeZoneAbbrElement() })
- this.AddElementClass("timezoneSec", func() TimeElement { return tfelem.NewTimeZoneNumbericOffsetElement(true) })
- this.AddElementClass("timezoneSecNoFill", func() TimeElement { return tfelem.NewTimeZoneNumbericOffsetElement(false) })
- this.AddElementClass("iso8601date", func() TimeElement { return tfelem.NewISO8601DateElement() })
- this.AddElementClass("iso8601time", func() TimeElement { return tfelem.NewISO8601TimeElement() })
- this.AddElementClass("iso8601full", func() TimeElement { return tfelem.NewISO8601FullElement() })
- this.AddElementClass("common", func() TimeElement { return tfelem.NewCommonDatetimeElement() })
- this.AddElementClass("nginx", func() TimeElement { return tfelem.NewNginxDefaultElement() })
- this.AddElementClass("!", func() TimeElement { return &tfelem.PureTextElement{PureText: "!"} })
- this.AddElementClass("lt", func() TimeElement { return &tfelem.PureTextElement{PureText: "<"} })
- this.AddElementClass("gt", func() TimeElement { return &tfelem.PureTextElement{PureText: ">"} })
- this.AddElementClass("q", func() TimeElement { return &tfelem.PureTextElement{PureText: `"`} })
- this.AddElementClass("sq", func() TimeElement { return &tfelem.PureTextElement{PureText: "'"} })
- this.AddElementClass("tab", func() TimeElement { return &tfelem.PureTextElement{PureText: "\t"} })
- this.AddElementClass("br", func() TimeElement { return &tfelem.PureTextElement{PureText: "\n"} })
- this.AddElementClass("cr", func() TimeElement { return &tfelem.PureTextElement{PureText: "\r"} })
- this.AddElementClass("sp", func() TimeElement { return &tfelem.PureTextElement{PureText: "!"} })
- this.AddTagAlias("y", "year")
- this.AddTagAlias("sy", "shortYear")
- this.AddTagAlias("mon", "month")
- this.AddTagAlias("monNF", "monthNoFill")
- this.AddTagAlias("monA", "monthAbbr")
- this.AddTagAlias("monN", "monthName")
- this.AddTagAlias("monNNF", "monthNameNoFill")
- this.AddTagAlias("d", "day")
- this.AddTagAlias("dNF", "dayNoFill")
- this.AddTagAlias("h24", "hour24")
- this.AddTagAlias("h12", "hour12")
- this.AddTagAlias("h24NF", "hour24NoFill")
- this.AddTagAlias("h12NF", "hour12NoFill")
- this.AddTagAlias("min", "minute")
- this.AddTagAlias("s", "second")
- this.AddTagAlias("wd", "weekday")
- this.AddTagAlias("wdN", "weekdayName")
- this.AddTagAlias("wdNNF", "weekdayNameNoFill")
- this.AddTagAlias("wdA", "weekdayAbbr")
- this.AddTagAlias("yw", "yearweek")
- this.AddTagAlias("ywNF", "yearweekNoFill")
- this.AddTagAlias("yd", "yearday")
- this.AddTagAlias("ydNF", "yeardayNoFill")
- this.AddTagAlias("tz", "timezone")
- this.AddTagAlias("tzA", "timezoneAbbr")
- this.AddTagAlias("tzS", "timezoneSec")
- this.AddTagAlias("tzSNF", "timezoneSecNoFill")
- this.AddTagAlias("i8d", "iso8601date")
- this.AddTagAlias("i8t", "iso8601time")
- this.AddTagAlias("i8f", "iso8601full")
- this.AddTagAlias("#000", "!")
- this.AddTagAlias("#001", "year")
- this.AddTagAlias("#002", "shortYear")
- this.AddTagAlias("#003", "month")
- this.AddTagAlias("#004", "monthAbbr")
- this.AddTagAlias("#005", "monthName")
- this.AddTagAlias("#006", "monthNameNoFill")
- this.AddTagAlias("#007", "monthNoFill")
- this.AddTagAlias("#008", "day")
- this.AddTagAlias("#009", "dayNoFill")
- this.AddTagAlias("#010", "hour24")
- this.AddTagAlias("#011", "hour12")
- this.AddTagAlias("#012", "hour24NoFill")
- this.AddTagAlias("#013", "hour12NoFill")
- this.AddTagAlias("#014", "minute")
- this.AddTagAlias("#015", "second")
- this.AddTagAlias("#016", "weekdayName")
- this.AddTagAlias("#017", "weekdayNameNoFill")
- this.AddTagAlias("#018", "weekdayAbbr")
- this.AddTagAlias("#019", "ampm")
- this.AddTagAlias("#020", "ms")
- this.AddTagAlias("#021", "us")
- this.AddTagAlias("#022", "ns")
- this.AddTagAlias("#023", "timezoneAbbr")
- this.AddTagAlias("#024", "timezone")
- }
|