github.com/gogf/gf/v2@v2.7.4/os/gcron/gcron_schedule_next.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  package gcron
     8  
     9  import (
    10  	"time"
    11  )
    12  
    13  // Next returns the next time this schedule is activated, greater than the given
    14  // time.  If no time can be found to satisfy the schedule, return the zero time.
    15  func (s *cronSchedule) Next(lastMeetTime time.Time) time.Time {
    16  	if s.everySeconds != 0 {
    17  		var (
    18  			diff  = lastMeetTime.Unix() - s.createTimestamp
    19  			count = diff/s.everySeconds + 1
    20  		)
    21  		return lastMeetTime.Add(time.Duration(count*s.everySeconds) * time.Second)
    22  	}
    23  
    24  	var currentTime = lastMeetTime
    25  	if s.ignoreSeconds {
    26  		// Start at the earliest possible time (the upcoming minute).
    27  		currentTime = currentTime.Add(1*time.Minute - time.Duration(currentTime.Nanosecond())*time.Nanosecond)
    28  	} else {
    29  		// Start at the earliest possible time (the upcoming second).
    30  		currentTime = currentTime.Add(1*time.Second - time.Duration(currentTime.Nanosecond())*time.Nanosecond)
    31  	}
    32  
    33  	var (
    34  		loc       = currentTime.Location()
    35  		yearLimit = currentTime.Year() + 5
    36  	)
    37  
    38  WRAP:
    39  	if currentTime.Year() > yearLimit {
    40  		return currentTime // who will care the job that run in five years later
    41  	}
    42  
    43  	for !s.checkMeetMonth(currentTime) {
    44  		currentTime = currentTime.AddDate(0, 1, 0)
    45  		currentTime = time.Date(currentTime.Year(), currentTime.Month(), 1, 0, 0, 0, 0, loc)
    46  		if currentTime.Month() == time.January {
    47  			goto WRAP
    48  		}
    49  	}
    50  	for !s.checkMeetWeek(currentTime) || !s.checkMeetDay(currentTime) {
    51  		currentTime = currentTime.AddDate(0, 0, 1)
    52  		currentTime = time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 0, 0, 0, 0, loc)
    53  		if currentTime.Day() == 1 {
    54  			goto WRAP
    55  		}
    56  	}
    57  	for !s.checkMeetHour(currentTime) {
    58  		currentTime = currentTime.Add(time.Hour)
    59  		currentTime = currentTime.Truncate(time.Hour)
    60  		if currentTime.Hour() == 0 {
    61  			goto WRAP
    62  		}
    63  	}
    64  	for !s.checkMeetMinute(currentTime) {
    65  		currentTime = currentTime.Add(1 * time.Minute)
    66  		currentTime = currentTime.Truncate(time.Minute)
    67  		if currentTime.Minute() == 0 {
    68  			goto WRAP
    69  		}
    70  	}
    71  
    72  	for !s.checkMeetSecond(lastMeetTime, currentTime) {
    73  		currentTime = currentTime.Add(1 * time.Second)
    74  		if currentTime.Second() == 0 {
    75  			goto WRAP
    76  		}
    77  	}
    78  	return currentTime.In(loc)
    79  }