{"id":18023141,"url":"https://github.com/rustyconover/duckdb-cron-extension","last_synced_at":"2025-03-26T23:31:00.516Z","repository":{"id":241451176,"uuid":"806843247","full_name":"rustyconover/duckdb-cron-extension","owner":"rustyconover","description":"DuckDB Cron Expression Extension","archived":false,"fork":false,"pushed_at":"2024-06-23T15:01:47.000Z","size":19,"stargazers_count":24,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-19T20:59:34.652Z","etag":null,"topics":["duckdb","duckdb-extension"],"latest_commit_sha":null,"homepage":"","language":"Rust","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/rustyconover.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}},"created_at":"2024-05-28T02:41:03.000Z","updated_at":"2025-01-07T22:56:39.000Z","dependencies_parsed_at":"2024-05-28T12:30:20.896Z","dependency_job_id":"75714668-c188-463d-b574-b8ca14c08a7b","html_url":"https://github.com/rustyconover/duckdb-cron-extension","commit_stats":null,"previous_names":["rustyconover/duckdb-cron-extension"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustyconover%2Fduckdb-cron-extension","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustyconover%2Fduckdb-cron-extension/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustyconover%2Fduckdb-cron-extension/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustyconover%2Fduckdb-cron-extension/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rustyconover","download_url":"https://codeload.github.com/rustyconover/duckdb-cron-extension/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245753874,"owners_count":20666827,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["duckdb","duckdb-extension"],"created_at":"2024-10-30T07:07:33.474Z","updated_at":"2025-03-26T23:31:00.086Z","avatar_url":"https://github.com/rustyconover.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cron Expressions For DuckDB\n\n## Motivation\n\nCron jobs are a fundamental tool for scheduling tasks, often used for analyzing system behavior or verifying the completeness of data collections. For instance, a task might be scheduled to run daily at 10:30 AM, while another runs every Tuesday at 3 PM. These times might be in different time zones, such as UTC or New York time.\n\nTo efficiently compare these scheduled tasks against actual data, it’s beneficial to generate a list of expected timestamps directly within DuckDB. While DuckDB's `generate_series()` function can create a series of timestamps, it lacks the expressiveness needed for complex recurring patterns. I want to fill this with a new DuckDB extension that interprets cron expressions, leveraging the Rust crate [`croner`](https://crates.io/crates/croner).\n\nThis extension introduces a table-returning function `cron()`, which calculates upcoming or past times that satisfy a given cron expression.\n\n## Examples\n\n#### Basic Usage\n\nThe `cron()` function returns the next timestamp for a given cron expression:\n\n```sql\n-- This expression occurs every day at 5 AM.\nSELECT * FROM cron('0 5 * * *');\n┌─────────────────────┐\n│        cron         │\n│     timestamp_s     │\n├─────────────────────┤\n│ 2024-05-26 05:00:00 │\n└─────────────────────┘\n```\n\n#### Future Timestamps\n\nTo retrieve all future occurrences up to a specific date:\n\n```sql\nselect * from cron('0 5 * * *', until='2024-06-05');\n┌─────────────────────┐\n│        cron         │\n│     timestamp_s     │\n├─────────────────────┤\n│ 2024-05-26 05:00:00 │\n│ 2024-05-27 05:00:00 │\n│ 2024-05-28 05:00:00 │\n│ 2024-05-29 05:00:00 │\n│ 2024-05-30 05:00:00 │\n│ 2024-05-31 05:00:00 │\n│ 2024-06-01 05:00:00 │\n│ 2024-06-02 05:00:00 │\n│ 2024-06-03 05:00:00 │\n│ 2024-06-04 05:00:00 │\n├─────────────────────┤\n│       10 rows       │\n└─────────────────────┘\n````\n\n#### Past Timestamps\n\nTo retrieve occurrences within a past date range:\n\n```sql\nselect * from cron('0 5 * * *', until='2020-08-04', start='2020-08-01');\n┌─────────────────────┐\n│        cron         │\n│     timestamp_s     │\n├─────────────────────┤\n│ 2020-08-01 05:00:00 │\n│ 2020-08-02 05:00:00 │\n│ 2020-08-03 05:00:00 │\n└─────────────────────┘\n```\n\n#### Timezone Handling\n\nCron expressions can be evaluated in specific time zones:\n\n```sql\nselect * from\ncron(\n  '0 5 * * *',\n  until='2024-03-14 00:00:00',\n  start='2024-03-08 01:58:00',\n  timezone='America/New_York');\n\n┌─────────────────────┐\n│        cron         │\n│     timestamp_s     │\n├─────────────────────┤\n│ 2024-03-08 10:00:00 │\n│ 2024-03-09 10:00:00 │\n│ 2024-03-10 09:00:00 │\n│ 2024-03-11 09:00:00 │\n│ 2024-03-12 09:00:00 │\n│ 2024-03-13 09:00:00 │\n└─────────────────────┘\n```\n\nChanging DuckDB's timezone to match.\n\n```sql\nset timezone to 'America/New_York';\n\nselect * from\ncron(\n  '0 5 * * *',\n  until='2024-03-14 00:00:00',\n  start='2024-03-08 01:58:00',\n  timezone='America/New_York');\n┌─────────────────────┐\n│        cron         │\n│     timestamp_s     │\n├─────────────────────┤\n│ 2024-03-08 10:00:00 │\n│ 2024-03-09 10:00:00 │\n│ 2024-03-10 09:00:00 │\n│ 2024-03-11 09:00:00 │\n│ 2024-03-12 09:00:00 │\n│ 2024-03-13 09:00:00 │\n└─────────────────────┘\n```\n\n#### Second Level Precision\n\n```sql\nselect * from cron('*/3 0 5 * * *', until='2024-05-30') limit 5;\n┌─────────────────────┐\n│        cron         │\n│     timestamp_s     │\n├─────────────────────┤\n│ 2024-05-26 05:00:00 │\n│ 2024-05-26 05:00:03 │\n│ 2024-05-26 05:00:06 │\n│ 2024-05-26 05:00:09 │\n│ 2024-05-26 05:00:12 │\n└─────────────────────┘\n```\n\n#### More complicated cron expressions\n\nUsing cron expressions for specific days of the week:\n\n```sql\nselect * from cron('0 5 * * Mon', until='2024-09-30') limit 5;\n┌─────────────────────┐\n│        cron         │\n│     timestamp_s     │\n├─────────────────────┤\n│ 2024-05-27 05:00:00 │\n│ 2024-06-03 05:00:00 │\n│ 2024-06-10 05:00:00 │\n│ 2024-06-17 05:00:00 │\n│ 2024-06-24 05:00:00 │\n└─────────────────────┘\n```\n\n## Function Documentation\n\n### `cron(VARCHAR, start=TIMESTAMP, until=TIMESTAMP, timezone=VARCHAR)`\n\n#### Parameters:\n\n* `pattern` (VARCHAR): The cron pattern to evaluate.\n\n#### Optional Named Parameters:\n\n* `start` (TIMESTAMP): The timestamp at which to begin evaluating the cron pattern.\n* `until` (TIMESTAMP): The timestamp at which to stop evaluating the cron pattern (exclusive).\n* `timezone` (VARCHAR): The time zone in which to evaluate the cron pattern (e.g., 'America/New_York', 'America/Chicago').\n\n#### Returning\n\nA single column `cron`, which contains timestamps when the cron pattern is satisfied.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frustyconover%2Fduckdb-cron-extension","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frustyconover%2Fduckdb-cron-extension","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frustyconover%2Fduckdb-cron-extension/lists"}