1 | import _ from 'lodash';
|
2 | import { CraftAiTimeError } from './errors';
|
3 | import moment from 'moment';
|
4 | import isTimezone, { timezones } from './timezones';
|
5 |
|
6 |
|
7 | const OFFSET_REGEX = /Z|[+-]\d\d:?\d\d/gi;
|
8 |
|
9 | export function tzFromOffset(offset) {
|
10 | if (_.isInteger(offset)) {
|
11 | const sign = offset >= 0 ? '+' : '-';
|
12 | const abs = Math.abs(offset);
|
13 |
|
14 |
|
15 | if (abs < 16)
|
16 | return `${sign}${_.padStart(abs, 2, '0')}:00`;
|
17 | return `${sign}${_.padStart(Math.floor(abs / 60), 2, '0')}:${_.padStart(abs % 60, 2, '0')}`;
|
18 | }
|
19 | else {
|
20 | return offset;
|
21 | }
|
22 | }
|
23 |
|
24 | export default function Time(t = undefined, tz = undefined) {
|
25 |
|
26 | if (!(this instanceof Time)) {
|
27 | return new Time(t, tz);
|
28 | }
|
29 |
|
30 | let m;
|
31 | if (t instanceof Time) {
|
32 |
|
33 | m = moment.unix(t.timestamp);
|
34 | m.utcOffset(t.timezone);
|
35 | }
|
36 | else if (t instanceof moment) {
|
37 |
|
38 | m = t;
|
39 | }
|
40 | else if (_.isDate(t)) {
|
41 |
|
42 | m = moment(t);
|
43 | }
|
44 | else if (_.isNumber(t)) {
|
45 |
|
46 |
|
47 | m = moment.unix(t);
|
48 | }
|
49 | else if (_.isString(t)) {
|
50 |
|
51 | if (t.match(OFFSET_REGEX)) {
|
52 |
|
53 | m = moment.parseZone(t, moment.ISO_8601);
|
54 | }
|
55 | else {
|
56 |
|
57 | m = moment(t, moment.ISO_8601);
|
58 | }
|
59 | }
|
60 | else if (_.isUndefined(t)) {
|
61 | m = moment();
|
62 | }
|
63 |
|
64 | if (m === undefined || !m.isValid()) {
|
65 | throw new CraftAiTimeError(`Time error, given "${t}" is invalid.`);
|
66 | }
|
67 |
|
68 | if (tz) {
|
69 |
|
70 | if (!isTimezone(tz)) {
|
71 | throw new CraftAiTimeError(`Time error, the given timezone "${tz}" is invalid.
|
72 | Please refer to the client's documentation to see accepted formats:
|
73 | https://beta.craft.ai/doc/http#context-properties-types.`);
|
74 | }
|
75 | m.utcOffset(timezones[tz] || tz);
|
76 | }
|
77 |
|
78 | const minuteOffset = m.utcOffset();
|
79 |
|
80 | return _.extend(this, {
|
81 | timestamp: m.unix(),
|
82 | timezone: tzFromOffset(minuteOffset),
|
83 | time_of_day: m.hour() + m.minute() / 60 + m.second() / 3600,
|
84 | day_of_month: m.date(),
|
85 | month_of_year: m.month() + 1,
|
86 | day_of_week: m.isoWeekday() - 1,
|
87 | utc: m.toISOString()
|
88 | });
|
89 | }
|