Skip to content

Commit 49567bc

Browse files
committed
Extracted from hour module
0 parents  commit 49567bc

File tree

6 files changed

+246
-0
lines changed

6 files changed

+246
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

.npmignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/source

package.json

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "@datatypes/duration",
3+
"version": "0.1.0",
4+
"description": "Full ISO 8601 compatible duration class",
5+
"main": "build/index.js",
6+
"directories": {
7+
"test": "test"
8+
},
9+
"scripts": {
10+
"build": "babel --quiet --presets es2015 source --out-dir build",
11+
"test": "npm run build && ava --fail-fast",
12+
"prepublish": "npm test"
13+
},
14+
"keywords": [
15+
"duration",
16+
"iso 8601",
17+
"date"
18+
],
19+
"author": "Adrian Sieber",
20+
"devDependencies": {
21+
"ava": "^0.12.0",
22+
"babel-cli": "^6.6.5",
23+
"babel-preset-es2015": "^6.6.0",
24+
"unexpected": "^10.4.0"
25+
},
26+
"repository": {
27+
"type": "git",
28+
"url": "git+https://github.com/datatypes/duration.git"
29+
},
30+
"bugs": {
31+
"url": "https://github.com/datatypes/duration/issues"
32+
},
33+
"homepage": "https://github.com/datatypes/duration#readme",
34+
"dependencies": {},
35+
"license": "ISC"
36+
}

source/fragments.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
'use strict'
2+
3+
export default [
4+
'years',
5+
'months',
6+
'weeks',
7+
'days',
8+
'hours',
9+
'minutes',
10+
'seconds',
11+
'milliseconds'
12+
]

source/index.js

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import durationFragments from './fragments'
2+
3+
export default class Duration {
4+
constructor (durationString) {
5+
let durationPattern =
6+
'P' +
7+
'(?:(\\d+)Y)?' + // Years
8+
'(?:(\\d+)M)?' + // Months
9+
'(?:(\\d+)W)?' + // Weeks
10+
'(?:(\\d+)D)?' + // Days
11+
'T?' +
12+
'(?:(\\d+)H)?' + // Hours
13+
'(?:(\\d+)M)?' + // Minutes
14+
'(?:(\\d+)?' + // Seconds
15+
'\\.?(\\d+)?S)?' // Milliseconds
16+
17+
let regex = new RegExp(durationPattern, 'i')
18+
let durationArray = durationString.match(regex)
19+
20+
durationFragments.forEach((fragment, index) => {
21+
let value = Number(durationArray[index + 1])
22+
if (value)
23+
this[fragment] = value
24+
})
25+
}
26+
27+
get string () {
28+
return durationFragments
29+
.reduce(
30+
(string, fragment) => {
31+
if (this[fragment] == null) {
32+
return string
33+
}
34+
35+
if (fragment === 'minutes' && !string.includes('t')) {
36+
string += 't'
37+
}
38+
39+
string += this[fragment] + fragment.substr(0, 1)
40+
41+
if (fragment === 'days') {
42+
string += 't'
43+
}
44+
if (fragment === 'milliseconds') {
45+
string.replace('s', '.' + this[fragment] + 's')
46+
}
47+
48+
return string
49+
},
50+
'p'
51+
)
52+
.replace(/t$/, '')
53+
.toUpperCase()
54+
}
55+
56+
toString () {
57+
return this.string
58+
}
59+
60+
toObject () {
61+
return durationFragments.reduce(
62+
(object, fragment) => {
63+
if (this[fragment] != null)
64+
object[fragment] = this[fragment]
65+
return object
66+
},
67+
{
68+
string: this.string
69+
}
70+
)
71+
}
72+
73+
toJSON () {
74+
return this.toObject()
75+
}
76+
}

test/main.js

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import runTest from 'ava'
2+
import expect from 'unexpected'
3+
import Duration from '../build/index.js'
4+
5+
runTest('P7Y', test => {
6+
expect(
7+
new Duration(test.title).toObject(),
8+
'to equal',
9+
{
10+
string: test.title,
11+
years: 7,
12+
}
13+
)
14+
})
15+
16+
runTest('P7M', test => {
17+
expect(
18+
new Duration(test.title).toObject(),
19+
'to equal',
20+
{
21+
string: test.title,
22+
months: 7,
23+
}
24+
)
25+
})
26+
27+
runTest('P7W', test => {
28+
expect(
29+
new Duration(test.title).toObject(),
30+
'to equal',
31+
{
32+
string: test.title,
33+
weeks: 7,
34+
}
35+
)
36+
})
37+
38+
runTest('P7D', test => {
39+
expect(
40+
new Duration(test.title).toObject(),
41+
'to equal',
42+
{
43+
string: test.title,
44+
days: 7,
45+
}
46+
)
47+
})
48+
49+
runTest('P7H', test => {
50+
expect(
51+
new Duration(test.title).toObject(),
52+
'to equal',
53+
{
54+
string: test.title,
55+
hours: 7,
56+
}
57+
)
58+
})
59+
60+
runTest('PT7M', test => {
61+
expect(
62+
new Duration(test.title).toObject(),
63+
'to equal',
64+
{
65+
string: test.title,
66+
minutes: 7,
67+
}
68+
)
69+
})
70+
71+
runTest('P7S', test => {
72+
expect(
73+
new Duration(test.title).toObject(),
74+
'to equal',
75+
{
76+
string: test.title,
77+
seconds: 7,
78+
}
79+
)
80+
})
81+
82+
runTest('P7.345S', test => {
83+
expect(
84+
new Duration(test.title).toObject(),
85+
'to equal',
86+
{
87+
string: 'P7S345M',
88+
seconds: 7,
89+
milliseconds: 345,
90+
}
91+
)
92+
})
93+
94+
runTest('P7Y5M', test => {
95+
expect(
96+
new Duration(test.title).toObject(),
97+
'to equal',
98+
{
99+
string: test.title,
100+
years: 7,
101+
months: 5
102+
}
103+
)
104+
})
105+
106+
runTest('P3Y6M4DT12H30M5S', test => {
107+
expect(
108+
new Duration(test.title).toObject(),
109+
'to equal',
110+
{
111+
string: test.title,
112+
years: 3,
113+
months: 6,
114+
days: 4,
115+
hours: 12,
116+
minutes: 30,
117+
seconds: 5,
118+
}
119+
)
120+
})

0 commit comments

Comments
 (0)