Skip to content

Commit

Permalink
edge case for dates where timezone was different
Browse files Browse the repository at this point in the history
  • Loading branch information
daneryl committed May 31, 2021
1 parent 475e1b1 commit 8562d74
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 12 deletions.
13 changes: 9 additions & 4 deletions app/react/Forms/components/DatePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ import 'react-datepicker/dist/react-datepicker.css';
import DatePickerComponent from 'react-datepicker';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import moment from 'moment';
import moment from 'moment-timezone';

const removeOffset = (useTimezone, value) => {
let datePickerValue = null;
const miliseconds = value * 1000;
if (value) {
const newValue = moment.utc(value * 1000);
const newValue = moment.utc(miliseconds);

if (!useTimezone) {
newValue.subtract(moment().utcOffset(), 'minute');
// in order to get the system offset for the specific date we
// need to create a new not UTC moment object with the original timestamp
newValue.subtract(moment(moment(miliseconds)).utcOffset(), 'minutes');
}

datePickerValue = parseInt(newValue.locale('en').format('x'), 10);
Expand All @@ -25,7 +28,9 @@ const addOffset = (useTimezone, endOfDay, value) => {
const newValue = moment.utc(value);

if (!useTimezone) {
newValue.add(moment().utcOffset(), 'minute');
// in order to get the proper offset moment has to be initialized with the actual date
// without this you always get the "now" moment offset
newValue.add(moment(value).utcOffset(), 'minutes');
}

if (endOfDay) {
Expand Down
43 changes: 35 additions & 8 deletions app/react/Forms/components/specs/DatePicker.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,9 @@ describe('DatePicker', () => {
input = component.find(DatePickerComponent);
};

const expectCorrectSelectedValue = () => {
it('should render a DatePickerComponent with the correct date transformed to local value', () => {
render();
const expectedSelectedValue = date.clone().subtract(moment().utcOffset(), 'minute');
expect(input.props().selected).toBe(parseInt(expectedSelectedValue.format('x'), 10));
};

it('should render a DatePickerComponent with the correct transformed to local value', () => {
expectCorrectSelectedValue();
expect(input.props().selected).toBe(parseInt(moment('2016-07-28').format('x'), 10));
});

describe('when useTimezone is true', () => {
Expand All @@ -62,6 +57,37 @@ describe('DatePicker', () => {
expectCorrectOnChange();
});

afterEach(() => {
moment.tz.setDefault();
});

describe('when date is in a diferent timezone than today', () => {
it.each([
{ timezone: 'Japan', dateToTest: '1950-08-05' },
{ timezone: 'Europe/Madrid', dateToTest: '1973-08-18' },
])('should use the timestamp offsetting to UTC %s', ({ timezone, dateToTest }) => {
moment.tz.setDefault(timezone);
const newDate = moment.utc(dateToTest);
props.value = Number(newDate.format('X'));

render();
expect(input.props().selected).toBe(parseInt(moment(dateToTest).format('x'), 10));
});

it.each([
{ timezone: 'Japan', dateToTest: '1950-08-05' },
{ timezone: 'Europe/Madrid', dateToTest: '1973-08-18' },
])('should set the value to timestamp offsetting to UTC %s', ({ timezone, dateToTest }) => {
moment.tz.setDefault(timezone);
const newDate = moment(dateToTest).toDate();
render();
input.simulate('change', newDate);
expect(props.onChange).toHaveBeenCalledWith(
parseInt(moment.utc(dateToTest).format('X'), 10)
);
});
});

describe('When locale is a non-latin locale', () => {
let originalLocale;

Expand All @@ -75,7 +101,8 @@ describe('DatePicker', () => {
});

it('should render a latin-based value (until correct locales are implemented)', () => {
expectCorrectSelectedValue();
render();
expect(input.props().selected).toBe(parseInt(moment('2016-07-28').format('x'), 10));
});

it('should not fail on change', () => {
Expand Down

0 comments on commit 8562d74

Please sign in to comment.