update new func
This commit is contained in:
+321
@@ -0,0 +1,321 @@
|
||||
package when
|
||||
|
||||
import (
|
||||
"b612.me/startimer"
|
||||
"errors"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func matchPeriodPattern01(base time.Time, str string) (startimer.StarTimer, error) {
|
||||
str = transChn(str)
|
||||
var rpt startimer.Repeats
|
||||
var duration time.Duration
|
||||
reg := regexp.MustCompile(`(每隔|每)?(\d{1,4}年)?(\d{1,5}个?月)?(\d{1,4}[明后大]{0,4}[日号天])?([上中下午夜早凌清晨傍晚里]+)?(\d{1,4}个?[点小时钟:]+)?(\d{1,4}[分:])?(\d{1,10}秒?)?(后)?`)
|
||||
if reg.MatchString(str) {
|
||||
pts := reg.FindStringSubmatch(str)
|
||||
var timeParse = pts[5]
|
||||
count := 1
|
||||
if pts[1] != "" {
|
||||
rpt.Every = true
|
||||
count = 0
|
||||
}
|
||||
if pts[2] != "" {
|
||||
if !rpt.Every {
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_YEAR, Value: uint32(getNumbers(pts[2]))})
|
||||
} else {
|
||||
duration += time.Hour * 24 * 365 * time.Duration(getNumbers(pts[2]))
|
||||
}
|
||||
}
|
||||
if pts[3] != "" {
|
||||
if !rpt.Every {
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_MONTH, Value: uint32(getNumbers(pts[3]))})
|
||||
} else {
|
||||
duration += time.Hour * 24 * 30 * time.Duration(getNumbers(pts[3]))
|
||||
}
|
||||
}
|
||||
if pts[4] != "" {
|
||||
now := time.Now()
|
||||
switch pts[4] {
|
||||
case "明天":
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_DAY, Value: uint32(now.Add(time.Hour * 24).Day())})
|
||||
case "后天":
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_DAY, Value: uint32(now.Add(time.Hour * 48).Day())})
|
||||
case "大后天":
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_DAY, Value: uint32(now.Add(time.Hour * 72).Day())})
|
||||
case "大大后天":
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_DAY, Value: uint32(now.Add(time.Hour * 96).Day())})
|
||||
default:
|
||||
if !rpt.Every {
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_DAY, Value: uint32(getNumbers(pts[4]))})
|
||||
} else {
|
||||
duration += time.Hour * 24 * time.Duration(getNumbers(pts[4]))
|
||||
}
|
||||
}
|
||||
}
|
||||
setAsDate := false
|
||||
if rpt.Every && timeParse != "" {
|
||||
setAsDate = true
|
||||
} else if rpt.Every && !strings.Contains(pts[6], "小时") {
|
||||
setAsDate = true
|
||||
base = time.Date(base.Year(), base.Month(), base.Day(), 0, 0, 0, 0, base.Location())
|
||||
}
|
||||
var hour uint32
|
||||
if pts[6] != "" {
|
||||
hour = uint32(getNumbers(pts[6]))
|
||||
if timeParse == "下午" || strings.Contains(timeParse, "晚") || strings.Contains(timeParse, "夜") {
|
||||
hour += 12
|
||||
}
|
||||
if !setAsDate && !rpt.Every {
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_HOUR, Value: hour})
|
||||
} else if rpt.Every && !setAsDate {
|
||||
duration += time.Hour * time.Duration(hour)
|
||||
} else {
|
||||
base.Add(time.Hour * time.Duration(hour))
|
||||
}
|
||||
} else if timeParse != "" {
|
||||
switch timeParse {
|
||||
case "上午":
|
||||
hour = 9
|
||||
case "中午":
|
||||
hour = 8
|
||||
case "下午":
|
||||
hour = 15
|
||||
case "傍晚":
|
||||
hour = 18
|
||||
case "夜里", "晚上", "晚", "夜", "夜晚":
|
||||
hour = 21
|
||||
case "凌晨":
|
||||
hour = 0
|
||||
case "清晨":
|
||||
hour = 6
|
||||
}
|
||||
if !setAsDate {
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_HOUR, Value: hour})
|
||||
} else {
|
||||
base.Add(time.Hour * time.Duration(hour))
|
||||
}
|
||||
}
|
||||
if pts[7] != "" {
|
||||
if !setAsDate && !rpt.Every {
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_MINUTE, Value: uint32(getNumbers(pts[7]))})
|
||||
} else if rpt.Every && !setAsDate {
|
||||
duration += time.Minute * time.Duration(uint32(getNumbers(pts[7])))
|
||||
} else {
|
||||
base.Add(time.Minute * time.Duration(uint32(getNumbers(pts[7]))))
|
||||
}
|
||||
} else if hour != 0 {
|
||||
if !rpt.Every && !setAsDate {
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_MINUTE, Value: 0})
|
||||
}
|
||||
}
|
||||
|
||||
if pts[8] != "" {
|
||||
if !setAsDate && !rpt.Every {
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_SECOND, Value: uint32(getNumbers(pts[8]))})
|
||||
} else if rpt.Every && !setAsDate {
|
||||
duration += time.Second * time.Duration(uint32(getNumbers(pts[8])))
|
||||
} else {
|
||||
base.Add(time.Second * time.Duration(uint32(getNumbers(pts[8]))))
|
||||
}
|
||||
} else if hour != 0 {
|
||||
if !rpt.Every && !setAsDate {
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_SECOND, Value: 0})
|
||||
}
|
||||
}
|
||||
if pts[9] != "" {
|
||||
if rpt.Every {
|
||||
return startimer.StarTimer{}, errors.New("Invalid Setences")
|
||||
}
|
||||
now := time.Now()
|
||||
for _, sr := range rpt.Repeat {
|
||||
switch sr.Unit {
|
||||
case startimer.STAR_YEAR:
|
||||
now = now.AddDate(int(sr.Value), 0, 0)
|
||||
case startimer.STAR_MONTH:
|
||||
now = now.AddDate(0, int(sr.Value), 0)
|
||||
case startimer.STAR_DAY:
|
||||
now = now.AddDate(0, 0, int(sr.Value))
|
||||
case startimer.STAR_HOUR:
|
||||
now = now.Add(time.Duration(sr.Value) * time.Hour)
|
||||
case startimer.STAR_MINUTE:
|
||||
now = now.Add(time.Duration(sr.Value) * time.Minute)
|
||||
case startimer.STAR_SECOND:
|
||||
now = now.Add(time.Duration(sr.Value) * time.Second)
|
||||
}
|
||||
}
|
||||
return startimer.NewTimer(time.Now(), startimer.WithStaticDate(now), startimer.WithRunCountLimit(count)), nil
|
||||
}
|
||||
if duration.Seconds() > 0 {
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_SECOND, Value: uint32(duration.Seconds())})
|
||||
}
|
||||
return startimer.NewTimer(base, startimer.WithRepeats(&rpt), startimer.WithRunCountLimit(count)), nil
|
||||
}
|
||||
return startimer.StarTimer{}, errors.New("no Match")
|
||||
}
|
||||
|
||||
func matchPeroidPattern02(base time.Time, str string) (startimer.StarTimer, error) {
|
||||
str = transChn(str)
|
||||
var rpt startimer.Repeats
|
||||
reg := regexp.MustCompile(`(每)?([周星期礼拜][周礼拜星期到1-6日天]+)+的?([上中下午夜早凌清晨傍晚里]+)?(\d{1,4}[个点时:]+)?(\d{1,4}[分:])?(\d{1,10}秒?)?`)
|
||||
if reg.MatchString(str) {
|
||||
pts := reg.FindStringSubmatch(str)
|
||||
if pts[2] != "" {
|
||||
wk := strings.ReplaceAll(pts[2], "周日", "周0")
|
||||
wk = strings.ReplaceAll(wk, "礼拜天", "周0")
|
||||
wk = strings.ReplaceAll(wk, "星期日", "周0")
|
||||
wk = strings.ReplaceAll(wk, "星期天", "周0")
|
||||
wk = strings.ReplaceAll(wk, "周天", "周0")
|
||||
if strings.Contains(wk, "到") {
|
||||
pk := strings.Split(wk, "到")
|
||||
startWk := getNumbers(pk[0])
|
||||
endWk := getNumbers(pk[1])
|
||||
if endWk < startWk {
|
||||
endWk += 7
|
||||
}
|
||||
for i := startWk; i <= endWk; i++ {
|
||||
num := i
|
||||
if num > 6 {
|
||||
num -= 7
|
||||
}
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_WEEK, Value: uint32(num)})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
timeParse := pts[3]
|
||||
var hour uint32
|
||||
if pts[4] != "" {
|
||||
hour = uint32(getNumbers(pts[4]))
|
||||
if timeParse == "下午" || strings.Contains(timeParse, "晚") || strings.Contains(timeParse, "夜") {
|
||||
hour += 12
|
||||
}
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_HOUR, Value: hour})
|
||||
} else if timeParse != "" {
|
||||
switch timeParse {
|
||||
case "上午":
|
||||
hour = 9
|
||||
case "中午":
|
||||
hour = 8
|
||||
case "下午":
|
||||
hour = 15
|
||||
case "傍晚":
|
||||
hour = 18
|
||||
case "夜里", "晚上", "晚", "夜", "夜晚":
|
||||
hour = 21
|
||||
case "凌晨":
|
||||
hour = 0
|
||||
case "清晨":
|
||||
hour = 6
|
||||
}
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_HOUR, Value: hour})
|
||||
}
|
||||
if pts[5] != "" {
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_MINUTE, Value: uint32(getNumbers(pts[5]))})
|
||||
} else if hour != 0 {
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_MINUTE, Value: 0})
|
||||
}
|
||||
if pts[6] != "" {
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_SECOND, Value: uint32(getNumbers(pts[6]))})
|
||||
} else if hour != 0 {
|
||||
rpt.Repeat = append(rpt.Repeat, startimer.Repeat{Unit: startimer.STAR_SECOND, Value: 0})
|
||||
}
|
||||
count := 1
|
||||
if pts[1] != "" {
|
||||
count = 0
|
||||
}
|
||||
return startimer.NewTimer(base, startimer.WithRepeats(&rpt), startimer.WithRunCountLimit(count)), nil
|
||||
}
|
||||
return startimer.StarTimer{}, errors.New("no Match")
|
||||
}
|
||||
|
||||
func WhenWithPeriod(str string) (startimer.StarTimer, error) {
|
||||
if match, _ := regexp.MatchString(`(周|星期|礼拜)[一二三四五六天日]`, str); match {
|
||||
return matchPeroidPattern02(time.Now(), str)
|
||||
}
|
||||
return matchPeriodPattern01(time.Now(), str)
|
||||
}
|
||||
|
||||
func transChn(msg string) string {
|
||||
var res []rune
|
||||
var tmpMap []rune
|
||||
keyMap := map[rune]int{
|
||||
'零': 0, '一': 1, '二': 2, '三': 3, '四': 4, '五': 5, '六': 6, '七': 7, '八': 8, '九': 9, '十': 10, '百': 100, '千': 1000, '万': 10000, '亿': 100000000, '两': 2, '俩': 2,
|
||||
}
|
||||
for _, v := range []rune(msg) {
|
||||
if _, ok := keyMap[v]; ok {
|
||||
tmpMap = append(tmpMap, v)
|
||||
} else {
|
||||
if len(tmpMap) != 0 {
|
||||
res = append(res, []rune(strconv.Itoa(transfer(string(tmpMap))))...)
|
||||
tmpMap = []rune{}
|
||||
}
|
||||
res = append(res, v)
|
||||
}
|
||||
}
|
||||
return string(res)
|
||||
}
|
||||
func transfer(msg string) int {
|
||||
keyMap := map[rune]int{
|
||||
'零': 0, '一': 1, '二': 2, '三': 3, '四': 4, '五': 5, '六': 6, '七': 7, '八': 8, '九': 9, '十': 10, '百': 100, '千': 1000, '万': 10000, '亿': 100000000, '两': 2, '俩': 2,
|
||||
}
|
||||
result := 0
|
||||
secCache := 0
|
||||
thrCache := 0
|
||||
fKWord := map[rune]int{'百': 100, '千': 1000, '万': 10000, '亿': 100000000}
|
||||
for _, num := range []rune(msg) {
|
||||
if _, match := fKWord[num]; !match {
|
||||
if num == '十' && thrCache != 0 {
|
||||
thrCache *= keyMap[num]
|
||||
} else {
|
||||
thrCache += keyMap[num]
|
||||
}
|
||||
} else {
|
||||
if fKWord[num] < 10000 {
|
||||
secCache += thrCache * fKWord[num]
|
||||
thrCache = 0
|
||||
} else {
|
||||
secCache += thrCache
|
||||
thrCache = 0
|
||||
if secCache == 0 {
|
||||
result *= fKWord[num]
|
||||
continue
|
||||
}
|
||||
result += secCache * fKWord[num]
|
||||
secCache = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result += secCache + thrCache
|
||||
return result
|
||||
}
|
||||
|
||||
func getNumbers(s string) float64 {
|
||||
res := ""
|
||||
isNegative := false
|
||||
|
||||
for _, c := range s {
|
||||
switch {
|
||||
case c == '-' && len(res) == 0:
|
||||
isNegative = true
|
||||
case c >= '0' && c <= '9':
|
||||
res += string(c)
|
||||
case c == '.' && !strings.Contains(res, "."):
|
||||
res += string(c)
|
||||
}
|
||||
}
|
||||
|
||||
if res == "" {
|
||||
return 0
|
||||
}
|
||||
|
||||
if isNegative {
|
||||
res = "-" + res
|
||||
}
|
||||
|
||||
num, _ := strconv.ParseFloat(res, 64)
|
||||
return num
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package when
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
for _, code := range []string{"一个小时后告诉我事情", "三个小时后爱我", "每两个小时提醒我吃饭", "每五个月零二十五天三小时25分15秒告诉我时间", "5月23日上午3点24分12秒打我", "周四上午11点提醒我"} {
|
||||
a, _ := WhenWithPeriod(code)
|
||||
//fmt.Println(a.Repeats()[0])
|
||||
fmt.Println(a.NextTimer(), a.RunCountLimit(), code)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user