+ {hasInteracted && isValid === false && (
+
+
+ Invalid crontab expression.
+
+
+ )}
+
+
+
+
+ }
+ initialValues={initialValues}
+ exampleCards={exampleCards}
+ getGroups={null}
+ setInput={setInput}
+ compute={compute}
+ toolInfo={{ title: `What is a ${title}?`, description: longDescription }}
+ />
+ );
+}
diff --git a/src/pages/tools/time/crontab-guru/meta.ts b/src/pages/tools/time/crontab-guru/meta.ts
new file mode 100644
index 0000000..1ce0744
--- /dev/null
+++ b/src/pages/tools/time/crontab-guru/meta.ts
@@ -0,0 +1,24 @@
+import { defineTool } from '@tools/defineTool';
+import { lazy } from 'react';
+
+export const tool = defineTool('time', {
+ name: 'Crontab explainer',
+ path: 'crontab-guru',
+ icon: 'mdi:calendar-clock',
+ description:
+ 'Parse, validate, and explain crontab expressions in plain English.',
+ shortDescription: 'Crontab expression parser and explainer',
+ keywords: [
+ 'crontab',
+ 'cron',
+ 'schedule',
+ 'guru',
+ 'time',
+ 'expression',
+ 'parser',
+ 'explain'
+ ],
+ longDescription:
+ 'Enter a crontab expression (like "35 16 * * 0-5") to get a human-readable explanation and validation. Useful for understanding and debugging cron schedules. Inspired by crontab.guru.',
+ component: lazy(() => import('./index'))
+});
diff --git a/src/pages/tools/time/crontab-guru/service.ts b/src/pages/tools/time/crontab-guru/service.ts
new file mode 100644
index 0000000..638636c
--- /dev/null
+++ b/src/pages/tools/time/crontab-guru/service.ts
@@ -0,0 +1,22 @@
+import cronstrue from 'cronstrue';
+import { isValidCron } from 'cron-validator';
+
+export function explainCrontab(expr: string): string {
+ try {
+ return cronstrue.toString(expr);
+ } catch (e: any) {
+ return `Invalid crontab expression: ${e.message}`;
+ }
+}
+
+export function validateCrontab(expr: string): boolean {
+ return isValidCron(expr, { seconds: false, allowBlankDay: true });
+}
+
+export function main(input: string, _options: any): string {
+ if (!input.trim()) return '';
+ if (!validateCrontab(input)) {
+ return 'Invalid crontab expression.';
+ }
+ return explainCrontab(input);
+}
diff --git a/src/pages/tools/time/index.ts b/src/pages/tools/time/index.ts
index 9b80e65..1e9145d 100644
--- a/src/pages/tools/time/index.ts
+++ b/src/pages/tools/time/index.ts
@@ -1,3 +1,4 @@
+import { tool as timeCrontabGuru } from './crontab-guru/meta';
import { tool as timeBetweenDates } from './time-between-dates/meta';
import { tool as daysDoHours } from './convert-days-to-hours/meta';
import { tool as hoursToDays } from './convert-hours-to-days/meta';
@@ -11,5 +12,6 @@ export const timeTools = [
convertSecondsToTime,
convertTimetoSeconds,
truncateClockTime,
- timeBetweenDates
+ timeBetweenDates,
+ timeCrontabGuru
];