Skip to content

Improving date utils #2610

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 18 additions & 15 deletions src/incubator/Calendar/Day.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {Colors} from 'style';
import View from '../../components/view';
import TouchableOpacity from '../../components/touchableOpacity';
import Text from '../../components/text';
import {getDayOfDate, isSameDay, isToday} from './helpers/DateUtils';
import {getDateObject, isSameDay, isToday} from './helpers/DateUtils';
import {DayProps, UpdateSource} from './types';
import CalendarContext from './CalendarContext';

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

const Day = (props: DayProps) => {
const {date, onPress, inactive} = props;
const {date, onPress, currentMonth} = props;
const {selectedDate, setDate, showExtraDays} = useContext(CalendarContext);


const dateObject = useMemo(() => {
return !isNull(date) && getDateObject(date);
}, [date]);
const day = dateObject ? dateObject.day : '';

const isSelected = useSharedValue(!isNull(date) ? isSameDay(selectedDate.value, date) : false);
const inactive = useMemo(() => { // inactive have different look but is still pressable
if (dateObject) {
const dayMonth = dateObject.month;
return dayMonth !== currentMonth;
}
}, [dateObject, currentMonth]);
const isHidden = !showExtraDays && inactive;

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

const animatedTextStyles = useAnimatedStyle(() => {
return {
color: withTiming(isSelected.value ?
SELECTED_TEXT_COLOR : textColor, {duration: 100})
color: withTiming(isSelected.value ? SELECTED_TEXT_COLOR : textColor, {duration: 100})
};
});

Expand All @@ -68,20 +78,13 @@ const Day = (props: DayProps) => {
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [date, setDate, onPress]);

const renderDay = () => {
const day = !isNull(date) ? getDayOfDate(date) : '';
return (

return (
<TouchableOpacity flex center style={styles.dayContainer} onPress={_onPress} activeOpacity={1}>
<View center>
<View reanimated style={selectionStyle}/>
<AnimatedText style={animatedTextStyles}>{day}</AnimatedText>
</View>
);
};

return (
<TouchableOpacity flex center style={styles.dayContainer} onPress={_onPress} activeOpacity={1}>
{renderDay()}
</TouchableOpacity>
);
};
Expand Down
18 changes: 10 additions & 8 deletions src/incubator/Calendar/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Reanimated, {useAnimatedProps} from 'react-native-reanimated';
import {Colors, Typography} from 'style';
import View from '../../components/view';
import Button from '../../components/button';
import {getDateObject, getMonthForIndex, addMonths, getTimestamp} from './helpers/DateUtils';
import {getDateObject, getMonthForIndex, addMonths} from './helpers/DateUtils';
import {HeaderProps, DayNamesFormat, UpdateSource} from './types';
import CalendarContext from './CalendarContext';
import WeekDaysNames from './WeekDaysNames';
Expand All @@ -21,9 +21,7 @@ const Header = (props: HeaderProps) => {
const {selectedDate, setDate, showWeeksNumbers, staticHeader, setHeaderHeight} = useContext(CalendarContext);

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

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

const animatedProps = useAnimatedProps(() => {
const dateObject = getDateObject(selectedDate.value);
const monthString = getMonthForIndex(staticHeader ? dateObject.month : month!);
const dateString = staticHeader ? monthString + ` ${dateObject.year}` : monthString + ` ${year}`;
let m = month!;
let y = year;
if (staticHeader) {
const dateObject = getDateObject(selectedDate.value);
m = dateObject.month;
y = dateObject.year;
}
return {
text: dateString
text: getMonthForIndex(m) + ` ${y}`
};
});

Expand Down
2 changes: 1 addition & 1 deletion src/incubator/Calendar/TodayButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {/* Animated, */ useAnimatedStyle /* , useSharedValue */} from 'react-na
import {Colors} from '../../style';
import View from '../../components/view';
import Button from '../../components/button';
import {isSameDay /*, isToday, isPastDate*/} from './helpers/DateUtils';
import {isSameDay /*, isPastDate*/} from './helpers/DateUtils';
import {TodayButtonProps, UpdateSource} from './types';
import CalendarContext from './CalendarContext';

Expand Down
12 changes: 3 additions & 9 deletions src/incubator/Calendar/Week.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import _ from 'lodash';
import React, {useContext, useMemo, useCallback} from 'react';
import React, {useContext, useMemo} from 'react';
import {StyleSheet} from 'react-native';
import View from '../../components/view';
import Text from '../../components/text';
import {getDaysOfWeekNumber, getDateObject} from './helpers/DateUtils';
import {getDaysOfWeekNumber} from './helpers/DateUtils';
import {WeekProps} from './types';
import CalendarContext from './CalendarContext';
import Day from './Day';
Expand All @@ -13,7 +13,6 @@ const WEEK_NUMBER_WIDTH = 20;

const Week = (props: WeekProps) => {
const {weekNumber, year, month} = props;

const {firstDayOfWeek, showWeeksNumbers} = useContext(CalendarContext);

const days = useMemo(() => {
Expand All @@ -26,16 +25,11 @@ const Week = (props: WeekProps) => {
}
};

const isExtraDay = useCallback((day: number) => {
const dayMonth = getDateObject(day).month;
return dayMonth !== month;
}, [month]);

return (
<View row>
{renderWeekNumbers()}
{_.map(days, day => (
<Day key={day} date={day} inactive={isExtraDay(day)}/>
<Day key={day} date={day} currentMonth={month}/>
))}
</View>
);
Expand Down
52 changes: 21 additions & 31 deletions src/incubator/Calendar/__tests__/DateUtils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,23 @@ describe('Calendar/DateUtils', () => {
const dayObject = DateUtils.getDateObject(firstDayInTheYear);
expect(dayObject.day).toBe(28);
expect(dayObject.month).toBe(11);
expect(DateUtils.getDayOfTheWeek(firstDayInTheYear)).toBe(6);
expect(dayObject.dayOfTheWeek).toBe(6);
});

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

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

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

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

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

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

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

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

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

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

it('2023 When Monday is first day of the week - should return Monday Dec 26th', () => {
const firstDayInTheYear = DateUtils._forTesting.getFirstDayInTheYear(2023, FirstDayOfWeek.MONDAY);
const dayObject = DateUtils.getDateObject(firstDayInTheYear);
expect(dayObject.day).toBe(26);
expect(dayObject.month).toBe(11);
expect(DateUtils.getDayOfTheWeek(firstDayInTheYear)).toBe(1);
expect(dayObject.dayOfTheWeek).toBe(1);
});
});
});
Expand Down Expand Up @@ -187,25 +187,6 @@ describe('Calendar/DateUtils', () => {
});
});

describe('getDayOfDate', () => {
it('should return the day number from the date timestamp', () => {
const day = DateUtils.getDayOfDate(new Date(2022, 11, 26).getTime());
expect(day).toBe(26);
});
});

describe('getDayOfTheWeek', () => {
it('should return the day of week (Sunday = 0) from the date timestamp', () => {
const day = DateUtils.getDayOfTheWeek(new Date(2023, 1, 5).getTime());
expect(day).toBe(0);
});
it('should return the day of week (Friday = 5) from the date timestamp', () => {
const day = DateUtils.getDayOfTheWeek(new Date(2023, 1, 3).getTime());
expect(day).toBe(5);
});
});


describe('addMonths', () => {
it('should return the date timestamp for the next (1) months in the next (1) years', () => {
const date = DateUtils.addMonths(new Date(2022, 11, 26).getTime(), 1);
Expand Down Expand Up @@ -271,6 +252,15 @@ describe('Calendar/DateUtils', () => {
expect(dayObject.month).toBe(11);
expect(dayObject.year).toBe(2020);
});

// useFirstDay
it('should return the date timestamp for the 1st day of the next (1) months in the next (1) years', () => {
const date = DateUtils.addMonths(new Date(2022, 11, 26).getTime(), 1, true);
const dayObject = DateUtils.getDateObject(date);
expect(dayObject.day).toBe(1);
expect(dayObject.month).toBe(0);
expect(dayObject.year).toBe(2023);
});
});

describe('addYears', () => {
Expand Down
Loading