https://github.com/s-taylor/time-walk
A simple recurrence library
https://github.com/s-taylor/time-walk
date moment-timezone momentjs recurrance rule timezone
Last synced: about 2 months ago
JSON representation
A simple recurrence library
- Host: GitHub
- URL: https://github.com/s-taylor/time-walk
- Owner: s-taylor
- License: mit
- Created: 2017-04-13T10:17:43.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2017-07-04T22:50:38.000Z (almost 8 years ago)
- Last Synced: 2025-04-05T13:51:27.386Z (2 months ago)
- Topics: date, moment-timezone, momentjs, recurrance, rule, timezone
- Language: JavaScript
- Size: 239 KB
- Stars: 8
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Time Walk [](https://circleci.com/gh/s-taylor/time-walk)

## What is this?
**Time Walk** is a simple library for generating date recurrance rules. I was inspired to write this after having previously used **Rrule** for a work project and found **Rrule** to have it's quirks. This module heavily leverages the [moment-timezone](https://momentjs.com/timezone/) library and aims to keep this library as lightweight as possible.
See [Rrule library here](https://github.com/jakubroztocil/rrule)
See [differences to Rrule here](https://gist.github.com/s-taylor/f59e0cefc9c2e52d77271cebf021de01)
## What would I use this for?
There are a number of potential use cases for this module, two better examples I can think of are...
* Generating calendar appointments based on a defined pattern (rule).
* Implementing a scheduled jobs service in your app, where timezone support is important. Cron doesn't support fortnightly intervals or multi-timezone.## Try it out
[See runkit demo here](https://runkit.com/nizmox/time-walk-demo)
## How do I use it?
### Syntax
#### Install
`yarn add time-walk`
OR
`npm install --save time-walk`#### Creating a Rule
Arguments for a `new` rule are...
* **start** a `moment-timezone` object where the date and timezone align to the first occurance you want the rule to generate. The timezone specified in the `moment-timezone` object will be used to generate all occurrences (dates) by **Time Walk**. See [moment-timezone](https://momentjs.com/timezone/) for more details.
* an **interval**, starting from the start date, how far apart do we want occurrence (date) to be (must be in a format `moment.js` understands, see [moment docs here](https://momentjs.com/docs/#/manipulating/add/).For example, if I want a rule that recurs on the 1st of every month according to the time in Sydney, Australia, and I wan't my rule to start from next month (July 2017), I would input...
```js
const moment = require('moment-timezone');
const { TimeWalk } = require('time-walk');const start = new moment.tz('2017-07-01', 'Australia/Sydney');
const rule = new TimeWalk(start, { months: 1 });
```OR if I want a rule that recurs every second Monday (fortnightly), starting in July 2017 in UTC.
```js
const moment = require('moment-timezone');
const { TimeWalk } = require('TimeWalk');const start = new moment.tz('2017-07-03', 'UTC');
const rule = new TimeWalk(start, { weeks: 2 });
```
Note: the 3rd of July is the first Monday in July, so this needs to be the start date.#### Getting (n)th Occurance
If I want to get the 2nd occurance of my rule...
```js
const start = new moment.tz('2017-07-01', 'Australia/Sydney');
const rule = new TimeWalk(start, { months: 1 });const result = rule.occurance(2) // result === 2017-08-01 in Australia/Sydney Time
```
Note: The start date **counts** as the first occurence.#### Getting the first (x) Occurances
If I want to get the first three ooccurances of my rule...
```js
const start = new moment.tz('2017-07-01', 'Australia/Sydney');
const rule = new TimeWalk(start, { months: 1 });const result = rule.first(3)
// result === [2017-07-01, 2017-08-01, 2017-09-01] in Australia/Sydney Time
```
Note: The start date **counts** as the first occurence.#### Getting Occurances within a Range
If I want to get ALL occurences for my rule that exist between two dates.
For example, to get all occurences in July I would do...```js
const start = new moment.tz('2017-07-01', 'Australia/Sydney');
const rule = new TimeWalk(start, { weeks: 1 });const from = new moment.tz('2017-07-01', 'Australia/Sydney');
const to = new moment.tz('2017-08-01', 'Australia/Sydney');
const result = rule.between(from, to);// result === [2017-07-01, 2017-07-08, 2017-07-15, 2017-07-22, 2017-07-29]
// in Australia/Sydney Time
```#### Converting to a string
This is useful if you want to store rules in a database.
You may also need to store the last occurance generated via the rule, but that must be handled separately.```js
const start = new moment.tz('2017-07-01', 'Australia/Sydney');
const rule = new TimeWalk(start, { months: 1 });const result = rule.toString();
// result === "START=2017-06-30T14:00:00.000Z;INTERVAL=M1;TZ=Australia/Sydney;"
```#### Parse a rule (convert from a string)
```js
const { parse } = require('time-walk');const rule = parse("START=2017-06-30T14:00:00.000Z;INTERVAL=M1;TZ=Australia/Sydney;");
// rule === new TimeWalk(new moment.tz('2017-07-01', 'Australia/Sydney'), { months: 1 });
```## Why am I doing this?
At present I'm doing this purely as a personal challenge at this point, it's an interesting problem to solve but as I'm not doing this for work, and thus not spending work time on it, set expectations accordingly.
## How can I help?
Send me a pull request! Please don't send me a pull request without tests though.
## What's changed?
[View Changelog](https://github.com/s-taylor/time-walk/blob/master/CHANGELOG.md)
## What still needs doing...
* Allow setting a default output type in constructor
* Add setter method (including setting default output type)
* Test between from and to validations
* Test interval is required (in constructor)
* Limit how many occurances get returned to 100?
* Document specifying output format* Add `.fromString` to create a rule with a date in string format + timezone.
* remove use of decimals in calcs so more accurate?
* compile to ES2015