3
3
addMonths as fnsAddMonths ,
4
4
endOfDay as fnsEndOfDay ,
5
5
format as fnsFormat ,
6
- formatISO as fnsFormatISO ,
7
6
getUnixTime as fnsGetUnixTime ,
8
7
isAfter as fnsIsAfter ,
9
8
isBefore as fnsIsBefore ,
@@ -13,98 +12,125 @@ import {
13
12
parseISO as fnsParseISO ,
14
13
startOfDay as fnsStartOfDay ,
15
14
} from 'date-fns' ;
15
+ import { utcToZonedTime , zonedTimeToUtc } from 'date-fns-tz' ;
16
16
import ms from 'ms' ;
17
17
18
- import { DEFAULT_FORMAT_DATE } from '@common/constants' ;
18
+ import { DEFAULT_FORMAT_DATE , TIMEZONE_UTC } from '@common/constants' ;
19
19
20
+ //TODO: should be work only with UTC time
20
21
export class DateUtil {
21
- static addMillisecondToDate ( date ?: DateCtx , amount ?: number ) : Date {
22
- return fnsAddMilliseconds ( DateUtil . transformDateToISO ( date ) , amount || 0 ) ;
23
- }
22
+ static addMillisecondToDate ( date : FlexibleDate , amount ?: number ) : Date {
23
+ const dateISO = this . parseISO ( date ) ;
24
24
25
- static addMonths ( date ?: DateCtx , amount ?: number ) : Date {
26
- return fnsAddMonths ( DateUtil . transformDateToISO ( date ) , amount || 0 ) ;
25
+ return fnsAddMilliseconds ( dateISO , amount || 0 ) ;
27
26
}
28
27
29
- static endOfDay ( date ?: DateCtx | null ) {
30
- date = DateUtil . transformDateToISO ( date || new Date ( ) ) ;
28
+ static addMonths ( date : FlexibleDate , amount ?: number ) : Date {
29
+ const dateISO = this . parseISO ( date ) ;
31
30
32
- return fnsEndOfDay ( date ) ;
31
+ return fnsAddMonths ( dateISO , amount || 0 ) ;
33
32
}
34
33
35
- static formatISO ( date ?: DateCtx ) {
36
- date = ( DateUtil . isValid ( date ) ? date : new Date ( ) ) as DateCtx ;
34
+ static endOfDay ( date : FlexibleDate ) {
35
+ const dateISO = this . parseISO ( date ) ;
37
36
38
- return fnsFormatISO ( DateUtil . parseISO ( date ) ) ;
37
+ return fnsEndOfDay ( dateISO ) ;
39
38
}
40
39
41
40
static isBetweenDay (
42
- from : DateCtx ,
43
- to ?: DateCtx | null ,
44
- date ?: DateCtx | null ,
41
+ dateFrom : FlexibleDate ,
42
+ dateTo : FlexibleDate ,
43
+ date : FlexibleDate ,
45
44
) {
46
- from = DateUtil . startOfDay ( from ) ;
47
- to = DateUtil . endOfDay ( to ) ;
48
- date = DateUtil . transformDateToISO ( date || new Date ( ) ) ;
45
+ const dateStartUtc = this . timeZoneToUTC ( this . startOfDay ( dateFrom ) ) ;
46
+ const dateEndUtc = this . timeZoneToUTC ( this . endOfDay ( dateTo ) ) ;
47
+ const dateISOUtc = this . parseISO ( date ) ;
49
48
50
49
return (
51
- ( fnsIsEqual ( from , date ) || fnsIsBefore ( from , date ) ) &&
52
- ( fnsIsEqual ( to , date ) || fnsIsAfter ( to , date ) )
50
+ ( fnsIsEqual ( dateStartUtc , dateISOUtc ) ||
51
+ fnsIsBefore ( dateStartUtc , dateISOUtc ) ) &&
52
+ ( fnsIsEqual ( dateEndUtc , dateISOUtc ) || fnsIsAfter ( dateEndUtc , dateISOUtc ) )
53
53
) ;
54
54
}
55
55
56
- static isSameDay ( dateLeft ?: DateCtx , dateRight ?: DateCtx ) : boolean {
57
- if ( DateUtil . isValid ( dateLeft ) && DateUtil . isValid ( dateRight ) ) {
58
- return fnsIsSameDay (
59
- DateUtil . parseISO ( dateLeft as DateCtx ) ,
60
- DateUtil . parseISO ( dateRight as DateCtx ) ,
61
- ) ;
56
+ static isSameDay ( dateLeft : FlexibleDate , dateRight : FlexibleDate ) : boolean {
57
+ if ( ! this . isValid ( dateLeft ) || ! this . isValid ( dateRight ) ) {
58
+ return false ;
62
59
}
63
60
64
- return false ;
61
+ return fnsIsSameDay ( this . parseISO ( dateLeft ) , this . parseISO ( dateRight ) ) ;
65
62
}
66
63
67
- static isSameOrBeforeDay ( from ?: DateCtx | null , to ?: DateCtx | null ) {
68
- from = DateUtil . startOfDay ( from || new Date ( ) ) ;
69
- to = DateUtil . startOfDay ( to || new Date ( ) ) ;
64
+ static isSameOrBeforeDay ( dateFrom : FlexibleDate , dateTo : FlexibleDate ) {
65
+ const dateStartFrom = this . startOfDay ( dateFrom ) ;
66
+ const dateStartTo = this . startOfDay ( dateTo ) ;
70
67
71
- return fnsIsEqual ( from , to ) || fnsIsBefore ( from , to ) ;
68
+ return (
69
+ fnsIsEqual ( dateStartFrom , dateStartTo ) ||
70
+ fnsIsBefore ( dateStartFrom , dateStartTo )
71
+ ) ;
72
72
}
73
73
74
- static isValid ( date ?: DateCtx ) {
75
- return fnsIsValid ( typeof date === 'string' ? Date . parse ( date ) : date ) ;
76
- }
74
+ static parseISO ( date : FlexibleDate ) {
75
+ if ( ! date || ! this . isValid ( date ) ) {
76
+ throw new Error ( 'Invalid Date' ) ;
77
+ }
77
78
78
- static parseISO ( date : DateCtx ) {
79
79
return typeof date === 'string' ? fnsParseISO ( date ) : date ;
80
80
}
81
81
82
- static startOfDay ( date ?: DateCtx | null ) {
83
- date = DateUtil . transformDateToISO ( date || new Date ( ) ) ;
82
+ static parseStringToMs ( str : string ) : number {
83
+ if ( ! str ) {
84
+ return 0 ;
85
+ }
84
86
85
- return fnsStartOfDay ( date ) ;
87
+ return ms ( str ) || 0 ;
86
88
}
87
89
88
- static toDate ( date : DateCtx ) {
89
- return DateUtil . transformDateToISO ( date ) ;
90
+ static startOfDay ( date : FlexibleDate ) {
91
+ const dateISO = this . parseISO ( date ) ;
92
+
93
+ return fnsStartOfDay ( dateISO ) ;
90
94
}
91
95
92
- // FIXME: https://github.com/date-fns/date-fns/issues/2151
93
- static toFormat ( date ?: DateCtx , format = DEFAULT_FORMAT_DATE ) {
94
- return fnsFormat ( DateUtil . transformDateToISO ( date ) , format ) ;
96
+ static timeZoneToUTC ( date : FlexibleDate , tz = TIMEZONE_UTC ) {
97
+ try {
98
+ const dateUtc = zonedTimeToUtc ( date , tz ) ;
99
+
100
+ if ( ! this . isValid ( dateUtc ) ) {
101
+ throw new Error ( ) ;
102
+ }
103
+
104
+ return dateUtc ;
105
+ } catch {
106
+ throw new Error ( 'Invalid Date' ) ;
107
+ }
95
108
}
96
109
97
- static toMs ( input : string ) : number {
98
- return ms ( input ) ;
110
+ static toFormat ( date : FlexibleDate , format = DEFAULT_FORMAT_DATE ) {
111
+ const dateISO = this . parseISO ( date ) ;
112
+
113
+ return fnsFormat ( dateISO , format ) ;
99
114
}
100
115
101
- static toUnix ( date ?: DateCtx ) : number {
102
- return fnsGetUnixTime ( DateUtil . transformDateToISO ( date ) ) ;
116
+ static toFormatUTC ( localDate : FlexibleDate , format = DEFAULT_FORMAT_DATE ) {
117
+ const dateISO = this . parseISO ( localDate ) ;
118
+ const date = utcToZonedTime ( dateISO , TIMEZONE_UTC ) ;
119
+
120
+ return fnsFormat ( date , format ) ;
103
121
}
104
122
105
- static transformDateToISO ( date ?: DateCtx ) {
106
- date = ( DateUtil . isValid ( date ) ? date : new Date ( ) ) as DateCtx ;
123
+ static toUnix ( date : FlexibleDate ) : number {
124
+ const dateISO = this . parseISO ( date ) ;
107
125
108
- return DateUtil . parseISO ( date ) ;
126
+ return fnsGetUnixTime ( dateISO ) ;
127
+ }
128
+
129
+ private static isValid ( date ?: FlexibleDate ) {
130
+ try {
131
+ return fnsIsValid ( typeof date === 'string' ? Date . parse ( date ) : date ) ;
132
+ } catch {
133
+ throw new Error ( 'Invalid Date' ) ;
134
+ }
109
135
}
110
136
}
0 commit comments