{"id":26497797,"url":"https://github.com/paganini2008/cronsmith","last_synced_at":"2026-05-20T09:06:10.682Z","repository":{"id":279609967,"uuid":"937932077","full_name":"paganini2008/cronsmith","owner":"paganini2008","description":"Cronsmith is a powerful Java utility library for handling cron expressions in an object-oriented way. It provides a highly flexible and user-friendly API for generating, parsing, and scheduling cron-based tasks.","archived":false,"fork":false,"pushed_at":"2025-03-14T02:28:11.000Z","size":94,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-14T03:27:11.355Z","etag":null,"topics":["cron-expression","crontab","quartz","spring","task-scheduler"],"latest_commit_sha":null,"homepage":"https://github.com/paganini2008/cronsmith","language":"Java","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/paganini2008.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":"2025-02-24T06:32:05.000Z","updated_at":"2025-03-14T02:28:14.000Z","dependencies_parsed_at":"2025-03-14T03:36:34.669Z","dependency_job_id":null,"html_url":"https://github.com/paganini2008/cronsmith","commit_stats":null,"previous_names":["paganini2008/cronsmith"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paganini2008%2Fcronsmith","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paganini2008%2Fcronsmith/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paganini2008%2Fcronsmith/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paganini2008%2Fcronsmith/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paganini2008","download_url":"https://codeload.github.com/paganini2008/cronsmith/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244623927,"owners_count":20483244,"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":["cron-expression","crontab","quartz","spring","task-scheduler"],"created_at":"2025-03-20T13:59:37.959Z","updated_at":"2026-05-20T09:06:10.675Z","avatar_url":"https://github.com/paganini2008.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cronsmith - The Ultimate Cron Expression Generator \u0026 Parser\n\n[![Java](https://img.shields.io/badge/Java-Compatible-orange.svg)](https://www.java.com)\n[![Cron](https://img.shields.io/badge/Cron-Supported-blue.svg)](https://en.wikipedia.org/wiki/Cron)\n[![Spring Quartz](https://img.shields.io/badge/Spring%20Quartz-Compatible-brightgreen.svg)](https://spring.io/projects/spring-quartz)\n\n### Are cron expressions sometimes difficult to understand? Let's try a different approach to creating scheduled tasks.\n\n**Cronsmith** is a powerful and versatile Java utility library designed for handling complex cron expressions in an intuitive, object-oriented manner. It offers a highly flexible and comprehensive API for generating, parsing, and scheduling cron-based tasks with ease.\n\nBuilt for seamless integration, **Cronsmith** provides full support for both Spring and Quartz cron expressions, ensuring compatibility with widely used scheduling frameworks. Moreover, it extends traditional cron syntax by introducing advanced patterns — such as multiple numbers combined with 'L' (last) and 'W' (weekday)—which were previously unsupported, offering greater precision and flexibility in scheduling.\n\n\n## Features\n\n### 1. Object-Oriented \u003ccode\u003eCronExpression\u003c/code\u003e Builder\n\n**Cronsmith** allows developers to construct complex cron expressions in an intuitive, object-oriented manner. This approach enables easy customization and avoids the need for manual string construction.\n\n#### Example:\n\n```java\n@Test\n    public void testA() {\n        CronExpression cronExpression = new CronBuilder().everySecond(5);\n        System.out.println(cronExpression.toString());\n        assertEquals(\"*/5 * * * * ?\", cronExpression.toString());\n    }\n\n    @Test\n    public void testB() {\n        CronExpression cronExpression = new CronBuilder().everyMinute(5).second(5).andSecond(10)\n                .toSecond(30).andSecond(32).toSecond(59, 2);\n        System.out.println(cronExpression.toString());\n        assertEquals(\"5,10-30,32/2 */5 * * * ?\", cronExpression.toString());\n    }\n\n    @Test\n    public void testC() {\n        CronExpression cronExpression = new CronBuilder().everyMonth().day(10).andDay(15).andDay(16)\n                .andLastDay().everyHour(2).everyMinute(5);\n        System.out.println(cronExpression.toString());\n        assertEquals(\"0 */5 */2 10,15,16,L * ?\", cronExpression.toString());\n    }\n\n    @Test\n    public void testD() {\n        CronExpression cronExpression = new CronBuilder().everyMonth(3).day(10).andLastWeekday()\n                .hour(12).minute(1).toMinute(15, 1);\n        System.out.println(cronExpression.toString());\n        assertEquals(\"0 1-15 12 10,LW */3 ?\", cronExpression.toString());\n    }\n\n    @Test\n    public void testE() {\n        CronExpression cronExpression =\n                new CronBuilder().everyMonth().everyWeek().Mon().toFri().at(15, 10);\n        System.out.println(cronExpression.toString());\n        assertEquals(\"0 10 15 ? * MON-FRI\", cronExpression.toString());\n    }\n\n    @Test\n    public void testF() {\n        CronExpression cronExpression = new CronBuilder().everyMonth().dayOfWeek(3, 6).everyHour(2);\n        System.out.println(cronExpression.toString());\n        assertTrue(cronExpression.toString().equals(\"0 0 */2 ? * SAT#3\"));\n    }\n\n    @Test\n    public void testG() {\n        CronExpression cronExpression =\n                new CronBuilder().year(2025).Mar().toSept().everyWeek().everyWeekday().at(9, 10);\n        System.out.println(cronExpression.toString());\n        assertTrue(cronExpression.toString().equals(\"0 10 9 ? MAR-SEP MON-FRI 2025\"));\n    }\n\n    @Test\n    public void testH() {\n        CronExpression cronExpression =\n                new CronBuilder().year(2025).toYear(2028).everyMonth(2).lastDay().hour(12);\n        System.out.println(cronExpression.toString());\n        assertEquals(\"0 0 12 L */2 ? 2025-2028\", cronExpression.toString());\n    }\n\n    @Test\n    public void testI() {\n        CronExpression cronExpression = new CronBuilder().everyYear().June().andJuly().andAug()\n                .latestWeekday(15).hour(10).toHour(18, 2);\n        System.out.println(cronExpression.toString());\n        assertEquals(\"0 0 10-18/2 15W JUN,JUL,AUG ?\", cronExpression.toString());\n    }\n\n    @Test\n    public void testJ() {\n        CronExpression cronExpression = new CronBuilder().everyYear(2).Mar().andApr().andMay()\n                .toDec().everyWeek(2).Tues().toFri().hour(10).andHour(12).toHour(22).everyMinute()\n                .second(10).andSecond(20).andSecond(30);\n        System.out.println(cronExpression.toString());\n        assertEquals(\"10,20,30 * 10,12-22 ? MAR,APR,MAY-DEC TUE-FRI 2025/2\",\n                cronExpression.toString());\n    }\n\n    @Test\n    public void testK() {\n        CronExpression cronExpression = new CronBuilder().year(2025).toYear(2030).andYear(2035)\n                .toEnd(2).everyMonth(2, 2).dayOfWeek(2, DayOfWeek.TUESDAY)\n                .and(3, DayOfWeek.WEDNESDAY).andLastFri().hour(2).andHour(3).andHour(4)\n                .toHour(17, 2).minute(0).toMinute(12, 3).andMinute(15).toMinute(40, 2).andMinute(46)\n                .andMinute(48).andMinute(50).everySecond(5);\n        System.out.println(cronExpression.toString());\n        assertEquals(\n                \"*/5 0-12/3,15-40/2,46,48,50 2,3,4-17/2 ? FEB-DEC/2 TUE#2,WED#3,5L 2025-2030,2035/2\",\n                cronExpression.toString());\n    }\n\n    @Test\n    public void testL() {\n        CronExpression cronExpression = new CronBuilder().everyYear(2025, 4).everyMonth(5, 1)\n                .day(10).andDay(15).andDay(20).andLastDay(2).hour(10).toHour(15, 1).at(10, 0)\n                .andSecond(15).andSecond(30).andSecond(45);\n        System.out.println(cronExpression.toString());\n        assertEquals(\"0,15,30,45 10 10-15 10,15,20,L-2 MAY-DEC ? 2025/4\",\n                cronExpression.toString());\n    }\n\n    @Test\n    public void testM() {\n        CronExpression cronExpression = new CronBuilder().year().andYear(2026).andYear(2030)\n                .toEnd(2).Mar().andJuly().andSept().dayOfWeek(1, DayOfWeek.SATURDAY)\n                .and(2, DayOfWeek.THURSDAY).andLast(DayOfWeek.FRIDAY).hour(0).toHour(12, 3)\n                .everyMinute(10).second(0).andSecond(15).andSecond(30).andSecond(45).toSecond(59);\n        System.out.println(cronExpression.toString());\n        assertEquals(\"0,15,30,45/1 */10 0-12/3 ? MAR,JUL,SEP SAT#1,THU#2,5L 2025,2026,2030/2\",\n                cronExpression.toString());\n    }\n```\n\n### 2. Cron Expression String Parsing and Reverse Engineering to \u003ccode\u003eCronExpression\u003c/code\u003e\n\n**Cronsmith** includes a powerful parser built with ANTLR, allowing you to parse an existing cron expression string and convert it back into a structured `CronExpression` object.\n\n#### Example:\n\n```java\n    @Test\n    public void testA() {\n        String cron = \"0 0 12 * * ?\";\n        CronExpression cronExpression = CRON.parse(cron);\n        System.out.println(cronExpression);\n        assertEquals(cron, cronExpression.toString());\n    }\n\n    @Test\n    public void testB() {\n        String cron = \"0 15 10 ? * MON-FRI\";\n        CronExpression cronExpression = CRON.parse(cron);\n        System.out.println(cronExpression);\n        assertEquals(cron, cronExpression.toString());\n    }\n\n    @Test\n    public void testC() {\n        String cron = \"0 10,20,30 9-17 L * ?\";\n        CronExpression cronExpression = CRON.parse(cron);\n        System.out.println(cronExpression);\n        assertEquals(cron, cronExpression.toString());\n    }\n\n    @Test\n    public void testD() {\n        String cron = \"1,3,5,7,9 3-30/3 12-16 ? * TUE#1\";\n        CronExpression cronExpression = CRON.parse(cron);\n        System.out.println(cronExpression);\n        assertEquals(cron, cronExpression.toString());\n    }\n\n    @Test\n    public void testE() {\n        String cron = \"0 0 6 ? 1-5 MON,WED,FRI\";\n        CronExpression cronExpression = CRON.parse(cron);\n        System.out.println(cronExpression);\n        assertEquals(cron, cronExpression.toString());\n    }\n\n    @Test\n    public void testF() {\n        String cron = \"*/5 1 12,15,18-22 LW * ? 2025\";\n        CronExpression cronExpression = CRON.parse(cron);\n        System.out.println(cronExpression);\n        assertEquals(cron, cronExpression.toString());\n    }\n\n    @Test\n    public void testG() {\n        String cron = \"0 1 0-12,15,16-22/2 ? * 1-5 2025-2028\";\n        CronExpression cronExpression = CRON.parse(cron);\n        System.out.println(cronExpression);\n        assertEquals(cron, cronExpression.toString());\n    }\n\n    @Test\n    public void testH() {\n        String cron = \"0 1,5,7,13,29,45 12/2 5,10,27W,L-1 APR-NOV ?\";\n        CronExpression cronExpression = CRON.parse(cron);\n        System.out.println(cronExpression);\n        assertEquals(cron, cronExpression.toString());\n    }\n\n    @Test\n    public void testI() {\n        String cron = \"5/1 */5 12 ? 1-9 3#1,5#2,6L\";\n        CronExpression cronExpression = CRON.parse(cron);\n        System.out.println(cronExpression);\n        assertEquals(cron, cronExpression.toString());\n    }\n\n    @Test\n    public void testJ() {\n        String cron = \"*/5 1,3,5/1 12-16 1,3,20,LW MAR-SEP ? 2026/1\";\n        CronExpression cronExpression = CRON.parse(cron);\n        System.out.println(cronExpression);\n        assertEquals(cron, cronExpression.toString());\n    }\n\n    @Test\n    public void testK() {\n        String cron = \"5-30/7 0-12/3,15-45/2 2,3,4-17/2 ? JAN-JUL MON-THU/2 2025-2033\";\n        CronExpression cronExpression = CRON.parse(cron);\n        System.out.println(cronExpression);\n        assertEquals(cron, cronExpression.toString());\n    }\n\n    @Test\n    public void testL() {\n        String cron = \"0,15,30,45/1 */10 0-12/3 ? MAR,JUL,SEP SAT#1,THU#2,5L 2025,2026,2030/2\";\n        CronExpression cronExpression = CRON.parse(cron);\n        System.out.println(cronExpression);\n        assertEquals(cron, cronExpression.toString());\n    }\n\n    @Test\n    public void testM() {\n        String cron = \"*/2 0 12 1,5,9,22,L */2 ? 2025/2\";\n        CronExpression cronExpression = CRON.parse(cron);\n        System.out.println(cronExpression);\n        assertEquals(cron, cronExpression.toString());\n    }\n```\n\nParse Tree: \n\n``` shell\ncron\n    second\n        secondField\n            rangeWithStep\n                5\n                -\n                30\n                /\n                7\n    \u003cmissing SPACE\u003e\n    minute\n        minuteField\n            rangeWithStep\n                0\n                -\n                12\n                /\n                3\n        ,\n        minuteField\n            rangeWithStep\n                15\n                -\n                45\n                /\n                2\n    \u003cmissing SPACE\u003e\n    hour\n        hourField\n            2\n        ,\n        hourField\n            3\n        ,\n        hourField\n            rangeWithStep\n                4\n                -\n                17\n                /\n                2\n    \u003cmissing SPACE\u003e\n    dayOfMonth\n        dayOfMonthField\n            ?\n    \u003cmissing SPACE\u003e\n    month\n        monthField\n            monthRange\n                monthName\n                    JAN\n                -\n                monthName\n                    JUL\n    \u003cmissing SPACE\u003e\n    dayOfWeek\n        dayOfWeekField\n            weekdayRangeWithStep\n                dayOfWeekName\n                    MON\n                -\n                dayOfWeekName\n                    THU\n                /\n                2\n    year\n        yearField\n            yearRange\n                2025\n                -\n                2030\n    \u003cEOF\u003e\n```\n\nRetrieve next date and times from  \u003ccode\u003eCronExpression\u003c/code\u003e\n\n```java\npublic static void main(String[] args) {\n   int N = 100; // Retrieve 100 items\n   String cron = \"10 0 12 LW 1/2 ?\";\n   CronExpression cronExpression = CRON.parse(cron);\n   System.out.println(cronExpression);\n   cronExpression.consume(l -\u003e {\n       System.out.println(l);\n   }, N);\n}\n\n// Console:\n// 2025-05-30T12:00:10\n// 2025-07-31T12:00:10\n// 2025-09-30T12:00:10\n// 2025-11-28T12:00:10\n// 2026-01-30T12:00:10\n// 2026-03-31T12:00:10\n// 2026-05-29T12:00:10\n// 2026-07-31T12:00:10\n// 2026-09-30T12:00:10\n// 2026-11-30T12:00:10\n// 2027-01-29T12:00:10\n// 2027-03-31T12:00:10\n// 2027-05-31T12:00:10\n// 2027-07-30T12:00:10\n// 2027-09-30T12:00:10\n// 2027-11-30T12:00:10\n// 2028-01-31T12:00:10\n// 2028-03-31T12:00:10\n// 2028-05-31T12:00:10\n// ...\n\n```\n\n\n\n### 3. Built-in Scheduler\n\n**Cronsmith** provides a built-in scheduler that allows you to execute tasks at specified intervals based on cron expressions. This feature makes it easy to schedule repetitive tasks efficiently.\n\n#### Example: Scheduling a Task Every 5 Seconds\n\n```java\nprivate ScheduledExecutorService scheduledExecutorService;\n\n@Before\npublic void start() {\n    scheduledExecutorService =\n                Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors() * 2);\n}\n\n@Test\npublic void testSchedulerAndRunTenTimes() {\n    int N = 10; // Run 10 times\n    final CountDownLatch latch = new CountDownLatch(N);\n    final AtomicInteger counter = new AtomicInteger();\n    \n    CronFuture future = new CronBuilder()\n        .everySecond(5)\n        .scheduler(scheduledExecutorService)\n        .setDebuged(false)\n        .runTask(() -\u003e {\n            System.out.println(\"Run task_\" + counter.incrementAndGet());\n            latch.countDown();\n        }, N);\n    \n    try {\n        latch.await();\n    } catch (InterruptedException e) {\n        Thread.currentThread().interrupt();\n    }\n    \n    future.cancel(true);\n    assertTrue(future.isDone() \u0026\u0026 counter.get() == N);\n}\n\n@After\npublic void release() {\n    scheduledExecutorService.shutdown();\n}\n```\n\n### 4. Advanced Part\n\n**Can specify day of year**\n\n``` java\npublic static void main(String[] args) {\n   int N = 1000;\n   DateTimeFormatter dtf = DateTimeFormatter.ofPattern(\"yyyy-MM-dd HH:mm:ss\");\n   new CronBuilder().setZoneId(ZoneId.of(\"UTC\")).year(2025).day(208).andDay(330).toLastDay()\n                .at(12, 0).consume(ldt -\u003e {\n                    System.out.println(ldt.format(dtf));\n                }, N);\n}\n// Console: \n// 2025-07-27 12:00:00\n// 2025-11-26 12:00:00\n// 2025-11-27 12:00:00\n// 2025-11-28 12:00:00\n// 2025-11-29 12:00:00\n// 2025-11-30 12:00:00\n// 2025-12-01 12:00:00\n// 2025-12-02 12:00:00\n// 2025-12-03 12:00:00\n// 2025-12-04 12:00:00\n// 2025-12-05 12:00:00\n// 2025-12-06 12:00:00\n// ...\n\n```\n\n**Can specify week of year**\n\n``` java\npublic static void main(String[] args) {\n    int N = 1000;\n    DateTimeFormatter dtf = DateTimeFormatter.ofPattern(\"yyyy-MM-dd HH:mm:ss\");\n    new CronBuilder().setZoneId(ZoneId.of(\"UTC\")).everyYear().week(40).andWeek(45).Mon().toFri()\n                .at(12, 0).consume(ldt -\u003e {\n                    System.out.println(ldt.format(dtf));\n                }, N);\n}\n// Console: \n// 2025-09-29 12:00:00\n// 2025-09-30 12:00:00\n// 2025-10-01 12:00:00\n// 2025-10-02 12:00:00\n// 2025-10-03 12:00:00\n// 2025-11-03 12:00:00\n// 2025-11-04 12:00:00\n// 2025-11-05 12:00:00\n// 2025-11-06 12:00:00\n// 2025-11-07 12:00:00\n// 2026-09-28 12:00:00\n// 2026-09-29 12:00:00\n// 2026-09-30 12:00:00\n// 2026-10-01 12:00:00\n// 2026-10-02 12:00:00\n// ...\n```\n\n\n\n## Installation\n\nSupport Jdk1.8 or later\n\nTo use **Cronsmith** in your Java project, add the following dependency to your `pom.xml` (if using Maven):\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.paganini2008\u003c/groupId\u003e\n    \u003cartifactId\u003ecronsmith\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.0-RC1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nIf using Gradle:\n\n```gradle\ndependencies {\n    implementation 'com.github.paganini2008:cronsmith:1.0.0-RC1'\n}\n```\n\n## Getting Started\n\n1. Add Cronsmith as a dependency in your project.\n2. Use `CronBuilder` to create complex cron expressions.\n3. Parse existing cron expressions using `CRON.parse()`.\n4. Schedule tasks using the built-in scheduler.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Download\n\n[Click here to download the latest release](https://github.com/paganini2008/cronsmith)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaganini2008%2Fcronsmith","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaganini2008%2Fcronsmith","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaganini2008%2Fcronsmith/lists"}