forked from opencollective/opencollective-frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdate-utils.js
147 lines (133 loc) · 4.29 KB
/
date-utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import { padStart } from 'lodash';
import INTERVALS from './constants/intervals';
import dayjs from './dayjs';
/**
* For a given date, return the next charge date.
*
* @param {Date} firstChargeDate
* @param {month|year} interval
*/
export const getNextChargeDate = (firstChargeDate, interval) => {
if (interval === INTERVALS.month) {
if (firstChargeDate.getDate() > 15) {
return new Date(firstChargeDate.getFullYear(), firstChargeDate.getMonth() + 2);
}
return new Date(firstChargeDate.getFullYear(), firstChargeDate.getMonth() + 1);
} else if (interval === INTERVALS.year) {
return new Date(firstChargeDate.getFullYear() + 1, firstChargeDate.getMonth());
} else {
return null;
}
};
/**
* Format a datetime object to an ISO date like `YYYY-MM-DD`
*/
export const toIsoDateStr = date => {
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getUTCDate();
return `${year}-${padStart(month.toString(), 2, '0')}-${padStart(day.toString(), 2, '0')}`;
};
/**
* From an order frequency provided as `ContributionFrequency` GQLV2 enum, returns an interval
* as we use it in the DB (ie. MONTHLY => month)
*/
export const getIntervalFromContributionFrequency = input => {
switch (input) {
case 'MONTHLY':
return INTERVALS.month;
case 'YEARLY':
return INTERVALS.year;
default:
return null;
}
};
/**
* Takes a date and returns it as a string in the format YYYY-MM-DD
*/
export const stripTime = date => {
if (!date) {
return '';
} else {
return dayjs(date).format('YYYY-MM-DD');
}
};
/**
* A helper that returns a Date object from different types of input.
* Currently supports:
* - string: ISO date string
* - Date object
* - DayJS object
* - null
*/
export const getDateFromValue = value => {
if (!value) {
return null;
} else if (typeof value === 'string') {
return new Date(value);
} else if (value instanceof Date) {
return value;
} else if (value instanceof dayjs) {
return value.toDate();
}
};
/**
* From a simple date as '2020-01-01', returns a string like '2020-01-01T00:00:00Z'.
*/
export const simpleDateToISOString = (date, isEndOfDay, timezoneType) => {
if (!date) {
return null;
} else {
const isUTC = timezoneType === 'UTC';
const dayjsTimeMethod = isEndOfDay ? 'endOf' : 'startOf';
const result = isUTC ? dayjs.utc(date) : dayjs(date);
return result[dayjsTimeMethod]('day').toISOString();
}
};
/**
* Parse `strValue` in a "dateFrom→dateTo" format and returns an object like { from, to, timezoneType }.
* Each value in the object will be `undefined` if there's no filter for it.
*/
export const parseDateInterval = strValue => {
const parsedValue = strValue?.match(/^(?<from>[^→]+)(→(?<to>.+?(?=~UTC|$)))?(~(?<timezoneType>UTC))?$/);
if (parsedValue) {
const getDateIsoString = dateStr => (!dateStr || dateStr === 'all' ? undefined : dateStr);
return {
from: getDateIsoString(parsedValue.groups.from),
to: getDateIsoString(parsedValue.groups.to),
timezoneType: parsedValue.groups.timezoneType || 'local',
};
} else {
return { from: undefined, to: undefined, timezoneType: 'local' };
}
};
/**
* Opposite of `parseDateInterval`: takes an object like {from, to, timezoneType} and returns a string
* like "from→to".
*/
export const encodeDateInterval = interval => {
if (!interval || (!interval.from && !interval.to)) {
return '';
}
const encodeDate = (date, isEndOfDay) => {
return simpleDateToISOString(date, isEndOfDay, interval.timezoneType) || 'all';
};
const baseResult = `${encodeDate(interval.from, false)}→${encodeDate(interval.to, true)}`;
return interval.timezoneType === 'UTC' ? `${baseResult}~UTC` : baseResult;
};
export const convertDateToApiUtc = (date, timezone) => {
const result = dayjs.tz(date, timezone).utc().format('YYYY-MM-DD HH:mm:ss+00');
// console.log('convertDateToApiUtc', date, timezone, result);
return result;
};
export const convertDateFromApiUtc = (date, timezone) => {
const result = dayjs(date).tz(timezone).format('YYYY-MM-DD HH:mm:ss');
// console.log('convertDateFromApiUtc', date, timezone, result);
return result;
};
/**
* Check if the date is valid while editing
*/
export const isValidDate = date => {
return date && !date.startsWith('0');
};