Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

edtf

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

edtf - npm Package Compare versions

Comparing version 0.1.0 to 1.0.0

src/interface.js

28

index.js
'use strict'
const ExtDate = require('./src/date')
const Year = require('./src/year')
const Decade = require('./src/decade')
const Century = require('./src/century')
const Season = require('./src/season')
const Interval = require('./src/interval')
const List = require('./src/list')
const Set = require('./src/set')
const Bitmask = require('./src/bitmask')
const types = require('./src/types')
const { sample, gen } = require('./src/sample')
const { sample } = require('./src/sample')
const { parse } = require('./src/parser')
const { assign, keys } = Object
function edtf(...args) {
if (!args.length)
return new ExtDate()
return new edtf.Date()
if (args.length === 1 && typeof args[0] === 'object')
return new (edtf[args[0].type] || ExtDate)(args[0])
return new (edtf[args[0].type] || edtf.Date)(args[0])

@@ -30,16 +23,7 @@ const res = parse(...args)

module.exports = Object.assign(edtf, {
Date: ExtDate,
Year,
Decade,
Century,
Season,
Interval,
List,
Set,
module.exports = assign(edtf, types, {
Bitmask,
parse,
sample,
gen,
types
types: keys(types)
})
{
"name": "edtf",
"version": "0.1.0",
"version": "1.0.0",
"description": "Extended Date Time Format (EDTF) / ISO 8601-2 Parser and Library",

@@ -36,3 +36,3 @@ "main": "index.js",

"dependencies": {
"nearley": "^2.4.1",
"nearley": "^2.5.0",
"randexp": "^0.4.2"

@@ -42,3 +42,3 @@ },

"chai": "^3.5.0",
"eslint": "^2.9.0",
"eslint": "^2.10.2",
"istanbul": "^0.4.3",

@@ -45,0 +45,0 @@ "mocha": "^2.4.5"

@@ -15,25 +15,258 @@ # EDTF.js

EDTF.js fully implements [EDTF](http://www.loc.gov/standards/datetime)
levels 0, 1, and 2 as specified by WD 2016-02-16 of ISO 8601-2.
levels 0, 1, and 2 as specified by WD 2016-02-16 of ISO 8601-2 with
the following exceptions (as raised by the EDTF community):
1. Symbols for unknown and open dates in intervals have been switched:
`*` makes more sense to represent an open date because it is often
used as a wildcard to match "all" or "everything". Also, when an
interval is blank, it suggessts "incomplete" or "unknown".
2. "Before or after" is redundant and has been removed. It is covered
by "One of a Set", e.g., `[1760-12..]` which means "December 1760
or some later month".
### ES6
EDTF.js is written in ES6 and therefore requires Node.js 6+ or a modern
browser. For Node.js 4/5 use the appropriate `--harmony` flags as necessary.
## Installation
### Node.js
$ npm install edtf
EDTF.js is written in ES6 and therefore requires Node.js 6+. You should
be able to use it in Node 4 or 5 when setting the appropriate
`--harmony` flags or by using your favourite transpiler.
### Browser
EDTF.js was written for Node.js. While we don't currently provide a
browser package, it should be easily possible to create one using
browserify or similar tools.
## Manual
## Parser
EDTF.js exports a top-level function which takes either a string
(with optional parser constraints), a parse result, a regular or any
of the extended date objects and returns a new, extended date object
as appropriate.
## Generator
const edtf = require('edtf')
## API
edtf('2016-XX') #-> returns an edtf.Date
edtf(new Date()) #-> returns an edtf.Date
edtf('2016-04~/2016-05') #-> returns an edtf.Interval
For a list of all types supported by EDTF.js see:
edtf.types
#-> ['Date', 'Year', 'Decade', 'Century', 'Season', 'Interval', 'List', 'Set']
Each type provides at least the following properties: the date's
corresponding EDTF string, its minimal and maximal numeric value,
its type, as well as its date part values.
edtf('2016?').edtf #-> '2016?'
edtf('2016-02').min #-> 1454284800000, i.e. 2016-02-01T00:00:00Z
edtf('2016-02').max #-> 1456790399999, i.e. 2016-02-29T23:59:59Z
edtf('2016-02-2X').min #-> 1455926400000, i.e. 2016-02-20T00:00:00Z
edtf('2016-02-2X').max #-> 1456790399999, i.e. 2016-02-29T23:59:59Z
edtf('[..2016,2017]').min #-> -Infinity
edtf('[..2016,2017]').max #-> 1514764799999, i.e. 2017-12-31T23:59:59Z
edtf('2016-34').min #-> 1459468800000, i.e. 2016-04-01T00:00:00Z
edtf('2016-34').max #-> 1467331199999, i.e. 2016-06-30T23:59:59Z
edtf('2016?-02').values #-> [2016, 1]
edtf('2016-05').values #-> [2016, 4]
A date's `min` value is also used as its primitive value for numeric
coercion. Because this is the case for all EDTF.js classes, comparison
semantics tend to align well with common-sense expectations -- but be
careful, as always when type coercion is at play.
### Unspecified, uncertain, and approximate dates
EDTF.js keeps track of qualified dates using bitmasks. If you are interested
in binary yes or no, you can always convert a bitmask's value to boolean. For
more fine-grained information, the `edtf.Bitmask` class provides a convenient
interface for accessing these states:
edtf('2016-05?').uncertain.value #-> 63 / yes
edtf('2016-05?').approximate.value #-> 0 / no
edtf('2016-05?').uncertain.is('year') #-> 15 / yes
edtf('2016-05?').uncertain.is('month') #-> 48 / yes
edtf('2016-05?').uncertain.is('day') #-> 0 / no
edtf('2016-?05').uncertain.is('year') #-> 0 / no
edtf('2016-?05').uncertain.is('month') #-> 48 / yes
edtf('201X-XX').unspecified.value #-> 56 / yes
edtf('201X-XX').unspecified.is('year') #-> 8 / yes
edtf('201X-XX').unspecified.is('month') #-> 48 / yes
edtf('201X-XX').unspecified.is('day') #-> 0 / no
Instead of `year`, `month`, and `day`, you can also query a string-based
representation of the bitmask:
edtf('201X-XX').unspecified.test('XXYYMMDD') #-> 0 / no
edtf('201X-XX').unspecified.test('YYYXMMDD') #-> 8 / yes
When printing qualified dates, EDTF.js will try to find an optimal
rendtition of qualification symbols. For that reason, you can use EDTF.js
to normalize EDTF strings:
edtf('?2016-?05-31').edtf #-> 2016-05?-31
edtf('?2016-?05~-31').edtf #-> 2016-05%-31
Because every extended date object has a `min` and `max` value, you can
always test if one date covers another one:
edtf('2016-06/2016-09').covers(edtf('2016-08-24')) #-> true
edtf('2016-06/2016-09').covers(edtf('2016-05-31')) #-> false
Iteratable dates offer an `includes()` test as well which returns true
only if a given date is part of the iteration. For example:
edtf('2016-06/2016-09').includes(edtf('2016-08-24')) #-> false
August 24, 2016 is covered by the interval '2016-06/2016-09' but is not
included in it, because the interval has month precision and can be
iterated as:
[...edtf('2016-06/2016-09')]
#-> [2016-06, 2016-07, 2016-08, 2016-09]
### Enumerating dates
EDTF.js dates offer iterators to help measure the duration between
two dates. These iterators are dependent on a date's precision:
edtf('2016').next() #-> 2017
edtf('2016-05').next() #-> 2016-06
edtf('2016-02-28').next() #-> 2016-02-29
edtf('2017-02-28').next() #-> 2017-03-01
Careful, if your date has no precision, next will return the next
second!
The generator `*between()` returns all the dates, by precision,
between two dates; similarly, `*until()` returns all datesi in between
and includes the two dates themselves.
[...edtf('2016-05').between('2016-07')]
#-> [2016-06]
[...edtf('2016-05').until('2016-07')]
#-> [2016-05, 2016-06, 2016-07]
### Iterators
The EDTF.js classes `Date`, `Interval`, `List`, and `Set` (lists model
EDTF's 'multiple dates', while sets model 'one of a set') are iterable.
Date's are iterable.
[...edtf('2015/2018')]
#-> [2015, 2016, 2017, 2018]
Note that this also works with varying precisions:
[...edtf('2015-10/2016')]
#-> [2015-10, 2015-11, 2015-12, 2016-01, 2016-02, 2016]
Consecutive dates in lists and sets are expanded during an iteration:
[...edtf('{2015,2018..2020}')]
#-> [2015, 2018, 2019, 2020]
### Parser
To use EDTF.js' date parser directly, call `edtf.parse()` with an input
string and optional parser constraints. The parser will always return
plain JavaScript objects which you can pass to `edtf()` for conversion
to extended date object, or to your own post-processing.
edtf.parse('2016-02')
#-> { type: 'Date', level: 0, values: [2016, 1] }
As you can see, the parser output includes the compatibility level of
the date parsed; the values array contains the individual date parts
in a format compatible with JavaScript's Date semantics (months are
a zero-based index).
Unspecified, uncertain, or approximate dates are returned as a numeric
value representing a bitmask; refer to the `edtf.Bitmask` class for details.
edtf.parse('2016?-~02')
#-> { type: 'Date', level: 2, values: [2016, 1], uncertain: 15, approximate: 48 }
edtf.parse('20XX-02')
#-> { type: 'Date', level: 2, values: [2000, 1], unspecified: 12 }
Note that unspecified date values will always the least possible value,
e.g., '2000' for '20XX'. Note, also, that EDTF.js will not parse impossible
unspecified dates. For instance, none of the following examples can be
valid dates:
edtf.parse('2016-02-3X') #-> A day in February cannot start with a 3
edtf.parse('2016-2X-XX') #-> There are only 12 months
edtf.parse('2016-XX-32') #-> No month has 32 days
Intervals, Sets, and Lists will contain their parsed constiutent dates in
the values array:
edtf.parse('2015/2016')
#-> { type: 'Interval', level: 0, values: [{..}, {..}] }
By passing `level` or `types` constraints to the parser, you can ensure
EDTF.js will accept only dates supported by your application.
edtf.parse('2016?', { level: 0 }) #-> parse error
edtf.parse('2016?', { level: 1 }) #-> ok
edtf.parse('2016?-02', { level: 1 }) #-> parse error
edtf.parse('2016?-02', { level: 2 }) #-> ok
edtf.parse('2016-21', { types: ['Date'] }) #-> parse error
edtf.parse('2016-21', { types: ['Date', 'Season'] }) #-> ok
edtf.parse('2016?', { level: 0, types: ['Date'] }) #-> parse error
edtf.parse('2016?', { level: 1, types: ['Date'] }) #-> ok
### Generator
EDTF.js can generate random EDTF strings for you. Simply call
`edtf.sample()` to create a new iterator:
let it = edtf.sample()
it.next() #-> { value: '0097-26', done: false }
it.next() #-> { value: '0000-09-30T22:50:54-07', done: false }
...
For a finite iterator, simply pass a count:
[...edtf.sample({ count: 3 }]
#-> ['-003%', '-0070-07-31%', '[-0080-10..]']
You can also generate strings at a given compatibility level:
[...edtf.sample({ count: 3, level: 0 }]
#-> ['0305/0070-04-30', '-07', '0000/0013']
[...edtf.sample({ count: 3, level: 1 }]
#-> ['00XX', 'Y80105', '0000~']
[...edtf.sample({ count: 3, level: 2 }]
#-> ['Y1E30', '-8110S2', '{%0401}']
Note that some grammar rules at levels 1 and 2 may, potentially,
generate strings at a lower level (but never higher).
Finally, at each level you can also limit the generated strings
to a given type (you must specify a level for this to work):
[...edtf.sample({ count: 3, level: 2, type: 'Decade' }]
#-> ['003', '030~', '000']
## Credits

@@ -47,3 +280,2 @@ The EDTF.js parser is based on the awesome

## License
AGPL-3.0
'use strict'
const assert = require('assert')
const { parse } = require('./parser')
const ExtDate = require('./date')
const ExtDateTime = require('./interface')
const { abs, floor } = Math

@@ -9,12 +10,6 @@

class Century {
static parse(input) {
return parse(input, { types: ['Century'] })
}
class Century extends ExtDateTime {
constructor(input) {
super()
static from(input) {
return (input instanceof Century) ? input : new Century(input)
}
constructor(input) {
V.set(this, [])

@@ -60,6 +55,2 @@

get type() {
return 'Century'
}
get century() {

@@ -87,12 +78,8 @@ return this.values[0]

get edtf() {
return this.toEDTF()
}
get min() {
return Date.UTC(this.year, 0)
return ExtDate.UTC(this.year, 0)
}
get max() {
return Date.UTC(this.year + 99, 11, 31, 24, 0, 0)
return ExtDate.UTC(this.year + 100, 0) - 1
}

@@ -99,0 +86,0 @@

@@ -6,3 +6,5 @@ 'use strict'

const Bitmask = require('./bitmask')
const { parse } = require('./parser')
const ExtDateTime = require('./interface')
const mixin = require('./mixin')
const { abs } = Math

@@ -16,13 +18,5 @@ const { isArray } = Array

const PM = [Bitmask.YMD, Bitmask.Y, Bitmask.YM, Bitmask.YMD]
class ExtDate extends Date {
static parse(input) {
return parse(input, { types: ['Date'] })
}
static from(input) {
return (input instanceof ExtDate) ? input : new ExtDate(input)
}
class Date extends global.Date {
constructor(...args) { // eslint-disable-line complexity

@@ -42,3 +36,3 @@ let precision = 0

case 'string':
args = [ExtDate.parse(args[0])]
args = [Date.parse(args[0])]
// eslint-disable-line no-fallthrough

@@ -72,8 +66,3 @@

args = [Date.UTC(...args)]
// ECMA Date constructor converts 0-99 to 1900-1999!
if (obj.values[0] >= 0 && obj.values[0] < 100)
args[0] = adj(new Date(args[0]))
args = [ExtDateTime.UTC(...args)]
}

@@ -114,3 +103,3 @@

set uncertain(value) {
U.set(this, new Bitmask(value))
U.set(this, this.bits(value))
}

@@ -123,3 +112,3 @@

set approximate(value) {
A.set(this, new Bitmask(value))
A.set(this, this.bits(value))
}

@@ -139,15 +128,14 @@

get type() {
return 'Date'
}
get min() {
// TODO uncertain and approximate
get edtf() {
return this.toEDTF()
}
get min() {
return this.getTime()
}
get max() { // todo
get max() {
// TODO unspecified
// TODO uncertain and approximate
if (this.precision) return this.next() - 1
return this.getTime()

@@ -195,9 +183,14 @@ }

/**
* Returns the next second, day, month, or year, depending on
* the current date's precision. Uncertain, approximate and
* unspecified masks are copied.
*/
next(k = 1) {
let { values, unspecified, uncertain, approximate } = this
values = values.slice(0, 3)
// values = values.slice(0, 3)
values.push(values.pop() + k)
return new ExtDate({ values, unspecified, uncertain, approximate })
return new Date({ values, unspecified, uncertain, approximate })
}

@@ -219,10 +212,12 @@

*between(then) {
then = Date.from(then)
let cur = this
let dir = this.compare(then)
if (!dir) return
for (;;) {
cur = cur.next(-dir)
dir = cur.compare(then)
if (!dir) break
if (cur.compare(then) !== dir) break
yield cur

@@ -232,12 +227,9 @@ }

compare(other) {
let [a, x, b, y] = [this.min, this.max, other.min, other.max]
*[Symbol.iterator]() {
let cur = this
if (a !== b)
return a < b ? -1 : 1
if (x !== y)
return x < y ? -1 : 1
return 0
while (cur <= this.max) {
yield cur
cur = cur.next()
}
}

@@ -248,3 +240,3 @@

let values = this.values.map(ExtDate.pad)
let values = this.values.map(Date.pad)

@@ -265,6 +257,2 @@ if (this.unspecified.value)

[Symbol.toPrimitive](hint) {
return (hint === 'number') ? this.valueOf() : this.toISOString()
}
static pad(number, idx = 0) { // idx 0 = year, 1 = month, ...

@@ -287,11 +275,12 @@ if (!idx) {

bits(value) {
if (value === true)
value = PM[this.precision]
return new Bitmask(value)
}
}
ExtDate.prototype.toJSON = ExtDate.prototype.toEDTF
mixin(Date, ExtDateTime)
function adj(date, by = 1900) {
date.setUTCFullYear(date.getUTCFullYear() - by)
return date.getTime()
}
module.exports = ExtDate
module.exports = Date
'use strict'
const assert = require('assert')
const { parse } = require('./parser')
const ExtDate = require('./date')
const ExtDateTime = require('./interface')
const { abs, floor } = Math

@@ -10,12 +11,6 @@

class Decade {
static parse(input) {
return parse(input, { types: ['Decade'] })
}
class Decade extends ExtDateTime {
constructor(input) {
super()
static from(input) {
return (input instanceof Decade) ? input : new Decade(input)
}
constructor(input) {
V.set(this, [])

@@ -61,6 +56,2 @@

get type() {
return 'Decade'
}
get decade() {

@@ -88,12 +79,8 @@ return this.values[0]

get edtf() {
return this.toEDTF()
}
get min() {
return Date.UTC(this.year, 0)
return ExtDate.UTC(this.year, 0)
}
get max() {
return Date.UTC(this.year + 9, 11, 31, 24, 0, 0)
return ExtDate.UTC(this.year + 10, 0) - 1
}

@@ -100,0 +87,0 @@

'use strict'
const assert = require('assert')
const { parse } = require('./parser')
const ExtDate = require('./date')
const ExtDateTime = require('./interface')

@@ -9,12 +10,6 @@ const V = new WeakMap()

class Interval {
static parse(input) {
return parse(input, { types: ['Interval'] })
}
class Interval extends ExtDateTime {
constructor(...args) {
super()
static from(input) {
return (input instanceof Interval) ? input : new Interval(input)
}
constructor(...args) {
V.set(this, [null, null])

@@ -47,2 +42,5 @@

;[this.lower, this.upper] = obj.values
this.earlier = obj.earlier
this.later = obj.later
}

@@ -64,7 +62,2 @@ break

get type() {
return 'Interval'
}
get lower() {

@@ -75,3 +68,14 @@ return this.values[0]

set lower(value) {
this.values[0] = value // todo
if (value == null)
return this.values[1] = null
if (value === Infinity || value === -Infinity)
return this.values[1] = Infinity
value = ExtDate.from(value)
if (value >= this.upper && this.upper != null)
throw new RangeError(`invalid lower bound: ${value}`)
this.values[0] = value
}

@@ -84,25 +88,38 @@

set upper(value) {
this.values[1] = value // todo
}
if (value == null)
return this.values[1] = null
get values() {
return V.get(this)
if (value === Infinity)
return this.values[1] = Infinity
value = ExtDate.from(value)
if (value <= this.lower)
throw new RangeError(`invalid upper bound: ${value}`)
this.values[1] = value
}
get earlier() {
get finite() {
return (this.lower != null && this.lower !== Infinity) &&
(this.upper != null && this.upper !== Infinity)
}
get later() {
*[Symbol.iterator]() {
if (!this.finite) throw Error('cannot iterate infinite interval')
yield* this.lower.until(this.upper)
}
get edtf() {
return this.toEDTF()
get values() {
return V.get(this)
}
get min() {
return this.lower.min
let v = this.lower
return !v ? null : (v === Infinity) ? -Infinity : v.min
}
get max() {
return this.upper.max
let v = this.upper
return !v ? null : (v === Infinity) ? Infinity : v.max
}

@@ -109,0 +126,0 @@

'use strict'
const assert = require('assert')
const ExtDate = require('./date')
const { parse } = require('./parser')
const Date = require('./date')
const ExtDateTime = require('./interface')
const { isArray } = Array

@@ -11,12 +11,6 @@

class List {
static parse(input) {
return parse(input, { types: ['List'] })
}
class List extends ExtDateTime {
constructor(...args) {
super()
static from(input) {
return (input instanceof this) ? input : new this(input)
}
constructor(...args) {
V.set(this, [])

@@ -29,3 +23,3 @@

case 'string':
args[0] = this.parse(args[0])
args[0] = new.target.parse(args[0])
// eslint-disable-line no-fallthrough

@@ -54,6 +48,2 @@

get type() {
return 'List'
}
get values() {

@@ -93,6 +83,6 @@ return V.get(this)

assert.equal(2, value.length)
return this.values.push(value.map(ExtDate.from))
return this.values.push(value.map(v => Date.from(v)))
}
return this.values.push(ExtDate.from(value))
return this.values.push(Date.from(value))
}

@@ -109,6 +99,2 @@

get edtf() {
return this.toEDTF()
}
get min() {

@@ -115,0 +101,0 @@ return this.empty ? 0 : this.first.min

@@ -11,4 +11,6 @@ /*

const randexp = require('randexp')
const types = Object.keys(require('./types'))
const { ParserRules: Rules } = require('./grammar')
const types = require('./types')
const { floor, random } = Math

@@ -30,3 +32,3 @@ const NAMES = [

*sample({ count, level, type }) {
*sample({ count, level, type } = {}) {
let name = 'edtf'

@@ -66,3 +68,3 @@

let sample = rules[
Math.floor(Math.random() * rules.length)
floor(random() * rules.length)
]

@@ -89,4 +91,6 @@

return output.join('')
return output
.join('')
.replace(/ +/g, '') // filter excessive whitespace
}
}
'use strict'
const assert = require('assert')
const { parse } = require('./parser')
const ExtDateTime = require('./interface')
const { pad } = require('./date')

@@ -9,12 +9,6 @@

class Season {
static parse(input) {
return parse(input, { types: ['Season'] })
}
class Season extends ExtDateTime {
constructor(input) {
super()
static from(input) {
return (input instanceof Season) ? input : new Season(input)
}
constructor(input) {
V.set(this, [])

@@ -58,6 +52,2 @@

get type() {
return 'Season'
}
get year() {

@@ -83,12 +73,82 @@ return this.values[0]

get edtf() {
return this.toEDTF()
}
// TODO next/prev
get min() {
return Date.UTC(this.year, 0)
get min() { // eslint-disable-line complexity
switch (this.season) {
case 21:
case 25:
case 32:
case 33:
case 40:
case 37:
return ExtDateTime.UTC(this.year, 0)
case 22:
case 26:
case 31:
case 34:
return ExtDateTime.UTC(this.year, 3)
case 23:
case 27:
case 30:
case 35:
case 41:
return ExtDateTime.UTC(this.year, 6)
case 24:
case 28:
case 29:
case 36:
return ExtDateTime.UTC(this.year, 9)
case 38:
return ExtDateTime.UTC(this.year, 4)
case 39:
return ExtDateTime.UTC(this.year, 8)
default:
return ExtDateTime.UTC(this.year, 0)
}
}
get max() {
return Date.UTC(this.year, 11, 31, 24, 0, 0)
get max() { // eslint-disable-line complexity
switch (this.season) {
case 21:
case 25:
case 32:
case 33:
return ExtDateTime.UTC(this.year, 3) - 1
case 22:
case 26:
case 31:
case 34:
case 40:
return ExtDateTime.UTC(this.year, 6) - 1
case 23:
case 27:
case 30:
case 35:
return ExtDateTime.UTC(this.year, 9) - 1
case 24:
case 28:
case 29:
case 36:
case 41:
case 39:
return ExtDateTime.UTC(this.year + 1, 0) - 1
case 37:
return ExtDateTime.UTC(this.year, 5) - 1
case 38:
return ExtDateTime.UTC(this.year, 9) - 1
default:
return ExtDateTime.UTC(this.year + 1, 0) - 1
}
}

@@ -95,0 +155,0 @@

'use strict'
module.exports = [
'Date', 'Year', 'Season', 'Interval', 'Set', 'List', 'Century', 'Decade'
]
module.exports = {
Date: require('./date'),
Year: require('./year'),
Decade: require('./decade'),
Century: require('./century'),
Season: require('./season'),
Interval: require('./interval'),
List: require('./list'),
Set: require('./set')
}
'use strict'
const assert = require('assert')
const { parse } = require('./parser')
const { pad } = require('./date')
const ExtDate = require('./date')
const ExtDateTime = require('./interface')
const { pad } = ExtDate
const { abs } = Math

@@ -11,8 +12,6 @@

class Year {
static parse(input) {
return parse(input, { types: ['Year'] })
}
class Year extends ExtDateTime {
constructor(input) {
super()
constructor(input) {
V.set(this, [])

@@ -54,6 +53,2 @@

get type() {
return 'Year'
}
get year() {

@@ -79,12 +74,8 @@ return this.values[0]

get edtf() {
return this.toEDTF()
}
get min() {
return Date.UTC(this.year, 0)
return ExtDateTime.UTC(this.year, 0)
}
get max() {
return Date.UTC(this.year, 11, 31, 24, 0, 0)
return ExtDateTime.UTC(this.year + 1, 0) - 1
}

@@ -91,0 +82,0 @@

@@ -26,2 +26,14 @@ 'use strict'

})
describe('bounds', () => {
it('min', () => {
expect(new Century(20).min)
.to.eql(Date.UTC(2000, 0, 1, 0, 0, 0, 0))
})
it('max', () => {
expect(new Century(20).max)
.to.eql(Date.UTC(2099, 11, 31, 23, 59, 59, 999))
})
})
})

@@ -7,2 +7,11 @@ 'use strict'

it('.type', () => {
expect(Date.type).to.eql('Date')
expect(new Date().type).to.eql('Date')
})
it('.from()', () => {
expect(Date.from('2016')).to.be.instanceof(Date)
})
describe('constructor()', () => {

@@ -95,2 +104,28 @@ it('Date', () =>

describe('max', () => {
it('full precision', () => {
let date = new Date()
expect(date.max).to.eql(date.min)
})
it('YYYY', () => {
expect(new Date([2016]).max)
.to.eql(global.Date.UTC(2016, 11, 31, 23, 59, 59, 999))
})
it('YYYY-MM', () => {
expect(new Date([2016, 1]).max)
.to.eql(global.Date.UTC(2016, 1, 29, 23, 59, 59, 999))
expect(new Date([2017, 1]).max)
.to.eql(global.Date.UTC(2017, 1, 28, 23, 59, 59, 999))
expect(new Date([2016, 7]).max)
.to.eql(global.Date.UTC(2016, 7, 31, 23, 59, 59, 999))
})
it('YYYY-MM-DD', () => {
expect(new Date([2016, 1, 1]).max)
.to.eql(global.Date.UTC(2016, 1, 1, 23, 59, 59, 999))
})
})
describe('.edtf', () => {

@@ -97,0 +132,0 @@ it('default', () =>

@@ -7,2 +7,14 @@ 'use strict'

describe('bounds', () => {
it('min', () => {
expect(new Decade(199).min)
.to.eql(Date.UTC(1990, 0, 1, 0, 0, 0, 0))
})
it('max', () => {
expect(new Decade(199).max)
.to.eql(Date.UTC(1999, 11, 31, 23, 59, 59, 999))
})
})
describe('.edtf', () => {

@@ -9,0 +21,0 @@ it('default', () =>

@@ -33,2 +33,10 @@ 'use strict'

})
it('roundtrips', () => {
for (let string of [
'2016', '2016-05', '2016-05-31', '2016?', '2016-05?',
'2016-05-31?', '2016~-05?', '2016-~05'
]) expect(edtf(string).edtf).to.eql(string)
})
})
'use strict'
const { Interval } = require('..')
const { Interval, Date } = require('..')
describe('Interval', () => {
it('.type', () => {
expect(Interval.type).to.eql('Interval')
expect(new Interval().type).to.eql('Interval')
})
it('.from()', () => {
expect(Interval.from('2016/2017')).to.be.instanceof(Interval)
})
describe('bounds', () => {
it('min', () => {
expect(new Interval([2001], [2003]).min)
.to.eql(Date.UTC(2001, 0, 1, 0, 0, 0, 0))
})
it('max', () => {
expect(new Interval([2001], [2003]).max)
.to.eql(Date.UTC(2003, 11, 31, 23, 59, 59, 999))
})
})
describe('invalid', () => {
it('bounds', () => {
expect(() => new Interval([2001], [2000])).to.throw(RangeError)
})
})
describe('iteration', () => {
const Q1_94 = new Interval([1994, 0], [1994, 2])
const FEB_94 = new Date(1994, 1)
const FEB1_94 = new Date(1994, 1, 1)
const YEAR_94 = new Date([1994])
it('@@iterator', () => {
expect([...new Interval([2001], [2003])].map(v => v.edtf))
.to.eql(['2001', '2002', '2003'])
expect([...Q1_94].map(v => v.edtf))
.to.eql(['1994-01', '1994-02', '1994-03'])
})
it('covers', () => {
expect(Q1_94.covers(FEB_94)).to.be.true
expect(Q1_94.covers(FEB1_94)).to.be.true
expect(Q1_94.covers(YEAR_94)).not.to.be.true
})
it('includes', () => {
expect(Q1_94.includes(FEB_94)).to.be.true
expect(Q1_94.includes(FEB1_94)).not.to.be.true
expect(Q1_94.includes(YEAR_94)).not.to.be.true
})
})
describe('.edtf', () => {

@@ -8,0 +62,0 @@ it('default', () =>

@@ -546,3 +546,8 @@ 'use strict'

})
describe('rejects', () => {
it('empty string', () => expect(() => p('')).to.be.rejected)
it('-', () => expect(() => p('-')).to.be.rejected)
})
})
'use strict'
const { gen, sample, parse: p } = require('..')
const { sample, parse: p } = require('..')

@@ -8,9 +8,5 @@ describe('sample', () => {

it('iterator', () => {
expect(Array.from(sample({ count: 5 }))).to.have.length(5)
expect([...sample({ count: 5 })]).to.have.length(5)
})
it('dates', () => {
expect(p(gen('date'))).to.have.type('Date')
})
describe('constraints', () => {

@@ -17,0 +13,0 @@ it('level 0', () =>

@@ -7,2 +7,18 @@ 'use strict'

describe('bounds', () => {
it('min', () => {
expect(new Season(2016, 33).min)
.to.eql(Date.UTC(2016, 0, 1, 0, 0, 0, 0))
expect(new Season(2016, 34).min)
.to.eql(Date.UTC(2016, 3, 1, 0, 0, 0, 0))
})
it('max', () => {
expect(new Season(2016, 33).max)
.to.eql(Date.UTC(2016, 2, 31, 23, 59, 59, 999))
expect(new Season(2016, 34).max)
.to.eql(Date.UTC(2016, 5, 30, 23, 59, 59, 999))
})
})
describe('.edtf', () => {

@@ -9,0 +25,0 @@ it('default', () =>

@@ -7,2 +7,11 @@ 'use strict'

it('type', () => {
expect(Set.type).to.eql('Set')
expect(new Set().type).to.eql('Set')
})
it('.from()', () => {
expect(Set.from('[2016]')).to.be.instanceof(Set)
})
describe('.edtf', () => {

@@ -9,0 +18,0 @@ it('default', () =>

@@ -7,2 +7,23 @@ 'use strict'

it('type', () => {
expect(Year.type).to.eql('Year')
expect(new Year().type).to.eql('Year')
})
it('.from()', () => {
expect(Year.from('Y22016')).to.be.instanceof(Year)
})
describe('bounds', () => {
it('min', () => {
expect(new Year(-1).min)
.to.eql(Date.UTC(-1, 0, 1, 0, 0, 0, 0))
})
it('max', () => {
expect(new Year(-1).max)
.to.eql(Date.UTC(-1, 11, 31, 23, 59, 59, 999))
})
})
describe('.edtf', () => {

@@ -9,0 +30,0 @@ it('default', () =>

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc