/** 只适用于一天24小时开奖的情况,0->1 **/ package gametimer import ( "errors" "fmt" "strconv" "strings" "time" "github.com/gookit/event" "github.com/sirupsen/logrus" "gogs.daxia.dev/huanan/pkg.daxia.dev.git/intutils" "gogs.daxia.dev/huanan/pkg.daxia.dev.git/time_utils" ) const ( EventTimerStart = "EventTimerStart" EventTimerStop = "EventTimerStop" ) type GameTimer struct { baseTime time.Time baseName string totalSecond int stopSecond int currentEvent string } func NewGameTimer(baseName string, baseTime time.Time, totalSecond, stopSecond int) *GameTimer { if stopSecond > totalSecond { panic("stop second > total second") } if (1440*60)%totalSecond != 0 { panic("total second不能被整除") } instance := &GameTimer{ baseTime: baseTime, baseName: baseName, totalSecond: totalSecond, stopSecond: stopSecond, } instance.currentEvent = "" go instance.start() return instance } func (p *GameTimer) start() { for { <-time.After(1 * time.Second) err := p.doWork() if err != nil { logrus.Error(err) } } } func (p *GameTimer) doWork() error { currentEvent := p.GetCurrentEvent() if p.currentEvent == currentEvent { return nil } p.currentEvent = currentEvent event.MustFire(p.currentEvent, event.M{}) return nil } func (p *GameTimer) GetCurrentEvent() string { secondFromBase := time_utils.TimeNowInCN().Unix() - p.baseTime.Unix() //180 [0 - 180] secondInRange := secondFromBase % int64(p.totalSecond) if secondInRange < int64(p.stopSecond) { return p.GetEvent(EventTimerStart) } return p.GetEvent(EventTimerStop) } func (p *GameTimer) GetIssueByTime(timeIssue time.Time) int64 { secondFromBase := timeIssue.Unix() - p.baseTime.Unix() issue := secondFromBase / int64(p.totalSecond) return (issue + 1) } func (p *GameTimer) GetIssueStrByTime(timeIssue time.Time) string { return p.GetIssueStr(p.GetIssueByTime(timeIssue)) } func (p *GameTimer) GetIssueStr(issue int64) string { timestamp := p.baseTime.Unix() + int64(issue-1)*int64(p.totalSecond) timeIssue := time.Unix(timestamp, 0) timeIssueCN := timeIssue.In(time_utils.GetCNZone()) totalIssueOnDay := (1440 * 60) / p.totalSecond maxSize := intutils.IntSize(totalIssueOnDay) fmtStr := fmt.Sprintf("0%dd", maxSize) todayIssue := p.GetIssueFromTodayZero(timeIssueCN) return timeIssueCN.Format("2006-01-02") + " " + fmt.Sprintf("%"+fmtStr, todayIssue) } func (p *GameTimer) GetIssueFromStr(issueStr string) (int64, error) { timeIssue, err := p.GetIssueTime(issueStr) if err != nil { return 0, err } fmt.Println(timeIssue) fmt.Println(p.baseTime) return 1 + ((timeIssue.Unix() - p.baseTime.Unix()) / int64(p.totalSecond)), nil } func (p *GameTimer) GetIssueTime(issueStr string) (*time.Time, error) { issueTimeSplit := strings.Split(issueStr, " ") if len(issueTimeSplit) != 2 { return nil, errors.New("期号格式错误") } timeIssue, err := time.ParseInLocation("2006-01-02", issueTimeSplit[0], time_utils.GetCNZone()) if err != nil { return nil, err } numStr := strings.TrimLeft(issueTimeSplit[1], "0") issueInt, err := strconv.Atoi(numStr) if err != nil { return nil, err } timeIssue = timeIssue.Add(time.Duration(issueInt-1) * time.Duration(p.totalSecond) * time.Second) return &timeIssue, nil } func (p *GameTimer) GetIssueTimeInt(issue int64) (*time.Time, error) { issueStr := p.GetIssueStr(issue) return p.GetIssueTime(issueStr) } func (p *GameTimer) GetBaseTime() time.Time { return p.baseTime } func (p *GameTimer) GetIssueFromTodayZero(timeIssue time.Time) int64 { secondFromBase := timeIssue.Unix() - time_utils.GetZeroTime(timeIssue).Unix() issue := secondFromBase / int64(p.totalSecond) return issue + 1 } func (p GameTimer) GetEvent(eventName string) string { return p.baseName + eventName }