Skip to content

Commit a4ffa09

Browse files
authored
Merge pull request #38 from a-ui/bugfix/date-fns-tz
🐛 Introduced timezones to the calendar, so the correct date is always…
2 parents 3e7ce28 + 5fd8c7a commit a4ffa09

File tree

8 files changed

+57
-142
lines changed

8 files changed

+57
-142
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## 7.10.1 - 2025-09-01
9+
10+
### Fixed
11+
12+
- Introduced timezones to the calendar, so the correct date is always returned no matter which timezone you are in
13+
814
## 7.10.0 - 2025-07-24
915

1016
### Added

documentation/playground/src/molecules/DatepickerExamples.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export function DatepickerExamples() {
3434
label="Without value (format dd/mm/yyyy)"
3535
required
3636
inputProps={{ id: 'aui-datepicker-1' }}
37+
onChange={v => console.log(v)}
3738
calendarProps={{
3839
unavailable: [new Date(Date.now()).toISOString()],
3940
unavailableTo: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000).toISOString(),
@@ -80,7 +81,7 @@ export function DatepickerExamples() {
8081
return 'IT DOES NOT CONTAIN 00/00';
8182
}}
8283
value={'THIS IS NOT A DATE!'}
83-
inputProps={{ id: 'aui-datepicker-1', state: 'success' }}
84+
inputProps={{ id: 'aui-datepicker-2', state: 'success' }}
8485
calendarProps={{
8586
unavailable: [new Date(Date.now()).toISOString()],
8687
unavailableTo: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000).toISOString(),

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
"prepare": "husky install"
1818
},
1919
"dependencies": {
20+
"@date-fns/tz": "^1.4.1",
2021
"@storybook/client-api": "^7.2.1",
2122
"@swc-node/register": "^1.5.5",
2223
"@swc/core": "^1.3.32",
2324
"@types/react-modal": "^3.13.1",
24-
"date-fns": "^2.29.3",
25+
"date-fns": "^4.1.0",
2526
"husky": "^8.0.3",
2627
"react": "^19.0.0",
2728
"react-dom": "^19.0.0",
@@ -37,7 +38,7 @@
3738
"@nrwl/vite": "15.8.7",
3839
"@nrwl/workspace": "15.8.7",
3940
"@testing-library/jest-dom": "^5.16.5",
40-
"@testing-library/react": "13.4.0",
41+
"@testing-library/react": "^16.3.0",
4142
"@types/jsdom": "^20.0.1",
4243
"@types/node": "18.11.9",
4344
"@typescript-eslint/eslint-plugin": "^5.36.1",

packages/antwerp-ui/react-components/src/constants/settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const SORT_DESCENDING = 'descending';
1616

1717
// DATES
1818
export const DEFAULT_DATE_FORMAT = 'dd/MM/yyyy';
19+
export const TIMEZONE = 'Europe/Brussels';
1920

2021
// LOCALES
2122
export const DEFAULT_LOCALE = nlBE;

packages/antwerp-ui/react-components/src/lib/molecules/datepicker/Calendar.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { Icon } from '../../base/icon';
99
import { MonthsView } from './views/MonthsView';
1010
import { YearsView } from './views/YearsView';
1111
import { titleize } from '../../../utils/string.utils';
12-
import { formatWithFallback } from '../../../utils/time.utils';
12+
import { formatWithFallback, toUtcMidnightInBrussels } from '../../../utils/time.utils';
1313

1414
export const Calendar = forwardRef<HTMLDivElement, CalendarProps>(
1515
(
@@ -144,7 +144,10 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarProps>(
144144
const handleChange = (value: Date) => {
145145
if (activeView === CalendarView.DAYS) {
146146
setActiveDate(value);
147-
return onChange && onChange(formatISO(value));
147+
const year = value.getFullYear();
148+
const month = value.getMonth();
149+
const day = value.getDate();
150+
return onChange && onChange(toUtcMidnightInBrussels(year, month, day));
148151
} else if (activeView === CalendarView.MONTHS) {
149152
setActiveMonth(getMonth(value));
150153
return setActiveView(CalendarView.DAYS);

packages/antwerp-ui/react-components/src/lib/molecules/datepicker/Datepicker.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
/* eslint-disable react-hooks/exhaustive-deps */
22
import { DatepickerProps } from './Datepicker.types';
33
import { DEFAULT_DATE_FORMAT } from '../../../constants/settings';
4-
import { formatISO } from 'date-fns';
54
import { Icon } from '../../base/icon';
6-
import { isValid as fnsIsValid, format as fnsFormat, parse as fnsParse } from 'date-fns';
5+
import { isValid as fnsIsValid, format as fnsFormat, parse as fnsParse, formatISO } from 'date-fns';
76
import { renderDescription, renderLabel } from '../../atoms/input/input.renders';
87
import { TextField } from '../../atoms/input';
98
import { useOutsideClick } from '../../../utils/custom.hooks';

packages/antwerp-ui/react-components/src/utils/time.utils.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { isAfter, isBefore, isSameDay, format, Locale } from 'date-fns';
2+
import { tz } from '@date-fns/tz';
3+
import { TIMEZONE } from '../constants/settings';
24

35
export function isInRange(date: Date, from?: string, to?: string, list?: string[]): boolean {
46
return (
@@ -27,3 +29,9 @@ export function formatWithFallback(date: Date, dateFormat: string, locale?: Loca
2729
return fallback;
2830
}
2931
}
32+
33+
export function toUtcMidnightInBrussels(year: number, month: number, day: number): string {
34+
const brusselsDate = tz(TIMEZONE)(new Date(Date.UTC(year, month, day, 0, 0, 0)));
35+
const brusselsISODate = brusselsDate.toISOString();
36+
return brusselsISODate;
37+
}

0 commit comments

Comments
 (0)