func New(cronExpr, timeZone string, durationMin uint64) (cr *CronRange, err error) {
	if durationMin == 0 {
		err = errZeroDuration
		return
	}
	cronExpr, timeZone = strings.TrimSpace(cronExpr), strings.TrimSpace(timeZone)
	cronSpec := cronExpr
	if strings.ToLower(timeZone) == "local" {
		timeZone = ""
	} else if len(timeZone) > 0 {
		cronSpec = fmt.Sprintf("CRON_TZ=%s %s", timeZone, cronExpr)
	}
	var schedule cron.Schedule
	if schedule, err = cronParser.Parse(cronSpec); err != nil {
		return
	}
	cr = &CronRange{
		cronExpression: cronExpr,
		timeZone:       timeZone,
		duration:       time.Minute * time.Duration(durationMin),
		schedule:       schedule,
	}
	return
}
New returns a CronRange instance with given config, time zone can be empty for local time zone.

It returns an error if duration is not positive number, or cron expression is invalid, or time zone doesn't exist.
package cronrange
import (
	"errors"
	"fmt"
	"strings"
	"time"
	"github.com/robfig/cron/v3"
)
var (
	cronParseOption = cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow
	cronParser      = cron.NewParser(cronParseOption)
	errZeroDuration = errors.New("duration should be positive")
)
type CronRange struct {
	cronExpression string
	timeZone       string
	duration       time.Duration
	schedule       cron.Schedule
}
type TimeRange struct {
	Start time.Time
	End   time.Time
}