func (j *Job) GetAt() string {
	return fmt.Sprintf("%d:%d", j.atTime/time.Hour, (j.atTime%time.Hour)/time.Minute)
}
GetAt returns the specific time of day the job will run at
s.Every(1).Day().At("10:30").GetAt() == "10:30"
package gocron
import (
	"errors"
	"fmt"
	"log"
	"reflect"
	"time"
)
var (
	ErrTimeFormat           = errors.New("time format error")
	ErrParamsNotAdapted     = errors.New("the number of params is not adapted")
	ErrNotAFunction         = errors.New("only functions can be schedule into the job queue")
	ErrPeriodNotSpecified   = errors.New("unspecified job period")
	ErrParameterCannotBeNil = errors.New("nil paramaters cannot be used with reflection")
)
type Job struct {
	interval uint64                    
	jobFunc  string                    
	unit     timeUnit                  
	atTime   time.Duration             
	err      error                     
	loc      *time.Location            
	lastRun  time.Time                 
	nextRun  time.Time                 
	startDay time.Weekday              
	funcs    map[string]interface{}    
	fparams  map[string][]interface{}  
	lock     bool                      
	tags     []string                  
}
func NewJob(interval uint64) *Job {
	return &Job{
		interval: interval,
		loc:      loc,
		lastRun:  time.Unix(0, 0),
		nextRun:  time.Unix(0, 0),
		startDay: time.Sunday,
		funcs:    make(map[string]interface{}),
		fparams:  make(map[string][]interface{}),
		tags:     []string{},
	}
}
func (j *Job) shouldRun() bool {
	return time.Now().Unix() >= j.nextRun.Unix()
}
func (j *Job) run() ([]reflect.Value, error) {
	if j.lock {
		if locker == nil {
			return nil, fmt.Errorf("trying to lock %s with nil locker", j.jobFunc)
		}
		key := getFunctionKey(j.jobFunc)
		locker.Lock(key)
		defer locker.Unlock(key)
	}
	result, err := callJobFuncWithParams(j.funcs[j.jobFunc], j.fparams[j.jobFunc])
	if err != nil {
		return nil, err
	}
	return result, nil
}
func (j *Job) Err() error {
	return j.err
}
func (j *Job) Do(jobFun interface{}, params ...interface{}) error {
	if j.err != nil {
		return j.err
	}
	typ := reflect.TypeOf(jobFun)
	if typ.Kind() != reflect.Func {
		return ErrNotAFunction
	}
	fname := getFunctionName(jobFun)
	j.funcs[fname] = jobFun
	j.fparams[fname] = params
	j.jobFunc = fname
	now := time.Now().In(j.loc)
	if !j.nextRun.After(now) {
		j.scheduleNextRun()
	}
	return nil
}
func (j *Job) DoSafely(jobFun interface{}, params ...interface{}) error {
	recoveryWrapperFunc := func() {
		defer func() {
			if r := recover(); r != nil {
				log.Printf("Internal panic occurred: %s", r)
			}
		}()
		_, _ = callJobFuncWithParams(jobFun, params)
	}
	return j.Do(recoveryWrapperFunc)
}
func (j *Job) At(t string) *Job {
	hour, min, sec, err := formatTime(t)
	if err != nil {
		j.err = ErrTimeFormat
		return j
	}
	j.atTime = time.Duration(hour)*time.Hour + time.Duration(min)*time.Minute + time.Duration(sec)*time.Second
	return j
}