Skip to content

Instantly share code, notes, and snippets.

@rajivm
Forked from kjhangiani/interview-cron.md
Last active November 11, 2021 22:41
Show Gist options
  • Save rajivm/b14690d7fcb70eadfacf58397c500859 to your computer and use it in GitHub Desktop.
Save rajivm/b14690d7fcb70eadfacf58397c500859 to your computer and use it in GitHub Desktop.
CRON to Dates API Endpoint

Cron2Date Parser

Summary

Create an API endpoint that accepts a json payload of cron strings, and returns a json payload of valid dates for these strings. Include any applicable tests for this endpoint using the testing platform of your choice.

Details

Frequency Object

A 'frequency' is an object that contains two attributes: name <string> and crons <Array> The crons property is a javascript array of strings (with cron format of "* * * * * *" representing "[sec] [min] [hr] [date] [month] [day of week]"). The following is an array of frequency objects.

[{
  name: "Monthly",
  crons: ["0 0 0 25 * *"] //the 25th of every month
},
{
  name: "Weekly",
  crons: ["0 0 0 * * 5"] //every friday
},
{
  name: "BiWeekly",
  crons: ["0 0 0 20 * *", "0 0 0 10 * *"] //the 10th and 20th of every month
},
{
  name: "Quarterly",
  crons: ["0 0 0 25 3 *", "0 0 0 27 6 *", "0 0 0 30 9 *", "0 0 0 22 12 *", "0 0 0 25 3 *"] //Mar 25, Jun 27, Sep 30, and Dec 22 - note duplicated Mar 25 entry
}]

Request data

We want an API endpoint that accepts an object with an array of frequencies, as well as a given start_date and end_date range (such as Jan 1, 2016 to Jan 31, 2016). Frequency names will always be unique within a request. The API should accept JSON as the POST payload.

Thus, the API endpoint POST /calculate-crons will receive json with the following structure:

{
  "start_date": "2016-02-01T08:00:00.000Z",
  "end_date": "2016-02-28T08:00:00.000Z",
  "frequencies": [
    {
      "name": "Monthly",
      "crons": ["0 0 0 25 * *"]
    },
    {
      "name": "BiWeekly",
      "crons": ["0 0 0 20 * *", "0 0 0 10 * *"]
    },
    {
      "name": "Weekly",
      "crons": ["0 0 0 * * 5"]
    },
    {
      "name": "Quarterly",
      "crons": ["0 0 0 25 3 *", "0 0 0 27 6 *", "0 0 0 30 9 *", "0 0 0 22 12 *", "0 0 0 25 3 *"]
    }
  ]
}

Response data

For every frequency object, the API will return a list of dates in the provided range that match any of the provided cron strings. We want to accomplish this using a single API request. The returned dates for each frequency should be sorted in ascending order, and not contain any duplicates. The response json should be keyed by the frequency name (assume its a unique alphanumeric string).

And the expected JSON response would be the following:

{
  "Monthly":[
    "2016-02-25T08:00:00.000Z"
  ],
  "Weekly":[
    "2016-02-05T08:00:00.000Z",
    "2016-02-12T08:00:00.000Z",
    "2016-02-19T08:00:00.000Z",
    "2016-02-26T08:00:00.000Z"
  ],
  "BiWeekly":[
    "2016-02-10T08:00:00.000Z",
    "2016-02-20T08:00:00.000Z"
  ],
  "Quarterly":[]
}

Assumptions & Tips

The following assumptions can be made:

  • All dates will be represented in UTC, please don't worry about time zone conversions
  • Cron strings will be valid
  • Frequency names will be unique
  • Each Frequency will contain at least one cron string.
  • All other cases may return a 400 or 500 error.

You CANNOT assume:

  • That there will be any valid dates within the specified date range
  • That the cron strings will be any specific order

You may use the following library to parse cron strings: https://www.npmjs.com/package/cron-parser

Note: one gotcha is that this library throws an error if the cron string does not result in any valid dates for the specified period - you need to catch and handle this error, as it is NOT an error for the purposes of this exercise - if there are no valid dates, return an empty array for that frequency.

You may use any framework (and test framework) to complete this exercise.

Submission

Once you are finished, email us a link to a git repository with your code, including tests.Please feel free to email if you have any clarification questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment