Skip to content

Commit 96f714a

Browse files
authored
Improving date utils (#2610)
* Improving date utils * replacing function * revert function change * Moving 'inactive' day logic from Week to Day * Header - addMonths - improve flow * Header - convert to dateObject only for staticHeader * pr comments
1 parent fc7711e commit 96f714a

File tree

8 files changed

+101
-105
lines changed

8 files changed

+101
-105
lines changed

src/incubator/Calendar/Day.tsx

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {Colors} from 'style';
66
import View from '../../components/view';
77
import TouchableOpacity from '../../components/touchableOpacity';
88
import Text from '../../components/text';
9-
import {getDayOfDate, isSameDay, isToday} from './helpers/DateUtils';
9+
import {getDateObject, isSameDay, isToday} from './helpers/DateUtils';
1010
import {DayProps, UpdateSource} from './types';
1111
import CalendarContext from './CalendarContext';
1212

@@ -24,10 +24,21 @@ const INACTIVE_TEXT_COLOR = Colors.$textNeutralLight;
2424
const AnimatedText = Reanimated.createAnimatedComponent(Text);
2525

2626
const Day = (props: DayProps) => {
27-
const {date, onPress, inactive} = props;
27+
const {date, onPress, currentMonth} = props;
2828
const {selectedDate, setDate, showExtraDays} = useContext(CalendarContext);
29-
29+
30+
const dateObject = useMemo(() => {
31+
return !isNull(date) && getDateObject(date);
32+
}, [date]);
33+
const day = dateObject ? dateObject.day : '';
34+
3035
const isSelected = useSharedValue(!isNull(date) ? isSameDay(selectedDate.value, date) : false);
36+
const inactive = useMemo(() => { // inactive have different look but is still pressable
37+
if (dateObject) {
38+
const dayMonth = dateObject.month;
39+
return dayMonth !== currentMonth;
40+
}
41+
}, [dateObject, currentMonth]);
3142
const isHidden = !showExtraDays && inactive;
3243

3344
const backgroundColor = useMemo(() => {
@@ -45,8 +56,7 @@ const Day = (props: DayProps) => {
4556

4657
const animatedTextStyles = useAnimatedStyle(() => {
4758
return {
48-
color: withTiming(isSelected.value ?
49-
SELECTED_TEXT_COLOR : textColor, {duration: 100})
59+
color: withTiming(isSelected.value ? SELECTED_TEXT_COLOR : textColor, {duration: 100})
5060
};
5161
});
5262

@@ -68,20 +78,13 @@ const Day = (props: DayProps) => {
6878
}
6979
// eslint-disable-next-line react-hooks/exhaustive-deps
7080
}, [date, setDate, onPress]);
71-
72-
const renderDay = () => {
73-
const day = !isNull(date) ? getDayOfDate(date) : '';
74-
return (
81+
82+
return (
83+
<TouchableOpacity flex center style={styles.dayContainer} onPress={_onPress} activeOpacity={1}>
7584
<View center>
7685
<View reanimated style={selectionStyle}/>
7786
<AnimatedText style={animatedTextStyles}>{day}</AnimatedText>
7887
</View>
79-
);
80-
};
81-
82-
return (
83-
<TouchableOpacity flex center style={styles.dayContainer} onPress={_onPress} activeOpacity={1}>
84-
{renderDay()}
8588
</TouchableOpacity>
8689
);
8790
};

src/incubator/Calendar/Header.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Reanimated, {useAnimatedProps} from 'react-native-reanimated';
44
import {Colors, Typography} from 'style';
55
import View from '../../components/view';
66
import Button from '../../components/button';
7-
import {getDateObject, getMonthForIndex, addMonths, getTimestamp} from './helpers/DateUtils';
7+
import {getDateObject, getMonthForIndex, addMonths} from './helpers/DateUtils';
88
import {HeaderProps, DayNamesFormat, UpdateSource} from './types';
99
import CalendarContext from './CalendarContext';
1010
import WeekDaysNames from './WeekDaysNames';
@@ -21,9 +21,7 @@ const Header = (props: HeaderProps) => {
2121
const {selectedDate, setDate, showWeeksNumbers, staticHeader, setHeaderHeight} = useContext(CalendarContext);
2222

2323
const getNewDate = useCallback((count: number) => {
24-
const newDate = addMonths(selectedDate.value, count);
25-
const dateObject = getDateObject(newDate);
26-
return getTimestamp({year: dateObject.year, month: dateObject.month, day: 1});
24+
return addMonths(selectedDate.value, count, true);
2725
// eslint-disable-next-line react-hooks/exhaustive-deps
2826
}, []);
2927

@@ -36,11 +34,15 @@ const Header = (props: HeaderProps) => {
3634
}, [setDate, getNewDate]);
3735

3836
const animatedProps = useAnimatedProps(() => {
39-
const dateObject = getDateObject(selectedDate.value);
40-
const monthString = getMonthForIndex(staticHeader ? dateObject.month : month!);
41-
const dateString = staticHeader ? monthString + ` ${dateObject.year}` : monthString + ` ${year}`;
37+
let m = month!;
38+
let y = year;
39+
if (staticHeader) {
40+
const dateObject = getDateObject(selectedDate.value);
41+
m = dateObject.month;
42+
y = dateObject.year;
43+
}
4244
return {
43-
text: dateString
45+
text: getMonthForIndex(m) + ` ${y}`
4446
};
4547
});
4648

src/incubator/Calendar/TodayButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {/* Animated, */ useAnimatedStyle /* , useSharedValue */} from 'react-na
44
import {Colors} from '../../style';
55
import View from '../../components/view';
66
import Button from '../../components/button';
7-
import {isSameDay /*, isToday, isPastDate*/} from './helpers/DateUtils';
7+
import {isSameDay /*, isPastDate*/} from './helpers/DateUtils';
88
import {TodayButtonProps, UpdateSource} from './types';
99
import CalendarContext from './CalendarContext';
1010

src/incubator/Calendar/Week.tsx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import _ from 'lodash';
2-
import React, {useContext, useMemo, useCallback} from 'react';
2+
import React, {useContext, useMemo} from 'react';
33
import {StyleSheet} from 'react-native';
44
import View from '../../components/view';
55
import Text from '../../components/text';
6-
import {getDaysOfWeekNumber, getDateObject} from './helpers/DateUtils';
6+
import {getDaysOfWeekNumber} from './helpers/DateUtils';
77
import {WeekProps} from './types';
88
import CalendarContext from './CalendarContext';
99
import Day from './Day';
@@ -13,7 +13,6 @@ const WEEK_NUMBER_WIDTH = 20;
1313

1414
const Week = (props: WeekProps) => {
1515
const {weekNumber, year, month} = props;
16-
1716
const {firstDayOfWeek, showWeeksNumbers} = useContext(CalendarContext);
1817

1918
const days = useMemo(() => {
@@ -26,16 +25,11 @@ const Week = (props: WeekProps) => {
2625
}
2726
};
2827

29-
const isExtraDay = useCallback((day: number) => {
30-
const dayMonth = getDateObject(day).month;
31-
return dayMonth !== month;
32-
}, [month]);
33-
3428
return (
3529
<View row>
3630
{renderWeekNumbers()}
3731
{_.map(days, day => (
38-
<Day key={day} date={day} inactive={isExtraDay(day)}/>
32+
<Day key={day} date={day} currentMonth={month}/>
3933
))}
4034
</View>
4135
);

src/incubator/Calendar/__tests__/DateUtils.spec.ts

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -48,23 +48,23 @@ describe('Calendar/DateUtils', () => {
4848
const dayObject = DateUtils.getDateObject(firstDayInTheYear);
4949
expect(dayObject.day).toBe(28);
5050
expect(dayObject.month).toBe(11);
51-
expect(DateUtils.getDayOfTheWeek(firstDayInTheYear)).toBe(6);
51+
expect(dayObject.dayOfTheWeek).toBe(6);
5252
});
5353

5454
it('2020 When Sunday is first day of the week - should return Sunday Dec 29th', () => {
5555
const firstDayInTheYear = DateUtils._forTesting.getFirstDayInTheYear(2020, FirstDayOfWeek.SUNDAY);
5656
const dayObject = DateUtils.getDateObject(firstDayInTheYear);
5757
expect(dayObject.day).toBe(29);
5858
expect(dayObject.month).toBe(11);
59-
expect(DateUtils.getDayOfTheWeek(firstDayInTheYear)).toBe(0);
59+
expect(dayObject.dayOfTheWeek).toBe(0);
6060
});
6161

6262
it('2020 When Monday is first day of the week - should return Monday Dec 30th', () => {
6363
const firstDayInTheYear = DateUtils._forTesting.getFirstDayInTheYear(2020, FirstDayOfWeek.MONDAY);
6464
const dayObject = DateUtils.getDateObject(firstDayInTheYear);
6565
expect(dayObject.day).toBe(30);
6666
expect(dayObject.month).toBe(11);
67-
expect(DateUtils.getDayOfTheWeek(firstDayInTheYear)).toBe(1);
67+
expect(dayObject.dayOfTheWeek).toBe(1);
6868
});
6969
});
7070

@@ -74,23 +74,23 @@ describe('Calendar/DateUtils', () => {
7474
const dayObject = DateUtils.getDateObject(firstDayInTheYear);
7575
expect(dayObject.day).toBe(26);
7676
expect(dayObject.month).toBe(11);
77-
expect(DateUtils.getDayOfTheWeek(firstDayInTheYear)).toBe(6);
77+
expect(dayObject.dayOfTheWeek).toBe(6);
7878
});
7979

8080
it('2021 When Sunday is first day of the week - should return Sunday Dec 27th', () => {
8181
const firstDayInTheYear = DateUtils._forTesting.getFirstDayInTheYear(2021, FirstDayOfWeek.SUNDAY);
8282
const dayObject = DateUtils.getDateObject(firstDayInTheYear);
8383
expect(dayObject.day).toBe(27);
8484
expect(dayObject.month).toBe(11);
85-
expect(DateUtils.getDayOfTheWeek(firstDayInTheYear)).toBe(0);
85+
expect(dayObject.dayOfTheWeek).toBe(0);
8686
});
8787

8888
it('2021 When Monday is first day of the week - should return Monday Dec 28th', () => {
8989
const firstDayInTheYear = DateUtils._forTesting.getFirstDayInTheYear(2021, FirstDayOfWeek.MONDAY);
9090
const dayObject = DateUtils.getDateObject(firstDayInTheYear);
9191
expect(dayObject.day).toBe(28);
9292
expect(dayObject.month).toBe(11);
93-
expect(DateUtils.getDayOfTheWeek(firstDayInTheYear)).toBe(1);
93+
expect(dayObject.dayOfTheWeek).toBe(1);
9494
});
9595
});
9696

@@ -100,23 +100,23 @@ describe('Calendar/DateUtils', () => {
100100
const dayObject = DateUtils.getDateObject(firstDayInTheYear);
101101
expect(dayObject.day).toBe(1);
102102
expect(dayObject.month).toBe(0);
103-
expect(DateUtils.getDayOfTheWeek(firstDayInTheYear)).toBe(6);
103+
expect(dayObject.dayOfTheWeek).toBe(6);
104104
});
105105

106106
it('2022 When Sunday is first day of the week - should return Sunday Dec 26th', () => {
107107
const firstDayInTheYear = DateUtils._forTesting.getFirstDayInTheYear(2022, FirstDayOfWeek.SUNDAY);
108108
const dayObject = DateUtils.getDateObject(firstDayInTheYear);
109109
expect(dayObject.day).toBe(26);
110110
expect(dayObject.month).toBe(11);
111-
expect(DateUtils.getDayOfTheWeek(firstDayInTheYear)).toBe(0);
111+
expect(dayObject.dayOfTheWeek).toBe(0);
112112
});
113113

114114
it('2022 When Monday is first day of the week - should return Monday Dec 27th', () => {
115115
const firstDayInTheYear = DateUtils._forTesting.getFirstDayInTheYear(2022, FirstDayOfWeek.MONDAY);
116116
const dayObject = DateUtils.getDateObject(firstDayInTheYear);
117117
expect(dayObject.day).toBe(27);
118118
expect(dayObject.month).toBe(11);
119-
expect(DateUtils.getDayOfTheWeek(firstDayInTheYear)).toBe(1);
119+
expect(dayObject.dayOfTheWeek).toBe(1);
120120
});
121121
});
122122

@@ -126,23 +126,23 @@ describe('Calendar/DateUtils', () => {
126126
const dayObject = DateUtils.getDateObject(firstDayInTheYear);
127127
expect(dayObject.day).toBe(31);
128128
expect(dayObject.month).toBe(11);
129-
expect(DateUtils.getDayOfTheWeek(firstDayInTheYear)).toBe(6);
129+
expect(dayObject.dayOfTheWeek).toBe(6);
130130
});
131131

132132
it('2023 When Sunday is first day of the week - should return Sunday Jan 1st', () => {
133133
const firstDayInTheYear = DateUtils._forTesting.getFirstDayInTheYear(2023, FirstDayOfWeek.SUNDAY);
134134
const dayObject = DateUtils.getDateObject(firstDayInTheYear);
135135
expect(dayObject.day).toBe(1);
136136
expect(dayObject.month).toBe(0);
137-
expect(DateUtils.getDayOfTheWeek(firstDayInTheYear)).toBe(0);
137+
expect(dayObject.dayOfTheWeek).toBe(0);
138138
});
139139

140140
it('2023 When Monday is first day of the week - should return Monday Dec 26th', () => {
141141
const firstDayInTheYear = DateUtils._forTesting.getFirstDayInTheYear(2023, FirstDayOfWeek.MONDAY);
142142
const dayObject = DateUtils.getDateObject(firstDayInTheYear);
143143
expect(dayObject.day).toBe(26);
144144
expect(dayObject.month).toBe(11);
145-
expect(DateUtils.getDayOfTheWeek(firstDayInTheYear)).toBe(1);
145+
expect(dayObject.dayOfTheWeek).toBe(1);
146146
});
147147
});
148148
});
@@ -187,25 +187,6 @@ describe('Calendar/DateUtils', () => {
187187
});
188188
});
189189

190-
describe('getDayOfDate', () => {
191-
it('should return the day number from the date timestamp', () => {
192-
const day = DateUtils.getDayOfDate(new Date(2022, 11, 26).getTime());
193-
expect(day).toBe(26);
194-
});
195-
});
196-
197-
describe('getDayOfTheWeek', () => {
198-
it('should return the day of week (Sunday = 0) from the date timestamp', () => {
199-
const day = DateUtils.getDayOfTheWeek(new Date(2023, 1, 5).getTime());
200-
expect(day).toBe(0);
201-
});
202-
it('should return the day of week (Friday = 5) from the date timestamp', () => {
203-
const day = DateUtils.getDayOfTheWeek(new Date(2023, 1, 3).getTime());
204-
expect(day).toBe(5);
205-
});
206-
});
207-
208-
209190
describe('addMonths', () => {
210191
it('should return the date timestamp for the next (1) months in the next (1) years', () => {
211192
const date = DateUtils.addMonths(new Date(2022, 11, 26).getTime(), 1);
@@ -271,6 +252,15 @@ describe('Calendar/DateUtils', () => {
271252
expect(dayObject.month).toBe(11);
272253
expect(dayObject.year).toBe(2020);
273254
});
255+
256+
// useFirstDay
257+
it('should return the date timestamp for the 1st day of the next (1) months in the next (1) years', () => {
258+
const date = DateUtils.addMonths(new Date(2022, 11, 26).getTime(), 1, true);
259+
const dayObject = DateUtils.getDateObject(date);
260+
expect(dayObject.day).toBe(1);
261+
expect(dayObject.month).toBe(0);
262+
expect(dayObject.year).toBe(2023);
263+
});
274264
});
275265

276266
describe('addYears', () => {

0 commit comments

Comments
 (0)