Evalate a date expression calc`now + 3 days`)!
npm install calcdate
import { calc } from "calcdate";
// import { datefnscalc } from "calcdate"; // with date-fns
// import { luxoncalc } from "calcdate"; // with luxon
// import { luxonsimplecalc } from "calcdate"; // with luxon
// import { momentcalc } from "calcdate"; // with moment
// import moment from "moment";
const dval = calc();
// const dval = momentcalc(moment);
dvalnow + 3 days + 5 hours;
`
$3
`
const calc = require("calcdate").default;
// const luxoncalc = require("calcdate").luxoncalc;
// import luxon from "luxon";
const dval = calc();
// const dval = luxoncalc(luxon);
dvalnow + 3 days + 5 hours;
`
$3
`
https://embed-sw29njl68eg5.runkit.sh/P1d
// https://embed-sw29njl68eg5.runkit.sh/datefns/now+5d
// https://embed-sw29njl68eg5.runkit.sh/moment/now+5d
// https://embed-sw29njl68eg5.runkit.sh/luxon/now+5d
`
Install
`
yarn add calcdate
`
`
npm i calcdate
`
git repo
Find source code on git
!Bundle size

Dependencies
There are no direct dependencies!
We recommend using this lib with your favourite date-time lib, use the bindings provided.
| import | required dependency | import |
| --------------------- | ---------------------------------------- | --------------------------------------------------- |
| datefnsCalculator | date-fns | import { datefnsCalculator } from "calcdate"; |
| luxonCalculator | luxon | import { luxonCalculator } from "calcdate"; |
| simpleluxonCalculator | luxon | import { simpleluxonCalculator } from "calcdate"; |
| momentCalculator | moment | import { momentCalculator } from "calcdate"; |
Note
You need to initialize the calculator with your library:
`
import { datefnsCalculator } from "calcdate"
import datefns from "datefns";
const calculator = datefnsCalculator(datefns);
`
Api docs
Calling the calculator is easy:
`
calculator
`
Example
`
// Imports
import { datefnsCalculator } from "calcdate"
import datefns from "datefns";
// Setup
const calculator = datefnsCalculator(datefns);
// Examples:
calculator2009-12T12:34;
calculatorP0002--10-15T10:+30:20;
calculatorNOW + 7days;
calculator2009-12T12:00 - 2019-12T12:00;
`
where calculator is your imported calculator and expression is what you want calculated. The following section outlines what is permitted in expressions.
$3
The calculator has to be initialized by passing it the library you are usigng it with with.
`
const luxon = require("luxon");
const calculator = require("calcdate").luxoncalc(luxon);
`
$3
Being a date-calculator the primary types used in expressions are date-times and the differences in between them (being durations and intervals).
#### Date-Time
A datetime is an exact point in time. It can be expressed as a ISO-8601-date-time (see w3 and wikipedia). Simply put, use the format YYYY-MM-DDThh:mm:ss.sss ("extended format"). All parts (but the year) are optional. If a part is not present, its default is used (0 for times and 1 for dates; 2019 = 2019-01-01T00:00:00.000). You can also use the normal form YYYYMMDD hhmmsssss. You can also add a time-zone using YYYY-MM-DDThh:mm:ss.sss+-hh:mm or YYYY-MM-DDThh:mm:ss.sssZ for utc.
Examples
`
2009-12T12:34 // Tue Dec 01 2009 12:34:00 GMT+1100 (Australian Eastern Daylight Time)
2009 // Thu Jan 01 2009 11:00:00 GMT+1100 (Australian Eastern Daylight Time)
2009-05-19 // Tue May 19 2009 10:00:00 GMT+1000 (Australian Eastern Standard Time)
2009-05-19 // Tue May 19 2009 00:00:00 GMT+1000 (Australian Eastern Standard Time)
2009-05 // Fri May 01 2009 10:00:00 GMT+1000 (Australian Eastern Standard Time)
2009-001 // Thu Jan 01 2009 00:00:00 GMT+1100 (Australian Eastern Daylight Time)
2009-05-19 // Tue May 19 2009 10:00:00 GMT+1000 (Australian Eastern Standard Time)
2009-05-19T00:00 // Tue May 19 2009 00:00:00 GMT+1000 (Australian Eastern Standard Time)
2009-05-19T14:31 // Tue May 19 2009 14:31:00 GMT+1000 (Australian Eastern Standard Time)
2009-05-19T14:39:22 // Tue May 19 2009 14:39:22 GMT+1000 (Australian Eastern Standard Time)
2009-05-19T14:39Z // Wed May 20 2009 00:39:00 GMT+1000 (Australian Eastern Standard Time)
2009-05-19T14:39:22-06:00 // Wed May 20 2009 06:39:22 GMT+1000 (Australian Eastern Standard Time)
2009-05-19T14:39:22+0600 // Tue May 19 2009 18:39:22 GMT+1000 (Australian Eastern Standard Time)
2007-04-06T00:00 // Fri Apr 06 2007 00:00:00 GMT+1000 (Australian Eastern Standard Time)
200912T1234 // Tue Dec 01 2009 12:34:00 GMT+1100 (Australian Eastern Daylight Time)
2009 // Thu Jan 01 2009 11:00:00 GMT+1100 (Australian Eastern Daylight Time)
20090519 // Tue May 19 2009 10:00:00 GMT+1000 (Australian Eastern Standard Time)
20090519 // Tue May 19 2009 00:00:00 GMT+1000 (Australian Eastern Standard Time)
200905 // Fri May 01 2009 10:00:00 GMT+1000 (Australian Eastern Standard Time)
2009001 // Thu Jan 01 2009 00:00:00 GMT+1100 (Australian Eastern Daylight Time)
20090519 // Tue May 19 2009 10:00:00 GMT+1000 (Australian Eastern Standard Time)
20090519 0000 // Tue May 19 2009 00:00:00 GMT+1000 (Australian Eastern Standard Time)
20090519 1431 // Tue May 19 2009 14:31:00 GMT+1000 (Australian Eastern Standard Time)
20090519 143922 // Tue May 19 2009 14:39:22 GMT+1000 (Australian Eastern Standard Time)
20090519 1439Z // Wed May 20 2009 00:39:00 GMT+1000 (Australian Eastern Standard Time)
20090519 143922-06:00 // Wed May 20 2009 06:39:22 GMT+1000 (Australian Eastern Standard Time)
20090519 143922+0600 // Tue May 19 2009 18:39:22 GMT+1000 (Australian Eastern Standard Time)
20070406 0000 // Fri Apr 06 2007 00:00:00 GMT+1000 (Australian Eastern Standard Time)
`
##### Binding depended
Each parser may provide its own parsing-from-string mechanism using {....}-notation.
Example
{"2012 juillet", "YYYY MMM", "fr"} + moment-bindings
{"12/11/2000", "MM/dd/yyyy"} + luxon-bindings
#### Duration
A duration expresses a time-period, aka "how long". A duration may be expressed using an iso-duration or the short-hand notation as follows.
Note
Without a start- or end-date (see Interval) the units in a duration are hard to compare. For example, a duration of 1 month can be either anywhere from 28 days (2019-02-01/2019-03-01) to 31 days (2019-12-01/2020-01-01). Therefore some operations might be unsafe to perform, such as 1 month / 1 days (interpreted as "how many days fit into a month"). Depending on the bindings a loss of information and accuracy may occurs. (Also see luxon-notes.)
##### Short-hand notation
Each short-hand notation has three different forms which can be used synonymously: spelled-out singular, plural and shorthand (which makes it a shorthand-shorthand, I guess?). Whitespace is irrelevant. So 1 day, 1 days, 1 d, 1day, 1days, 1d all mean "1 day".
| singular | plural | shorthand | example | notes |
| ----------- | ------------ | --------- | ------- | ------------------ |
| millisecond | milliseconds | ms | 5ms | |
| second | seconds | s | 1 s | alias: ss, sec |
| minute | minutes | m | 1 min | alias: min, mm, Tm |
| hour | hours | h | 1 h | alias: hh |
| day | days | d | 1 d | |
| weekday | weekdays | wd | 1 wd | |
| week | weeks | w | 1 w | |
| fortnight | fortnights | fn | 1 fn | = two weeks |
| month | months | M | 1 M | alias: l, L |
| quarter | quarters | q | 1 q | |
| year | years | y | 1 y | alias: a |
In general these notation are caseinsensetive and can be pluralized, with the following exceptions:
- M, months, not to be confused with m, minutes
- m, minutes, see above
- ms, milliseconds, not to be confused Ms, plural of M, months
##### Iso-Notation
Durations may be written in iso as PnYnMnDTnHnMnS (where n is a any number).
From wikipedia:
> P is the duration designator (for period) placed at the start of the duration representation.
>
> Y is the year designator that follows the value for the number of years.
>
> M is the month designator that follows the value for the number of months.
>
> W is the week designator that follows the value for the number of weeks.
>
> D is the day designator that follows the value for the number of days.
>
> T is the time designator that precedes the time components of the representation.
>
> H is the hour designator that follows the value for the number of hours.
>
> M is the minute designator that follows the value for the number of minutes.
>
> S is the second designator that follows the value for the number of seconds.
"+" and "-" are allowed for the entire expression and parts individually. Thus +P1Y (1 year), -P1Y (minus 1 year) and -P-1y (minus minus 1 year = 1 year) are valid.
Examples
`
// Iso extended form, any number of digits allowed
P1Y2M3DT4H05M600S // 1 year, 2 months, 3 days, 4 hours, 5 minutes, 600 seconds
PT3H5M // 3 hours, 5 minus
P1Y // 1 year
P-1Y1M // -1 year, 1 month -> effectively 11 month
P1DT-30S // 1 day, -30 seconds
P1Y // 1 year
P2M // 2 month
P3D // 3 days
PT4H // 4 hours
PT05M // 5 minutes; padding with 0s is allowed
PT600S // 600 seconds; more than 2 digits are allowed
P1y2m3dT4h5m6s // 1 year, 2 months, 3 days, 4 hours, 5 minutes, 6 seconds; case-insensitive
// Iso-short-form, 4 digits for year, 2 for each other component
P00021015T103020 // 2 years, 10 months, 15 days, 10 hours, 30 minutes, 20 seconds
P00021015 // 2 years, 10 months, 15 days
P0002-10-15T10:30:20 // 2 years, 10 months, 15 days, 10 hours, 30 minutes, 20 seconds
P0002-10-15 // 2 years, 10 months, 15 days
+P00021015T103020
+P00021015
+P0002-10-15T10:30:20
+P0002-10-15
-P00021015T103020 // -2 years, -10 months, -15 days, -10 hours, -30 minutes, -20 seconds
-P00021015
-P0002-10-15T10:30:20
-P0002-10-15
P+00021015T103020
P0002-1015
P0002--10-15T10:+30:20 // 2 years, -10 month, 15 days, 10 hours, 30 minutes, 20 seconds
P0002-10--15 // 2 years, 10 months, -15 days
-P0002-10--15 // -2 years, -10 months, --15 days = 15 days
`
Note
The time designator is mandatory when denoting times, so P1H would be _invalid_ while PT1H would be fine.
##### Binding depended
Each parser may provide its own parsing-from-string mechanism using [....]-notation.
Example
[ {"years": 1, "quarters"": 3, "milliseconds": 27} ] + luxon-bindings - uses luxon.Duration.fromObject
#### Interval
An interval expresses the duration between a start- and an end-date. It can be understood as a box for two dates and the duration in between. Hence an interval can be constructed by providing a start- and an end-date, or a start-date and a duration (end-date = start-date + duration), or an end-date and a duration (start-date = end-date - duration).
Intervals may be written as Iso-intervals. The three options are:
- Iso-Date-Time/Iso-Date-Time
- Iso-Date-Time/Iso-Duration
- Iso-Duration/Iso-Date-Time
Iso-Date-Time and Iso-Duration use the same parsing mechanisms described above and hence allow the notations outlined above.
Examples
`
2009-12T12:34/20090519 143922+0600
P1Y2M3DT4H05M600S/2009-12T12:34
2009-12T12:34/P1Y2M3DT4H05M600S
`
For more examples, combine any date-time example with another date-time-example or any duration-example.
Note
Not all bindings support intervals!
##### Binding depended
Each parser may provide its own parsing-from-string mechanism using ~....~-notation.
Example
~2007-03-01T13:00:00Z/P1Y2M10DT2H30M~ + luxon-bindings - uses luxon.Interval.fromISO
#### Unitless
You may enter "bare" numbers, such as 2. They are treated as such. This might be useful for scalar operations such as 2 * 2d (= 4 d).
Examples
`
1
0
100
-10
-5
0
-09
1 + 1 // 2
10 + 15 - 25 // 0
3 * 5 // 15
3d * -1 // -3d
88 / 11 // 8
1 / 2 // 0.5
2.5 * 2 // 5
2d * 5 // 10d
7 - 8 // -1
`
Warning
Longer number are going to be interpreted as Iso-dates and thus might fail parsing!
If you need to use numbers with more digits than 3, consider using interpolation instead.
`
2000 // 2000-01-01T00:00:00
${2000} // 'number' 2000
`
#### Custom / Existing values
Use interpolation to insert custom type:
`
calculator${any_thing_here}
`
This allows you to use your existing Date/luxon-Date-Times/moments/luxon-Intervals/... directly in the calculator.
The bindings define what custom types are supported!
That means, if you interpolate a datefnsCalculator with a luxon-Date-Time it will likely throw an error, as date-fns can't make sense of the luxon-object.
Examples
`
import DateTime from 'luxon/src/datetime.js';
luxonCalculator${DateTime.fromSQL(...)} + ${{ hours: 3, minutes: 13 }}
`
`
import moment from 'moment';
momentCalculator${moment()} + ${moment.duration(2, 'seconds');}
`
$3
#### Add ("plus", "+")
Adds two "things". The binding implementation defines what "add" means and if it has a meaning at all!
Example
1d + 1h
| Binding | Type a | Type b | Result | Notes |
| ------------ | -------- | -------- | --------------- | --------------------------------- |
| simple | Date | Date | Error | |
| simple | Date | Duration | Timestamp (Int) | Loses accuracy due to conversion |
| simple | Duration | Date | Timestamp (Int) | Loses accuracy due to conversion |
| simple | Duration | Duration | Duration | |
| simple | Unitless | Unitless | Unitless | |
| simple | Unitless | \* | Error | |
| simple | any | any | any | Cast to date/duration; else error |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| date-fns | Date | Date | Error | |
| date-fns | Date | Duration | Date | |
| date-fns | Duration | Date | Date | |
| date-fns | Duration | Duration | Duration | |
| date-fns | Unitless | Unitless | Unitless | |
| date-fns | \ | \ | Error | |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| luxon | Date | Date | Error | |
| luxon | Date | Duration | Date | |
| luxon | Date | Interval | Date | Date + Duration(Interval) |
| luxon | Duration | Date | Date | |
| luxon | Duration | Duration | Duration | |
| luxon | Duration | Interval | Interval | Shifts interval by duration |
| luxon | Interval | Date | Interval | Interval extended to Date |
| luxon | Interval | Duration | Interval | Shifts interval by duration |
| luxon | Interval | Interval | Interval | Union of intervals |
| luxon | Unitless | Unitless | Unitless | |
| luxon | \ | \ | Error | |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| simple-luxon | Date | Date | Error | |
| simple-luxon | Date | Duration | Date | |
| simple-luxon | Duration | Date | Date | |
| simple-luxon | Duration | Duration | Duration | |
| simple-luxon | Unitless | Unitless | Unitless | |
| simple-luxon | \ | \ | Error | |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| moment | Date | Date | Error | |
| moment | Date | Duration | Date | |
| moment | Duration | Date | Date | |
| moment | Duration | Duration | Duration | |
| moment | Unitless | Unitless | Unitless | |
| moment | \ | \ | Error | |
#### Subtract ("minus", "-")
Subtracts two "things" - binding defines the meaning. Can also be interpreted as a "until", as in "2019 - 2020" yielding an interval between those in some implementations.
Example
1d - 5h
| Binding | Type a | Type b | Result | Notes |
| ------------ | -------- | -------- | --------------- | ------------------------------------- |
| simple | Date | Date | Number | Difference of times in milliseconds |
| simple | Date | Duration | Timestamp (Int) | Loses accuracy due to conversion |
| simple | Duration | Date | Timestamp (Int) | Same as Date - Duration |
| simple | Duration | Duration | Duration | |
| simple | Unitless | Unitless | Unitless | |
| simple | \ | \ | \* | Cast to date/duration; else error |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| date-fns | Date | Date | Duration | Difference between the two dates |
| date-fns | Date | Duration | Date | |
| date-fns | Duration | Date | Date | Same as Date - Duration |
| date-fns | Duration | Duration | Duration | |
| date-fns | Unitless | Unitless | Unitless | |
| date-fns | \ | \ | Error | |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| luxon | Date | Date | Interval | Interval(start: Date a, end: Date b) |
| luxon | Date | Duration | Date | Puts date into the past by duration |
| luxon | Date | Interval | Date | Date - Duration(Interval) |
| luxon | Duration | Date | Date | Same as Date - Duration |
| luxon | Duration | Duration | Duration | |
| luxon | Duration | Interval | Interval | Same as Interval - Duration |
| luxon | Interval | Date | Interval | Limits Interval by Date |
| luxon | Interval | Duration | Interval | Shifts interval by duration |
| luxon | Interval | Interval | Interval | Intersection or Interval between both |
| luxon | Unitless | Unitless | Unitless | |
| luxon | \ | \ | Error | |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| simple-luxon | Date | Date | Error | |
| simple-luxon | Date | Duration | Date | |
| simple-luxon | Duration | Date | Error | |
| simple-luxon | Duration | Duration | Duration | |
| simple-luxon | Unitless | Unitless | Unitless | |
| simple-luxon | \ | \ | Error | |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| moment | Date | Date | Error | |
| moment | Date | Duration | Date | |
| moment | Duration | Date | Error | |
| moment | Duration | Duration | Duration | |
| moment | Unitless | Unitless | Unitless | |
| moment | \ | \ | Error | |
#### Multiply ("\*")
Example
5d * 3
| Binding | Type a | Type b | Result | Notes |
| ------------ | -------- | -------- | --------------- | -------------------------------- |
| simple | Duration | Unitless | Duration | |
| simple | Unitless | Duration | Duration | |
| simple | Unitless | Unitless | Unitless | |
| simple | \ | \ | Error | |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| date-fns | Duration | Unitless | Duration | |
| date-fns | Unitless | Duration | Duration | |
| date-fns | Unitless | Unitless | Unitless | |
| date-fns | \ | \ | Error | |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| luxon | Unitless | Interval | Interval | Shifts Interval.start back |
| luxon | Interval | Unitless | Interval | Shifts Interval.start forward |
| luxon | Duration | Unitless | Duration | |
| luxon | Unitless | Duration | Duration | |
| luxon | Unitless | Unitless | Unitless | |
| luxon | \ | \ | Error | |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| simple-luxon | Duration | Unitless | Duration | |
| simple-luxon | Unitless | Duration | Duration | |
| simple-luxon | Unitless | Unitless | Unitless | |
| simple-luxon | \ | \ | Error | |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| moment | Duration | Unitless | Duration | |
| moment | Unitless | Duration | Duration | |
| moment | Unitless | Unitless | Unitless | |
| moment | \ | \ | Error | |
#### Divide ("/")
Divide things Split "things" into n equal parts.
| Binding | Type a | Type b | Result | Notes |
| ------------ | -------- | -------- | --------------- | -------------------------------------------- |
| simple | Duration | Unitless | Duration | |
| simple | Unitless | Unitless | Unitless | |
| simple | \ | \ | Error | |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| date-fns | Duration | Unitless | Duration | |
| date-fns | Unitless | Duration | Duration | Inverts each duration part |
| date-fns | Duration | Duration | Unitless | Loses accuracy due to conversion |
| date-fns | Unitless | Unitless | Unitless | |
| date-fns | \ | \ | Error | |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| luxon | Date | Date | Interval | Interval(start: Date a, end: Date b) |
| luxon | Interval | Unitless | Duration | Duration c fits Unitless times into Interval |
| luxon | Interval | Duration | Unitless | Duration b fits Unitless times into Interval |
| luxon | Interval | Unitless | Duration | |
| luxon | Duration | Duration | Unitless | Loses accuracy due to conversion |
| luxon | Duration | Unitless | Duration | |
| luxon | Unitless | Duration | Duration | Inverts each duration part |
| luxon | Interval | 1u | Interval | Swops the interval (start->end, end->start) |
| luxon | Unitless | Unitless | Unitless | |
| luxon | \ | \ | Error | |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| simple-luxon | Duration | Unitless | Duration | |
| simple-luxon | Unitless | Unitless | Unitless | |
| simple-luxon | \ | \ | Error | |
| ------- | -------- | -------- | --------------- | -------------------------------- |
| moment | Duration | Unitless | Duration | |
| moment | Unitless | Unitless | Unitless | |
| moment | \ | \ | Error | |
$3
Additionally ( + ) is permitted to group any expression and give its evaluation priority. Nesting is allowed. (Or expressed differently: (...) works as you would expect!)
Example
( 1d - 5h ) * 2
On top there is the keywords "now" (alias "today", both case-insensitive), which creates a Date-Time with the value of "now".
$3
| Priority | Expression | Example |
| -------- | ------------------ | ---------------------------------- |
| 1 | Interval | 2009-12T12:34/20090519 143922+0600 |
| 2 | now, today | now, now(), Today |
| 2 | Custom Constructor | {....}, [....], \~....\~ |
| 2 | Duration | P1D |
| 2 | Date-Time | 2019 |
| 2 | Duration shorthand | 1 day |
| 3 | Unitless | 1 |
| 4 | Brackets | ( .... ) |
| 5 | Multiply | .. \* .. |
| 5 | Divide | .. / .. |
| 6 | Plus | .. + .. |
| 6 | Minus | .. - .. |
This order insures that 2019/P1D is an interval while 2019 / P1D means "divide 2019 by P1D".
It also care to interpret 2019-08 as "August of 2019", while 2019 - 08 means "The date 2019 minus unitless 8".
Bring your own lib date-lib
The date-calculator itself is not bound to any library. You can 'teach' it to work with any library by implementing 'bindings'. To create a new calculator type import the calculatorFactory (aka "parser") and call it with your bindings (see below).
`
import calculatorFactory from "./calcdate";
const yourCalculator = calculatorFactory({
makeDate: ...,
makeDuration: ...,
makeInterval: ...,
add: ...,
subtract: ...,
multiply: ...,
divide: ...
});
`
You will need to implement the following methods:
$3
You function to create a new date. It can take the following two signatures:
- makeDate(date: Native_Date, { type: calculatorFactory.NATIVEDATE }) : YourDateType
- makeDate(date: any, { type: calculatorFactory.DATEXPRESION }) : YourDateType, created by calculator{any_string}
$3
- makeDuration({ milliseconds, seconds, minutes, hours, days, weekdays, weeks, months, years } : { milliseoncds: Number?, seconds: Number?, minutes: Number?, hours: Number?, days: Number?, weekdays: Number?, weeks: Number?, months: Number?, years: Number? }, { type: calculatorFactory.DURATIONOBJECT }) : YourDurationType
- makeDuration(duration: any, { type: calculatorFactory.DURATIONEXPRESSION }) : YourDurationType, created by calculator[any_string]
$3
- makeInterval([from: YourDateType, to: YourDateType], { type: calculatorFactory.INTERVALOBJECT }) : YourIntervalType
- makeInterval([from: YourDateType, to: YourDurationType], { type: calculatorFactory.INTERVALOBJECT }) : YourIntervalType
- makeInterval([from: YourDurationType, to: YourDateType], { type: calculatorFactory.INTERVALOBJECT }) : YourIntervalType
- makeInterval(interval: any, { type: calculatorFactory.DURATIONEXPRESSION }) : INTERVALEXPRESION, created by calculator~any_string~
$3
add(a, b) : c, where a, b, c are YourDateType | YourDurationType | YourIntervalType | { unitless: Number } | any
Examples
- now + 1 day - add(a: YourDateType, b: YourDurationType)
- now + 1 - add(a: YourDateType, { unitless: 1 } : { unitless: Number })
- P3Y6M4DT12H30M5S + 1 day - add(a: YourDurationType, b: YourDurationType)
- 2019-01-01/2019-01-02 + now - add(a: YourIntervalType, b: YourDateType)
- ${new RegExp("foobar")} + ~hello world~ - add(a: any, b: YourIntervalType)
- 1d + 1h + 1m - add(add(a: YourDurationType, b: YourDurationType), x: YourDurationType)
Note
You should throw (helpful) errors when you can't make sense of the arguments. For example adding up two duration makes sense - adding up two dates might not! The same applies for all the operations!
$3
subtract(a, b) : c, where a, b, c are YourDateType | YourDurationType | YourIntervalType | { unitless: Number } | any
- now - 1 day - subtract(a: YourDateType, b: YourDurationType)
- now - 1 - subtract(a: YourDateType, { unitless: 1 } : { unitless: Number })
- P3Y6M4DT12H30M5S - 1 day - subtract(a: YourDurationType, b: YourDurationType)
- 2019-01-01/2019-01-02 - now - subtract(a: YourIntervalType, b: YourDateType)
- ${new RegExp("foobar")} - ~hello world~ - subtract(a: any, b: YourIntervalType)
- 1d - 1h - 1m - subtract(add(a: YourDurationType, b: YourDurationType), x: YourDurationType)
Note
You should throw (helpful) errors when you can't make sense of the arguments. For example substracting a duration from a date makes sense - substracting a date from a duration might not!
$3
multiply(a, b) : c, where a, b, c are YourDateType | YourDurationType | YourIntervalType | { unitless: Number } | any
- now * 1 day - multiply(a: YourDateType, b: YourDurationType)
- now * 1 - multiply(a: YourDateType, { unitless: 1 } : { unitless: Number })
- P3Y6M4DT12H30M5S * 1 day - multiply(a: YourDurationType, b: YourDurationType)
- 2019-01-01/2019-01-02 * now - multiply(a: YourIntervalType, b: YourDateType)
- ${new RegExp("foobar")} * ~hello world~ - multiply(a: any, b: YourIntervalType)
- 1d 1h 1m - multiply(add(a: YourDurationType, b: YourDurationType), x: YourDurationType)
Note
You should throw (helpful) errors when you can't make sense of the arguments. For example multiplying a duration by a unitless makes sense - multiplying a duration by another might not!
$3
divide(a, b) : c, where a, b, c are YourDateType | YourDurationType | YourIntervalType | { unitless: Number } | any
- now / 1 day - divide(a: YourDateType, b: YourDurationType)
- now / 1 - divide(a: YourDateType, { unitless: 1 } : { unitless: Number })
- P3Y6M4DT12H30M5S / 1 day - divide(a: YourDurationType, b: YourDurationType)
- 2019-01-01/2019-01-02 / now - divide(a: YourIntervalType, b: YourDateType)
- ${new RegExp("foobar")} / ~hello world~ - divide(a: any, b: YourIntervalType)
- 1d / 1h / 1m - divide(add(a: YourDurationType, b: YourDurationType), x: YourDurationType)`