Skip to content
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

Fixed datepicker timezone issue #2325

Merged
merged 5 commits into from
Oct 7, 2024
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
Empty file added 0
Empty file.
16 changes: 13 additions & 3 deletions src/components/DatePicker/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@ import React, { forwardRef, useState, useEffect } from "react";

import { DatePicker as AntDatePicker } from "antd";
import classnames from "classnames";
import dayjs from "dayjs";
import { isNotPresent } from "neetocist";
import { Left, Right, Calendar, Close } from "neetoicons";
import PropTypes from "prop-types";

import { Tag } from "components";
import Label from "components/Label";
import { useSyncedRef, useId } from "hooks";
import { convertToDayjsObjects, noop, hyphenize } from "utils";
import {
convertToDayjsObjects,
noop,
hyphenize,
dayjs,
getTimezoneAppliedDateTime,
} from "utils";

import IconOverride from "./IconOverride";
import Provider from "./Provider";
Expand Down Expand Up @@ -77,7 +82,12 @@ const DatePicker = forwardRef(
if (type === "range" && isNotPresent(date)) {
return onChange([], dateString);
}
const allowed = getAllowed(date, minDate, maxDate);

const allowed = getAllowed(
getTimezoneAppliedDateTime(date),
minDate,
maxDate
);
setValue(allowed);

return onChange(allowed, formattedString(allowed, dateFormat));
Expand Down
3 changes: 2 additions & 1 deletion src/components/TimePicker/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
hyphenize,
ANT_DESIGN_GLOBAL_TOKEN_OVERRIDES,
getLocale,
getTimezoneAppliedDateTime,
} from "utils";

import { TIME_PICKER_TYPES } from "./constants";
Expand Down Expand Up @@ -77,7 +78,7 @@ const TimePicker = forwardRef(
const handleOnChange = (time, timeString) => {
type === "range" && !time
? onChange([], timeString)
: onChange(time, timeString);
: onChange(getTimezoneAppliedDateTime(time), timeString);
};

const panelRender = originalPanel => (
Expand Down
60 changes: 55 additions & 5 deletions src/utils/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import dayjs from "dayjs";
import pureDayjs from "dayjs";
import localeData from "dayjs/plugin/localeData";
import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";
import weekday from "dayjs/plugin/weekday";
import weekOfYear from "dayjs/plugin/weekOfYear";
Expand All @@ -10,10 +11,11 @@ import { complement, equals, isEmpty, omit, pipe, toPairs } from "ramda";
// eslint-disable-next-line import/extensions
import en from "src/translations/en.json";

dayjs.extend(weekOfYear);
dayjs.extend(weekday);
dayjs.extend(localeData);
dayjs.extend(utc);
pureDayjs.extend(weekOfYear);
pureDayjs.extend(weekday);
pureDayjs.extend(localeData);
pureDayjs.extend(utc);
pureDayjs.extend(timezone);

const getEnTranslationValue = translationKey =>
translationKey.split(".").reduce((acc, key) => acc[key], en);
Expand All @@ -31,6 +33,54 @@ const getScrollbarWidth = () => {
return scrollbarWidth;
};

const hasTimezone = dateString => {
const timezoneRegex = /Z|[+-]\d{2}:\d{2}$|GMT([+-]\d{4})?$/;

return timezoneRegex.test(dateString);
};

// eslint-disable-next-line import/exports-last
export const dayjs = (...args) => {
if (
pureDayjs.tz().$x.$timezone === pureDayjs.tz.guess() ||
pureDayjs.tz().$x.$timezone === undefined
) {
return pureDayjs(...args);
}

if (args.length > 0 && typeof args[0] === "string") {
const pureDayjsArgs = args.slice(0, Math.min(args.length, 2));

if (hasTimezone(args[0])) {
args[0] = pureDayjs(...pureDayjsArgs);
} else {
args[0] = pureDayjs(...pureDayjsArgs).format("YYYY-MM-DD HH:mm:ss");
args[1] = "YYYY-MM-DD HH:mm:ss";
}
}

if (args[0]?.toString() === "Invalid Date") return pureDayjs(...args);

const timezone = pureDayjs.tz().$x.$timezone || pureDayjs.tz.guess();

return args.length === 2
? pureDayjs.tz(...args, timezone)
: pureDayjs.tz(...args);
};

Object.assign(dayjs, { ...pureDayjs });

export const getTimezoneAppliedDateTime = inputDateTime => {
if (!inputDateTime) return null;

const timezoneAppliedDateTime = date =>
dayjs(date.format("YYYY-MM-DD HH:mm:ss"));

return Array.isArray(inputDateTime)
? inputDateTime.map(timezoneAppliedDateTime)
: timezoneAppliedDateTime(inputDateTime);
};

export const noop = () => {};

export const hyphenize = input => {
Expand Down
3 changes: 1 addition & 2 deletions stories/Components/DatePicker.stories.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React from "react";

import dayjs from "dayjs";

import { Modal, Typography, Pane, DatePicker } from "components";
import Button from "components/Button";
import { dayjs } from "utils";

import { disabledDateTime } from "./constants";

Expand Down
3 changes: 1 addition & 2 deletions stories/Components/TimePicker.stories.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React from "react";

import dayjs from "dayjs";

import { Modal, Typography, Pane } from "components";
import Button from "components/Button";
import TimePicker from "components/TimePicker";
import { dayjs } from "utils";

import { disabledDateTime } from "./constants";

Expand Down
2 changes: 1 addition & 1 deletion tests/DatePicker.test.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from "react";

import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import dayjs from "dayjs";

import DatePicker from "components/DatePicker";
import { dayjs } from "utils";

const today = dayjs();
const theDate = dayjs(new Date(1999, 7, 16));
Expand Down
2 changes: 1 addition & 1 deletion tests/TimePicker.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React from "react";

import { screen, render, fireEvent } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import dayjs from "dayjs";

import { TimePicker } from "components";
import { dayjs } from "utils";

const currentTime = dayjs();
const { getByRole, getByText, getAllByText, getAllByRole } = screen;
Expand Down
Loading