{"id":36454517,"url":"https://github.com/goforj/scheduler","last_synced_at":"2026-01-11T23:01:37.764Z","repository":{"id":329101977,"uuid":"1118098816","full_name":"goforj/scheduler","owner":"goforj","description":"Laravel-inspired job scheduler for Go with a fluent API, built on gocron.","archived":false,"fork":false,"pushed_at":"2025-12-18T22:26:35.000Z","size":1706,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-20T22:51:19.637Z","etag":null,"topics":["background-jobs","builder-pattern","cron","developer-tools","distributed-locking","fluent-api","go","gocron","goforj","golang","job-scheduler","laravel-inspired","redis","scheduler","task-scheduling"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/goforj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-17T09:04:25.000Z","updated_at":"2025-12-18T22:26:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/goforj/scheduler","commit_stats":null,"previous_names":["goforj/scheduler"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/goforj/scheduler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goforj%2Fscheduler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goforj%2Fscheduler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goforj%2Fscheduler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goforj%2Fscheduler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/goforj","download_url":"https://codeload.github.com/goforj/scheduler/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goforj%2Fscheduler/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28326166,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T22:11:01.104Z","status":"ssl_error","status_checked_at":"2026-01-11T22:10:58.990Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["background-jobs","builder-pattern","cron","developer-tools","distributed-locking","fluent-api","go","gocron","goforj","golang","job-scheduler","laravel-inspired","redis","scheduler","task-scheduling"],"created_at":"2026-01-11T23:01:37.660Z","updated_at":"2026-01-11T23:01:37.747Z","avatar_url":"https://github.com/goforj.png","language":"Go","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./docs/images/logo.png?v=2\" width=\"400\" alt=\"scheduler logo\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    A fluent, Laravel-inspired scheduler for Go that wraps gocron with expressive APIs for defining, filtering, and controlling scheduled jobs.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://pkg.go.dev/github.com/goforj/scheduler\"\u003e\u003cimg src=\"https://pkg.go.dev/badge/github.com/goforj/scheduler.svg\" alt=\"Go Reference\"\u003e\u003c/a\u003e\n    \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/goforj/scheduler/actions\"\u003e\u003cimg src=\"https://github.com/goforj/scheduler/actions/workflows/test.yml/badge.svg\" alt=\"Go Test\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://golang.org\"\u003e\u003cimg src=\"https://img.shields.io/badge/go-1.18+-blue?logo=go\" alt=\"Go version\"\u003e\u003c/a\u003e\n    \u003cimg src=\"https://img.shields.io/github/v/tag/goforj/scheduler?label=version\u0026sort=semver\" alt=\"Latest tag\"\u003e\n    \u003ca href=\"https://codecov.io/gh/goforj/scheduler\" \u003e\u003cimg src=\"https://codecov.io/github/goforj/scheduler/graph/badge.svg?token=9KT46ZORP3\"/\u003e\u003c/a\u003e\n\u003c!-- test-count:embed:start --\u003e\n    \u003cimg src=\"https://img.shields.io/badge/tests-191-brightgreen\" alt=\"Tests\"\u003e\n\u003c!-- test-count:embed:end --\u003e\n    \u003ca href=\"https://goreportcard.com/report/github.com/goforj/scheduler\"\u003e\u003cimg src=\"https://goreportcard.com/badge/github.com/goforj/scheduler\" alt=\"Go Report Card\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Features\n\n- Fluent, chainable API for intervals, cron strings, and calendar helpers (daily/weekly/monthly).\n- Overlap protection with optional distributed locking plus per-job tags and metadata.\n- Filters (weekdays/weekends/time windows) and hooks (before/after/success/failure) keep jobs predictable.\n- Command execution helper for running CLI tasks with background mode and env-aware tagging.\n- Auto-generated, compile-tested examples ensure docs and behavior stay in sync.\n\n## Why scheduler?\n\nGo has excellent low-level scheduling libraries, but defining real-world schedules often turns into a maze of cron strings, conditionals, and glue code.\n\n`scheduler` provides a Laravel-style fluent API on top of gocron that lets you describe **when**, **how**, and **under what conditions** a job should run - without hiding what’s actually happening.\n\nEverything remains explicit, testable, and inspectable, while staying pleasant to read and maintain.\n\n## Example\n\n```go\nscheduler.NewJobBuilder(s).\n    Name(\"reports:generate\").\n    Weekdays().\n    Between(\"09:00\", \"17:00\").\n    WithoutOverlapping().\n    DailyAt(\"10:30\").\n    Do(func() {\n    generateReports()\n})\n```\n\n## List jobs as an ASCII table\n\n```go\npackage main\n\nimport (\n\t\"github.com/go-co-op/gocron/v2\"\n\t\"github.com/goforj/scheduler\"\n)\n\nfunc main() {\n\ts, _ := gocron.NewScheduler()\n\ts.Start()\n\tdefer s.Shutdown()\n\n\tscheduler.NewJobBuilder(s).\n\t\tEveryMinute().\n\t\tName(\"cleanup\").\n\t\tDo(func() {})\n\n\tscheduler.NewJobBuilder(s).PrintJobsList()\n}\n```\n\nExample output:\n\n```\n+--------------------------------------------------------------------------------------+\n| Scheduler Jobs › (3)\n+----------------+----------+----------------+---------+--------+----------------------+\n| Name           | Type     | Schedule       | Handler | Next   | Tags                 |\n+----------------+----------+----------------+---------+--------+----------------------+\n| hello:world    | command  | cron 0 0 * * 0 | -       | in 3d  | env=dev, args=\"w\"    |\n| hello:world    | command  | every 1h       | -       | in 1h  | env=dev, args=\"hour\" |\n| cleanup        | function | every 1m       | cleanup | in 1m  | env=dev              |\n+----------------+----------+----------------+---------+--------+----------------------+\n```\n\n## Runnable examples\n\nEvery function has a corresponding runnable example under [`./examples`](./examples).\n\nThese examples are **generated directly from the documentation blocks** of each function, ensuring the docs and code never drift. These are the same examples you see here in the README and GoDoc.\n\nAn automated test executes **every example** to verify it builds and runs successfully.\n\nThis guarantees all examples are valid, up-to-date, and remain functional as the API evolves.\n\n\u003c!-- api:embed:start --\u003e\n\n## API Index\n\n| Group | Functions |\n|------:|-----------|\n| **Adapters** | [Lock](#lock) [Run](#run) [Unlock](#unlock) |\n| **Commands** | [Command](#command) |\n| **Concurrency** | [WithoutOverlapping](#withoutoverlapping) [WithoutOverlappingWithLocker](#withoutoverlappingwithlocker) |\n| **Configuration** | [Timezone](#timezone) [WithCommandRunner](#withcommandrunner) [WithNowFunc](#withnowfunc) |\n| **Construction** | [NewJobBuilder](#newjobbuilder) |\n| **Diagnostics** | [CronExpr](#cronexpr) [Error](#error) [Job](#job) [PrintJobsList](#printjobslist) |\n| **Execution** | [RunInBackground](#runinbackground) |\n| **Filters** | [Between](#between) [Days](#days) [Environments](#environments) [Fridays](#fridays) [Mondays](#mondays) [Saturdays](#saturdays) [Skip](#skip) [Sundays](#sundays) [Thursdays](#thursdays) [Tuesdays](#tuesdays) [UnlessBetween](#unlessbetween) [Wednesdays](#wednesdays) [Weekdays](#weekdays) [Weekends](#weekends) [When](#when) |\n| **Hooks** | [After](#after) [Before](#before) [OnFailure](#onfailure) [OnSuccess](#onsuccess) |\n| **Locking** | [NewRedisLocker](#newredislocker) |\n| **Metadata** | [JobMetadata](#jobmetadata) [Name](#name) |\n| **Scheduling** | [Cron](#cron) [Daily](#daily) [DailyAt](#dailyat) [DaysOfMonth](#daysofmonth) [Do](#do) [Every](#every) [EveryFifteenMinutes](#everyfifteenminutes) [EveryFifteenSeconds](#everyfifteenseconds) [EveryFiveMinutes](#everyfiveminutes) [EveryFiveSeconds](#everyfiveseconds) [EveryFourHours](#everyfourhours) [EveryFourMinutes](#everyfourminutes) [EveryMinute](#everyminute) [EveryOddHour](#everyoddhour) [EverySecond](#everysecond) [EverySixHours](#everysixhours) [EveryTenMinutes](#everytenminutes) [EveryTenSeconds](#everytenseconds) [EveryThirtyMinutes](#everythirtyminutes) [EveryThirtySeconds](#everythirtyseconds) [EveryThreeHours](#everythreehours) [EveryThreeMinutes](#everythreeminutes) [EveryTwentySeconds](#everytwentyseconds) [EveryTwoHours](#everytwohours) [EveryTwoMinutes](#everytwominutes) [EveryTwoSeconds](#everytwoseconds) [Hourly](#hourly) [HourlyAt](#hourlyat) [Hours](#hours) [LastDayOfMonth](#lastdayofmonth) [Minutes](#minutes) [Monthly](#monthly) [MonthlyOn](#monthlyon) [Quarterly](#quarterly) [QuarterlyOn](#quarterlyon) [Seconds](#seconds) [TwiceDaily](#twicedaily) [TwiceDailyAt](#twicedailyat) [TwiceMonthly](#twicemonthly) [Weekly](#weekly) [WeeklyOn](#weeklyon) [Yearly](#yearly) [YearlyOn](#yearlyon) |\n| **State management** | [RetainState](#retainstate) |\n\n\n## Adapters\n\n### \u003ca id=\"lock\"\u003e\u003c/a\u003eLock\n\nLock invokes the underlying function.\n\n```go\nclient := redis.NewClient(\u0026redis.Options{})\nlocker := scheduler.NewRedisLocker(client, time.Minute)\nlock, _ := locker.Lock(context.Background(), \"job\")\n_ = lock.Unlock(context.Background())\n```\n\n### \u003ca id=\"run\"\u003e\u003c/a\u003eRun\n\nRun executes the underlying function.\n\n```go\nrunner := scheduler.CommandRunnerFunc(func(ctx context.Context, exe string, args []string) error {\n\treturn nil\n})\n_ = runner.Run(context.Background(), \"echo\", []string{\"hi\"})\n```\n\n### \u003ca id=\"unlock\"\u003e\u003c/a\u003eUnlock\n\nUnlock invokes the underlying function.\n\n## Commands\n\n### \u003ca id=\"command\"\u003e\u003c/a\u003eCommand\n\nCommand executes the current binary with the given subcommand and variadic args.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).\n\tCron(\"0 0 * * *\").\n\tCommand(\"jobs:purge\", \"--force\")\n```\n\n## Concurrency\n\n### \u003ca id=\"withoutoverlapping\"\u003e\u003c/a\u003eWithoutOverlapping\n\nWithoutOverlapping ensures the job does not run concurrently.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).\n\tWithoutOverlapping().\n\tEveryFiveSeconds().\n\tDo(func() { time.Sleep(7 * time.Second) })\n```\n\n### \u003ca id=\"withoutoverlappingwithlocker\"\u003e\u003c/a\u003eWithoutOverlappingWithLocker\n\nWithoutOverlappingWithLocker ensures the job does not run concurrently across distributed systems using the provided locker.\n\n```go\nlocker := scheduler.LockerFunc(func(ctx context.Context, key string) (gocron.Lock, error) {\n\treturn scheduler.LockFunc(func(context.Context) error { return nil }), nil\n})\n\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).\n\tWithoutOverlappingWithLocker(locker).\n\tEveryMinute().\n\tDo(func() {})\n```\n\n## Configuration\n\n### \u003ca id=\"timezone\"\u003e\u003c/a\u003eTimezone\n\nTimezone sets a timezone string for the job (not currently applied to gocron Scheduler).\n\n```go\nscheduler.NewJobBuilder(nil).\n\tTimezone(\"America/New_York\").\n\tDaily()\n```\n\n### \u003ca id=\"withcommandrunner\"\u003e\u003c/a\u003eWithCommandRunner\n\nWithCommandRunner overrides command execution (default: exec.CommandContext).\n\n```go\nrunner := scheduler.CommandRunnerFunc(func(_ context.Context, exe string, args []string) error {\n\tfmt.Println(exe, args)\n\treturn nil\n})\n\nbuilder := scheduler.NewJobBuilder(nil).\n\tWithCommandRunner(runner)\nfmt.Printf(\"%T\\n\", builder)\n```\n\n### \u003ca id=\"withnowfunc\"\u003e\u003c/a\u003eWithNowFunc\n\nWithNowFunc overrides current time (default: time.Now). Useful for tests.\n\n```go\nfixed := func() time.Time { return time.Unix(0, 0) }\nscheduler.NewJobBuilder(nil).WithNowFunc(fixed)\n```\n\n## Construction\n\n### \u003ca id=\"newjobbuilder\"\u003e\u003c/a\u003eNewJobBuilder\n\nNewJobBuilder creates a new JobBuilder with the provided scheduler.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\nscheduler.NewJobBuilder(s).EverySecond().Do(func() {})\n```\n\n## Diagnostics\n\n### \u003ca id=\"cronexpr\"\u003e\u003c/a\u003eCronExpr\n\nCronExpr returns the cron expression string configured for this job.\n\n```go\nbuilder := scheduler.NewJobBuilder(nil).Cron(\"0 9 * * *\")\nfmt.Println(builder.CronExpr())\n```\n\n### \u003ca id=\"error\"\u003e\u003c/a\u003eError\n\nError returns the error if any occurred during job scheduling.\n\n```go\nbuilder := scheduler.NewJobBuilder(nil).DailyAt(\"bad\")\nfmt.Println(builder.Error())\n```\n\n### \u003ca id=\"job\"\u003e\u003c/a\u003eJob\n\nJob returns the last scheduled gocron.Job instance, if available.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nb := scheduler.NewJobBuilder(s).EverySecond().Do(func() {})\nfmt.Println(b.Job() != nil)\n```\n\n### \u003ca id=\"printjobslist\"\u003e\u003c/a\u003ePrintJobsList\n\nPrintJobsList renders and prints the scheduler job table to stdout.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).\n\tEverySecond().\n\tName(\"heartbeat\").\n\tDo(func() {})\n\nscheduler.NewJobBuilder(s).PrintJobsList()\n```\n\n## Execution\n\n### \u003ca id=\"runinbackground\"\u003e\u003c/a\u003eRunInBackground\n\nRunInBackground runs command/exec tasks in a goroutine.\n\n```go\nscheduler.NewJobBuilder(nil).\n\tRunInBackground().\n\tCommand(\"noop\")\n```\n\n## Filters\n\n### \u003ca id=\"between\"\u003e\u003c/a\u003eBetween\n\nBetween limits the job to run between the provided HH:MM times (inclusive).\n\n```go\nscheduler.NewJobBuilder(nil).\n\tBetween(\"09:00\", \"17:00\").\n\tEveryMinute()\n```\n\n### \u003ca id=\"days\"\u003e\u003c/a\u003eDays\n\nDays limits the job to a specific set of weekdays.\n\n```go\nscheduler.NewJobBuilder(nil).\n\tDays(time.Monday, time.Wednesday, time.Friday).\n\tDailyAt(\"07:00\")\n```\n\n### \u003ca id=\"environments\"\u003e\u003c/a\u003eEnvironments\n\nEnvironments restricts job registration to specific environment names (e.g. \"production\", \"staging\").\n\n```go\nscheduler.NewJobBuilder(nil).Environments(\"production\").Daily()\n```\n\n### \u003ca id=\"fridays\"\u003e\u003c/a\u003eFridays\n\nFridays limits the job to Fridays.\n\n```go\nscheduler.NewJobBuilder(nil).Fridays().DailyAt(\"09:00\")\n```\n\n### \u003ca id=\"mondays\"\u003e\u003c/a\u003eMondays\n\nMondays limits the job to Mondays.\n\n```go\nscheduler.NewJobBuilder(nil).Mondays().DailyAt(\"09:00\")\n```\n\n### \u003ca id=\"saturdays\"\u003e\u003c/a\u003eSaturdays\n\nSaturdays limits the job to Saturdays.\n\n```go\nscheduler.NewJobBuilder(nil).Saturdays().DailyAt(\"09:00\")\n```\n\n### \u003ca id=\"skip\"\u003e\u003c/a\u003eSkip\n\nSkip prevents scheduling the job if the provided condition returns true.\n\n```go\nenabled := false\nscheduler.NewJobBuilder(nil).\n\tSkip(func() bool { return !enabled }).\n\tDaily()\n```\n\n### \u003ca id=\"sundays\"\u003e\u003c/a\u003eSundays\n\nSundays limits the job to Sundays.\n\n```go\nscheduler.NewJobBuilder(nil).Sundays().DailyAt(\"09:00\")\n```\n\n### \u003ca id=\"thursdays\"\u003e\u003c/a\u003eThursdays\n\nThursdays limits the job to Thursdays.\n\n```go\nscheduler.NewJobBuilder(nil).Thursdays().DailyAt(\"09:00\")\n```\n\n### \u003ca id=\"tuesdays\"\u003e\u003c/a\u003eTuesdays\n\nTuesdays limits the job to Tuesdays.\n\n```go\nscheduler.NewJobBuilder(nil).Tuesdays().DailyAt(\"09:00\")\n```\n\n### \u003ca id=\"unlessbetween\"\u003e\u003c/a\u003eUnlessBetween\n\nUnlessBetween prevents the job from running between the provided HH:MM times.\n\n```go\nscheduler.NewJobBuilder(nil).\n\tUnlessBetween(\"22:00\", \"06:00\").\n\tEveryMinute()\n```\n\n### \u003ca id=\"wednesdays\"\u003e\u003c/a\u003eWednesdays\n\nWednesdays limits the job to Wednesdays.\n\n```go\nscheduler.NewJobBuilder(nil).Wednesdays().DailyAt(\"09:00\")\n```\n\n### \u003ca id=\"weekdays\"\u003e\u003c/a\u003eWeekdays\n\nWeekdays limits the job to run only on weekdays (Mon-Fri).\n\n```go\nscheduler.NewJobBuilder(nil).Weekdays().DailyAt(\"09:00\")\n```\n\n### \u003ca id=\"weekends\"\u003e\u003c/a\u003eWeekends\n\nWeekends limits the job to run only on weekends (Sat-Sun).\n\n```go\nscheduler.NewJobBuilder(nil).Weekends().DailyAt(\"10:00\")\n```\n\n### \u003ca id=\"when\"\u003e\u003c/a\u003eWhen\n\nWhen only schedules the job if the provided condition returns true.\n\n```go\nflag := true\nscheduler.NewJobBuilder(nil).\n\tWhen(func() bool { return flag }).\n\tDaily()\n```\n\n## Hooks\n\n### \u003ca id=\"after\"\u003e\u003c/a\u003eAfter\n\nAfter sets a hook to run after task execution.\n\n```go\nscheduler.NewJobBuilder(nil).\n\tAfter(func() { println(\"after\") }).\n\tDaily()\n```\n\n### \u003ca id=\"before\"\u003e\u003c/a\u003eBefore\n\nBefore sets a hook to run before task execution.\n\n```go\nscheduler.NewJobBuilder(nil).\n\tBefore(func() { println(\"before\") }).\n\tDaily()\n```\n\n### \u003ca id=\"onfailure\"\u003e\u003c/a\u003eOnFailure\n\nOnFailure sets a hook to run after failed task execution.\n\n```go\nscheduler.NewJobBuilder(nil).\n\tOnFailure(func() { println(\"failure\") }).\n\tDaily()\n```\n\n### \u003ca id=\"onsuccess\"\u003e\u003c/a\u003eOnSuccess\n\nOnSuccess sets a hook to run after successful task execution.\n\n```go\nscheduler.NewJobBuilder(nil).\n\tOnSuccess(func() { println(\"success\") }).\n\tDaily()\n```\n\n## Locking\n\n### \u003ca id=\"newredislocker\"\u003e\u003c/a\u003eNewRedisLocker\n\nNewRedisLocker creates a RedisLocker with a client and TTL.\n\n```go\nclient := redis.NewClient(\u0026redis.Options{}) // replace with your client\nlocker := scheduler.NewRedisLocker(client, time.Minute)\n_, _ = locker.Lock(context.Background(), \"job\")\n```\n\n## Metadata\n\n### \u003ca id=\"jobmetadata\"\u003e\u003c/a\u003eJobMetadata\n\nJobMetadata returns a copy of the tracked job metadata keyed by job ID.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nb := scheduler.NewJobBuilder(s).EverySecond().Do(func() {})\nfor id, meta := range b.JobMetadata() {\n\t_ = id\n\t_ = meta.Name\n}\n```\n\n### \u003ca id=\"name\"\u003e\u003c/a\u003eName\n\nName sets an explicit job name.\n\n```go\nscheduler.NewJobBuilder(nil).\n\tName(\"cache:refresh\").\n\tHourlyAt(15)\n```\n\n## Scheduling\n\n### \u003ca id=\"cron\"\u003e\u003c/a\u003eCron\n\nCron sets the cron expression for the job.\n\n```go\nbuilder := scheduler.NewJobBuilder(nil).Cron(\"15 3 * * *\")\nfmt.Println(builder.CronExpr())\n```\n\n### \u003ca id=\"daily\"\u003e\u003c/a\u003eDaily\n\nDaily schedules the job to run once per day at midnight.\n\n```go\nscheduler.NewJobBuilder(nil).Daily()\n```\n\n### \u003ca id=\"dailyat\"\u003e\u003c/a\u003eDailyAt\n\nDailyAt schedules the job to run daily at a specific time (e.g., \"13:00\").\n\n```go\nscheduler.NewJobBuilder(nil).DailyAt(\"12:30\")\n```\n\n### \u003ca id=\"daysofmonth\"\u003e\u003c/a\u003eDaysOfMonth\n\nDaysOfMonth schedules the job to run on specific days of the month at a given time.\n\n```go\nscheduler.NewJobBuilder(nil).DaysOfMonth([]int{5, 20}, \"07:15\")\n```\n\n### \u003ca id=\"do\"\u003e\u003c/a\u003eDo\n\nDo schedules the job with the provided task function.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).\nName(\"cleanup\").\nCron(\"0 0 * * *\").\nDo(func() {})\n```\n\n### \u003ca id=\"every\"\u003e\u003c/a\u003eEvery\n\nEvery schedules a job to run every X seconds, minutes, or hours.\n\n```go\nscheduler.NewJobBuilder(nil).\n\tEvery(10).\n\tMinutes()\n```\n\n### \u003ca id=\"everyfifteenminutes\"\u003e\u003c/a\u003eEveryFifteenMinutes\n\nEveryFifteenMinutes schedules the job to run every 15 minutes.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).EveryFifteenMinutes().Do(func() {})\n```\n\n### \u003ca id=\"everyfifteenseconds\"\u003e\u003c/a\u003eEveryFifteenSeconds\n\nEveryFifteenSeconds schedules the job to run every 15 seconds.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).EveryFifteenSeconds().Do(func() {})\n```\n\n### \u003ca id=\"everyfiveminutes\"\u003e\u003c/a\u003eEveryFiveMinutes\n\nEveryFiveMinutes schedules the job to run every 5 minutes.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).EveryFiveMinutes().Do(func() {})\n```\n\n### \u003ca id=\"everyfiveseconds\"\u003e\u003c/a\u003eEveryFiveSeconds\n\nEveryFiveSeconds schedules the job to run every 5 seconds.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).EveryFiveSeconds().Do(func() {})\n```\n\n### \u003ca id=\"everyfourhours\"\u003e\u003c/a\u003eEveryFourHours\n\nEveryFourHours schedules the job to run every four hours at the specified minute.\n\n```go\nscheduler.NewJobBuilder(nil).EveryFourHours(25)\n```\n\n### \u003ca id=\"everyfourminutes\"\u003e\u003c/a\u003eEveryFourMinutes\n\nEveryFourMinutes schedules the job to run every 4 minutes.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).EveryFourMinutes().Do(func() {})\n```\n\n### \u003ca id=\"everyminute\"\u003e\u003c/a\u003eEveryMinute\n\nEveryMinute schedules the job to run every 1 minute.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).EveryMinute().Do(func() {})\n```\n\n### \u003ca id=\"everyoddhour\"\u003e\u003c/a\u003eEveryOddHour\n\nEveryOddHour schedules the job to run every odd-numbered hour at the specified minute.\n\n```go\nscheduler.NewJobBuilder(nil).EveryOddHour(10)\n```\n\n### \u003ca id=\"everysecond\"\u003e\u003c/a\u003eEverySecond\n\nEverySecond schedules the job to run every 1 second.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).EverySecond().Do(func() {})\n```\n\n### \u003ca id=\"everysixhours\"\u003e\u003c/a\u003eEverySixHours\n\nEverySixHours schedules the job to run every six hours at the specified minute.\n\n```go\nscheduler.NewJobBuilder(nil).EverySixHours(30)\n```\n\n### \u003ca id=\"everytenminutes\"\u003e\u003c/a\u003eEveryTenMinutes\n\nEveryTenMinutes schedules the job to run every 10 minutes.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).EveryTenMinutes().Do(func() {})\n```\n\n### \u003ca id=\"everytenseconds\"\u003e\u003c/a\u003eEveryTenSeconds\n\nEveryTenSeconds schedules the job to run every 10 seconds.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).EveryTenSeconds().Do(func() {})\n```\n\n### \u003ca id=\"everythirtyminutes\"\u003e\u003c/a\u003eEveryThirtyMinutes\n\nEveryThirtyMinutes schedules the job to run every 30 minutes.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).EveryThirtyMinutes().Do(func() {})\n```\n\n### \u003ca id=\"everythirtyseconds\"\u003e\u003c/a\u003eEveryThirtySeconds\n\nEveryThirtySeconds schedules the job to run every 30 seconds.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).EveryThirtySeconds().Do(func() {})\n```\n\n### \u003ca id=\"everythreehours\"\u003e\u003c/a\u003eEveryThreeHours\n\nEveryThreeHours schedules the job to run every three hours at the specified minute.\n\n```go\nscheduler.NewJobBuilder(nil).EveryThreeHours(20)\n```\n\n### \u003ca id=\"everythreeminutes\"\u003e\u003c/a\u003eEveryThreeMinutes\n\nEveryThreeMinutes schedules the job to run every 3 minutes.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).EveryThreeMinutes().Do(func() {})\n```\n\n### \u003ca id=\"everytwentyseconds\"\u003e\u003c/a\u003eEveryTwentySeconds\n\nEveryTwentySeconds schedules the job to run every 20 seconds.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).EveryTwentySeconds().Do(func() {})\n```\n\n### \u003ca id=\"everytwohours\"\u003e\u003c/a\u003eEveryTwoHours\n\nEveryTwoHours schedules the job to run every two hours at the specified minute.\n\n```go\nscheduler.NewJobBuilder(nil).EveryTwoHours(15)\n```\n\n### \u003ca id=\"everytwominutes\"\u003e\u003c/a\u003eEveryTwoMinutes\n\nEveryTwoMinutes schedules the job to run every 2 minutes.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).EveryTwoMinutes().Do(func() {})\n```\n\n### \u003ca id=\"everytwoseconds\"\u003e\u003c/a\u003eEveryTwoSeconds\n\nEveryTwoSeconds schedules the job to run every 2 seconds.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).EveryTwoSeconds().Do(func() {})\n```\n\n### \u003ca id=\"hourly\"\u003e\u003c/a\u003eHourly\n\nHourly schedules the job to run every hour.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).Hourly().Do(func() {})\n```\n\n### \u003ca id=\"hourlyat\"\u003e\u003c/a\u003eHourlyAt\n\nHourlyAt schedules the job to run every hour at the specified minute.\n\n```go\nscheduler.NewJobBuilder(nil).HourlyAt(5)\n```\n\n### \u003ca id=\"hours\"\u003e\u003c/a\u003eHours\n\nHours schedules the job to run every X hours.\n\n```go\nscheduler.NewJobBuilder(nil).Every(6).Hours()\n```\n\n### \u003ca id=\"lastdayofmonth\"\u003e\u003c/a\u003eLastDayOfMonth\n\nLastDayOfMonth schedules the job to run on the last day of each month at a specific time.\n\n```go\nscheduler.NewJobBuilder(nil).LastDayOfMonth(\"23:30\")\n```\n\n### \u003ca id=\"minutes\"\u003e\u003c/a\u003eMinutes\n\nMinutes schedules the job to run every X minutes.\n\n```go\nscheduler.NewJobBuilder(nil).Every(15).Minutes()\n```\n\n### \u003ca id=\"monthly\"\u003e\u003c/a\u003eMonthly\n\nMonthly schedules the job to run on the first day of each month at midnight.\n\n```go\nscheduler.NewJobBuilder(nil).Monthly()\n```\n\n### \u003ca id=\"monthlyon\"\u003e\u003c/a\u003eMonthlyOn\n\nMonthlyOn schedules the job to run on a specific day of the month at a given time.\n\n```go\nscheduler.NewJobBuilder(nil).MonthlyOn(15, \"09:30\")\n```\n\n### \u003ca id=\"quarterly\"\u003e\u003c/a\u003eQuarterly\n\nQuarterly schedules the job to run on the first day of each quarter at midnight.\n\n```go\nscheduler.NewJobBuilder(nil).Quarterly()\n```\n\n### \u003ca id=\"quarterlyon\"\u003e\u003c/a\u003eQuarterlyOn\n\nQuarterlyOn schedules the job to run on a specific day of each quarter at a given time.\n\n```go\nscheduler.NewJobBuilder(nil).QuarterlyOn(3, \"12:00\")\n```\n\n### \u003ca id=\"seconds\"\u003e\u003c/a\u003eSeconds\n\nSeconds schedules the job to run every X seconds.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nscheduler.NewJobBuilder(s).\n\tEvery(3).\n\tSeconds().\n\tDo(func() {})\n```\n\n### \u003ca id=\"twicedaily\"\u003e\u003c/a\u003eTwiceDaily\n\nTwiceDaily schedules the job to run daily at two specified hours (e.g., 1 and 13).\n\n```go\nscheduler.NewJobBuilder(nil).TwiceDaily(1, 13)\n```\n\n### \u003ca id=\"twicedailyat\"\u003e\u003c/a\u003eTwiceDailyAt\n\nTwiceDailyAt schedules the job to run daily at two specified times (e.g., 1:15 and 13:15).\n\n```go\nscheduler.NewJobBuilder(nil).TwiceDailyAt(1, 13, 15)\n```\n\n### \u003ca id=\"twicemonthly\"\u003e\u003c/a\u003eTwiceMonthly\n\nTwiceMonthly schedules the job to run on two specific days of the month at the given time.\n\n```go\nscheduler.NewJobBuilder(nil).TwiceMonthly(1, 15, \"10:00\")\n```\n\n### \u003ca id=\"weekly\"\u003e\u003c/a\u003eWeekly\n\nWeekly schedules the job to run once per week on Sunday at midnight.\n\n```go\nscheduler.NewJobBuilder(nil).Weekly()\n```\n\n### \u003ca id=\"weeklyon\"\u003e\u003c/a\u003eWeeklyOn\n\nWeeklyOn schedules the job to run weekly on a specific day of the week and time.\nDay uses 0 = Sunday through 6 = Saturday.\n\n```go\nscheduler.NewJobBuilder(nil).WeeklyOn(1, \"8:00\")\n```\n\n### \u003ca id=\"yearly\"\u003e\u003c/a\u003eYearly\n\nYearly schedules the job to run on January 1st every year at midnight.\n\n```go\nscheduler.NewJobBuilder(nil).Yearly()\n```\n\n### \u003ca id=\"yearlyon\"\u003e\u003c/a\u003eYearlyOn\n\nYearlyOn schedules the job to run every year on a specific month, day, and time.\n\n```go\nscheduler.NewJobBuilder(nil).YearlyOn(12, 25, \"06:45\")\n```\n\n## State management\n\n### \u003ca id=\"retainstate\"\u003e\u003c/a\u003eRetainState\n\nRetainState allows the job to retain its state after execution.\n\n```go\ns, _ := gocron.NewScheduler()\ns.Start()\ndefer s.Shutdown()\n\nbuilder := scheduler.NewJobBuilder(s).EverySecond().RetainState()\nbuilder.Do(func() {})\nbuilder.Do(func() {})\n```\n\u003c!-- api:embed:end --\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoforj%2Fscheduler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoforj%2Fscheduler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoforj%2Fscheduler/lists"}