DEV Community

Cover image for How Woovi handles complex date generation with Javascript
Danilo Assis for Woovi

Posted on

How Woovi handles complex date generation with Javascript

Everyone comments that data in javascript is a nightmare. Whether to generate new dates, deal with existing dates, migrations, etc.
Regardless of the context, people go crazy with dates.

Within Woovi we have several products that work directly linked to a date.

We have the generation of a Pix, the recurrence of signatures, pix in installments, sending scheduled emails, scheduled payments, among others.

Today we're going to talk about how we calculate the space between two dates and the days they repeat: recurrence.

Let's imagine the following scenario:

Scenario

Given a value, from 1 to 12, we want to generate the dates in that range based on a frequency. The frequency will be monthly and the dates must be generated on the same day as the initial one.

The initial date will always be the one when the script was run.

Problems

  • if the starting date is at the end of the month, we want you to take the closest previous day. If it's 31 today and the next one doesn't exist, you should get 30
  • the same rule applies for February ending on the 28th
  • the same rule applies for February in leap years

With pure javascript it is possible to do this generation. However, it can become somewhat difficult to guarantee that the rule is always correct.

What if we used something ready and that works?

So we decided to go with RRule, which as the lib itself says:

"rrule.js supports recurrence rules as defined in the iCalendar RFC, with a few important differences. It is a partial port of the rrule module from the excellent python-dateutil library. On top of that, it supports parsing and serialization of recurrence rules from and to natural language."

The Code

import { RRule } from 'rrule';

const recurrentNumber = 4;

const dateStart = moment(new Date())
  .startOf('day')
  .toDate();

const dateEnd = moment(dateStart)
  .add(recurrentNumber, 'month')
  .endOf('day')
  .toDate();

const rule = new RRule({
  freq: RRule.MONTHLY,
  dtstart: dateStart,
  until: dateEnd,
  bymonthday: -1,
Enter fullscreen mode Exit fullscreen mode

Breaking in steps:

  • declare the start date
  • get the end date and add the number of months based in the recurrent number
const dateStart = moment(new Date())
  .startOf('day')
  .toDate();

const dateEnd = moment(dateStart)
  .add(recurrentNumber, 'month')
  .endOf('day')
  .toDate();
Enter fullscreen mode Exit fullscreen mode
  • then, we call the rrule
  • pass the frequency, dtstart, until and the bymonthday which means:
If given, it must be either an integer, or an array of integers, meaning the month days to apply the recurrence to.
Enter fullscreen mode Exit fullscreen mode

and the result having a date start for 01/31/2023 is:

// date start and date end
{
  dateStart: 2023-01-30T03:00:00.000Z,
  dateEnd: 2023-05-31T02:59:59.999Z
}
// array of generated date
[
  2023-01-31T03:00:00.000Z,
  2023-02-28T03:00:00.000Z,
  2023-03-31T03:00:00.000Z,
  2023-04-30T03:00:00.000Z
]
Enter fullscreen mode Exit fullscreen mode

Conclusion

There is a world of endless implementations for the above problem and code, but with Woovi you have just learned a new way that is simple and fun!

References


If you want to work in a startup in its early stages, This is your chance. Apply today!


Woovi is a Startup that enables shoppers to pay as they please. To make this possible, Woovi provides instant payment solutions for merchants to accept orders.


Photo by insung yoon na Unsplash

Top comments (0)