Friday, 14 September 2012

Human readable cron expressions using JavaScript

So I was faced with the task of presenting cron expression (like '3 * * * *') on a web page in human readable format. I figured there would be plenty of scripts available to do just that, ready for use.
With the limitations to using JavaScript, I found nothing! Either it is hidden away somewhere or no one have published a script to convert cron expression in to human readable format.

After a little soul searching I decided to write my own implementation.
The final result looks like this:
Cron expression: 15 3,8,10,12,14,16,18 16 * *
Human readable: Every 15th minute past the 3, 8, 10, 12, 14, 16 and 18th hour on the 16th every month
Next run: Sunday at 3:15 AM

Cron expression: 30 * * * *
Human readable: Every 30th minute past every hour
Next run: Today at 1:30 AM

Cron expression: 0 * * * *
Human readable: Every hour, on the hour
Next run: Today at 2:00 AM

Cron expression: * 8,10,12,14,16,18,20 * * *
Human readable: Every minute of 8, 10, 12, 14, 16, 18 and 20th hour
Next run: Today at 8:00 AM

Cron expression: 2 8,10,12,14,16,18 * 4 0,3
Human readable: Every 2nd minute past the 8, 10, 12, 14, 16 and 18th hour in Apr on Sun and Thu
Next run: 04/07/2013

Dependencies

First download the dependencies:
moment.min.js - Credit Moment.js
later.min.js - Credit bunkat
prettycron.js - Credit myself

How to use

Copy the dependencies above to the web server.
In the same directory, create a new basic HTML file called prettycron.html.
Include the dependencies in prettycron.html:
    <script src="later.min.js" type="text/javascript"></script>
    <script src="moment.min.js" type="text/javascript"></script>
    <script src="prettycron.js" type="text/javascript"></script>

Add this in the body of prettycron.html:
document.write(getPrettyCron(cronParser().parse('0 * * * *', false)));

Open the page in a web browser and you should see the following output:
Every minute

That is it, just replace '0 * * * *' with any basic cron expression to see it in human readable format.


Full example

Please find the full example below to produce the example from introduction:
<html>
  <head>
    <title>Human readable cron schedule</title>
    <script src="later.min.js" type="text/javascript"></script>
    <script src="moment.min.js" type="text/javascript"></script>
    <script src="prettycron.js" type="text/javascript"></script>
  </head>
<body>
<script type="text/javascript">
function printCron(cron) {
    var s1 = cronParser().parse(cron, false);
    document.write('<b>Cron expression: </b>' + cron + '<br/>');
    document.write('<b>Human readable: </b>' + getPrettyCron(s1['schedules'][0]) + '<br/>');
    document.write('<b>Next run: </b>' + moment(later(60,true).getNext(s1)).calendar() + '<br/><br/>');
}
printCron('15 3,8,10,12,14,16,18 16 * *');
printCron('30 * * * *');
printCron('0 * * * *');
printCron('* 8,10,12,14,16,18,20 * * * ');
printCron('2 8,10,12,14,16,18 * 4 0,3 ');
</script>
</body>


Internet Explorer pre-9

Only in Internet Explorer 9 support came for Array.indexOf. The scripts depends heavily on this method so to make it work in Internet Explorer 6-8, perform the following steps:
1. Create ielt9.js containing the code from "Compatibility" section of:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf

2. Inside <head></head> add:
<!--[if lt IE 9]><script src="js/ltie9.js" type="text/javascript" charset="UTF-8"></script><![endif]-->

7 comments:

  1. It appears that moment.min.js and later.min.js are under the MIT License, but what about prettycron.js? I can't find a copyright notice or other license information. You obviously want others to use the code, or you wouldn't have shared it. How are you supposed to receive credit for your work if you don't stick your name on it? Please let me know.
    Thanks for sharing!

    ReplyDelete
    Replies
    1. I added LGPL notice in the header.
      Hope you find it useful.

      Delete
  2. I was looking for a web site that implements this, as it is very useful for the few times I edit crontab files. However, it does not support the complete syntax, e.g. */5 in the minute field for every fith minute.

    ReplyDelete
  3. Thank you dunse for your great work ! :)
    I don't know why but it doesn't work for me.
    I've copy/paste all your code and download all referencies.
    My links to referencies are good.
    In firebug, I get this error :

    ReferenceError: cronParser is not defined
    var s1 = cronParser().parse(cron, false);

    I hope you will help me.
    Thank you !

    Cyrille

    ReplyDelete
    Replies
    1. Use later.parse.cron instead of CronParser().parse

      Delete
  4. the link is broken prettycron.js is no longer avialable

    ReplyDelete
    Replies
    1. It's here (by different maintainer)
      https://github.com/azza-bazoo/prettycron

      Delete