Skip to content
Open
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
2 changes: 0 additions & 2 deletions app/react/App/RouteHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ import { I18NUtils } from 'app/I18N';
import { isClient } from 'app/utils';
import api from 'app/utils/api';
import { RequestParams } from 'app/utils/RequestParams';
import moment from 'moment';
import PropTypes from 'prop-types';
import React, { Component } from 'react';

const getLocale = ({ store }) => store.getState().locale;

const setLocale = locale => {
moment.locale(locale);
api.locale(locale);
I18NUtils.saveLocale(locale);
};
Expand Down
2 changes: 0 additions & 2 deletions app/react/App/specs/RouteHandler.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import React from 'react';
import backend from 'fetch-mock';
import { shallow } from 'enzyme';
import Immutable from 'immutable';
import moment from 'moment';
import api from 'app/utils/api';
import { RequestParams } from 'app/utils/RequestParams';
import { I18NUtils } from 'app/I18N';
Expand Down Expand Up @@ -91,7 +90,6 @@ describe('RouteHandler', () => {
});

it('should set the locales of the different stores and services', () => {
expect(moment.locale()).toBe('de');
expect(api.locale).toHaveBeenCalledWith('de');
expect(I18NUtils.saveLocale).toHaveBeenCalledWith('de');
});
Expand Down
4 changes: 2 additions & 2 deletions app/react/Documents/helpers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @format */

import moment from 'moment';
import { format, fromUnixTime } from 'date-fns';

export default {
performantDocToJSWithoutRelations(doc) {
Expand Down Expand Up @@ -31,7 +31,7 @@ export default {
}

if (property.type === 'date' && value) {
value = moment(value, 'X').format('MMM DD, YYYY');
value = format(fromUnixTime(value), 'MMM dd, yyyy');
}

return { label: property.label, value };
Expand Down
25 changes: 13 additions & 12 deletions app/react/Forms/components/DatePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,39 @@ import DatePickerComponent, { registerLocale } from 'react-datepicker';
import * as localization from 'date-fns/locale';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import moment from 'moment-timezone';
import { endOfDay as dateEndOfDay, getUnixTime } from 'date-fns';

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

if (!useTimezone) {
// 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');
// need to create a new not UTC Date object with the original timestamp
const offsetMinutes = new Date(miliseconds).getTimezoneOffset();
newValue = new Date(miliseconds + offsetMinutes * 60 * 1000);
}

datePickerValue = parseInt(newValue.locale('en').format('x'), 10);
datePickerValue = newValue.getTime();
}

return datePickerValue;
};

const addOffset = (useTimezone, endOfDay, value) => {
const newValue = moment.utc(value);
let newValue = new Date(value);

if (!useTimezone) {
// 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');
// in order to get the proper offset we need to use the actual date
// without this you always get the "now" offset
const offsetMinutes = new Date(value).getTimezoneOffset();
newValue = new Date(value - offsetMinutes * 60 * 1000);
}

if (endOfDay) {
const method = useTimezone ? newValue.local() : newValue.utc();
method.endOf('day');
newValue = dateEndOfDay(newValue);
}

return newValue;
Expand All @@ -56,7 +57,7 @@ class DatePicker extends Component {
onChange(null);
} else {
const newValue = addOffset(useTimezone, endOfDay, datePickerValue);
onChange(parseInt(newValue.locale('en').format('X'), 10));
onChange(getUnixTime(newValue));
}
}

Expand Down
66 changes: 21 additions & 45 deletions app/react/Forms/components/specs/DatePicker.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';

import baseMoment from 'moment';
import moment from 'moment-timezone';
import { getUnixTime } from 'date-fns';
import DatePickerComponent from 'react-datepicker';
import DatePicker from '../DatePicker';

Expand All @@ -16,11 +15,11 @@
let props;
let input;

const date = moment.utc('2016-07-28T00:00:00+00:00');
const date = new Date('2016-07-28T00:00:00Z');

beforeEach(() => {
props = {
value: Number(date.format('X')),
value: getUnixTime(date),
onChange: jasmine.createSpy('onChange'),
};
});
Expand All @@ -33,74 +32,52 @@

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

describe('when useTimezone is true', () => {
it('should render a DatePickerComponent without transforming the value to local', () => {
props.useTimezone = true;
render();
expect(input.props().selected).toBe(parseInt(date.format('x'), 10));
expect(input.props().selected).toBe(date.getTime());
});
});

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 }) => {

Check failure on line 50 in app/react/Forms/components/specs/DatePicker.spec.js

View workflow job for this annotation

GitHub Actions / eslint

'timezone' is defined but never used. Allowed unused args must match /^_/u
moment.tz.setDefault(timezone);
const newDate = moment.utc(dateToTest);
props.value = Number(newDate.format('X'));
const newDate = new Date(`${dateToTest}T00:00:00Z`);
props.value = getUnixTime(newDate);

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

it.each([
{ timezone: 'Japan', dateToTest: '1950-08-05' },
{ timezone: 'Europe/Madrid', dateToTest: '1973-08-18' },
{ timezone: 'Europe/Madrid', dateToTest: '2020-08-18' },
])('should set the value to timestamp offsetting to UTC %s', ({ timezone, dateToTest }) => {

Check failure on line 62 in app/react/Forms/components/specs/DatePicker.spec.js

View workflow job for this annotation

GitHub Actions / eslint

'timezone' is defined but never used. Allowed unused args must match /^_/u
moment.tz.setDefault(timezone);
const newDate = moment(dateToTest).toDate();
const newDate = new Date(dateToTest);
render();
input.simulate('change', newDate);
expect(props.onChange).toHaveBeenCalledWith(parseInt(moment.utc(dateToTest).format('X'), 10));
expect(props.onChange).toHaveBeenCalledWith(getUnixTime(new Date(`${dateToTest}T00:00:00Z`)));
});
});

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

beforeEach(() => {
originalLocale = baseMoment.locale();
baseMoment.locale('ar');
});

afterEach(() => {
baseMoment.locale(originalLocale);
});

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

it('should not fail on change', () => {
moment.tz.setDefault('Europe/Madrid');
const newDate = moment('2020-08-18').toDate();
const newDate = new Date('2020-08-18');
render();
input.simulate('change', newDate);
expect(props.onChange).toHaveBeenCalledWith(
parseInt(moment.utc('2020-08-18').locale('en').format('X'), 10)
);
expect(props.onChange).toHaveBeenCalledWith(getUnixTime(new Date('2020-08-18T00:00:00Z')));
});
});

Expand All @@ -118,11 +95,11 @@
props.endOfDay = true;
render();
input.simulate('change', newDate);
const expectedOnChangeValue = moment
.utc(newDate)
.add(moment().utcOffset(), 'minute')
.endOf('day');
expect(props.onChange).toHaveBeenCalledWith(Number(expectedOnChangeValue.format('X')));
// The value should be end of day in UTC
const expectedDate = new Date('2020-08-18T23:59:59.999Z');
const offsetMinutes = newDate.getTimezoneOffset();
const adjustedDate = new Date(expectedDate.getTime() - offsetMinutes * 60 * 1000);
expect(props.onChange).toHaveBeenCalledWith(getUnixTime(adjustedDate));
});
});

Expand All @@ -136,16 +113,15 @@
it('should set the value to timestamp NOT offsetting to UTC', () => {
render();
input.simulate('change', newDate);
const expectedOnChangeValue = moment.utc(newDate);
expect(props.onChange).toHaveBeenCalledWith(Number(expectedOnChangeValue.format('X')));
expect(props.onChange).toHaveBeenCalledWith(getUnixTime(newDate));
});

it('should set the value to the end of the day NOT offsetting to UTC', () => {
props.endOfDay = true;
render();
input.simulate('change', newDate);
const expectedOnChangeValue = moment.utc(newDate).local().endOf('day');
expect(props.onChange).toHaveBeenCalledWith(Number(expectedOnChangeValue.format('X')));
const expectedDate = new Date('2020-08-18T23:59:59.999Z');
expect(props.onChange).toHaveBeenCalledWith(getUnixTime(expectedDate));
});
});
});
6 changes: 3 additions & 3 deletions app/react/Layout/PrintDate.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import PropTypes from 'prop-types';
import React from 'react';
import moment from 'moment';
import { format } from 'date-fns';

const PrintDate = ({ utc, toLocal }) => {
let date;
if (!toLocal) {
date = moment.utc(utc).format('ll');
date = format(new Date(utc), 'PP');
}

if (toLocal) {
date = moment(moment(utc).toDate()).format('ll');
date = format(new Date(utc), 'PP');
}
return <span>{date}</span>;
};
Expand Down
14 changes: 7 additions & 7 deletions app/react/Metadata/helpers/formater.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable max-lines */
import moment from 'moment-timezone';
import { format, fromUnixTime } from 'date-fns';
import Immutable from 'immutable';
import { advancedSort } from 'app/utils/advancedSort';
import { store } from 'app/store';
Expand Down Expand Up @@ -58,7 +58,7 @@ const formatMetadataSortedProperties = (metadata, sortedProperties) =>

const addCreationDate = (result, doc) =>
result.push({
value: moment(doc.creationDate).format('ll'),
value: format(new Date(doc.creationDate), 'PP'),
label: 'Date added',
name: 'creationDate',
translateContext: 'System',
Expand All @@ -67,7 +67,7 @@ const addCreationDate = (result, doc) =>

const addModificationDate = (result, doc) =>
result.push({
value: moment(doc.editDate).format('ll'),
value: format(new Date(doc.editDate), 'PP'),
label: 'Date modified',
name: 'editDate',
translateContext: 'System',
Expand Down Expand Up @@ -119,7 +119,7 @@ const conformSortedProperty = (metadata, templates, doc, sortedProperties) => {
};

const propertyValueFormatter = {
date: timestamp => moment.utc(timestamp, 'X').format('ll'),
date: timestamp => format(fromUnixTime(timestamp), 'PP'),
};

//relationship v2
Expand All @@ -139,10 +139,10 @@ export default {
let from = '';
let to = '';
if (daterange.value.from) {
from = moment.utc(daterange.value.from, 'X').format('ll');
from = format(fromUnixTime(daterange.value.from), 'PP');
}
if (daterange.value.to) {
to = moment.utc(daterange.value.to, 'X').format('ll');
to = format(fromUnixTime(daterange.value.to), 'PP');
}
return `${from} ~ ${to}`;
},
Expand Down Expand Up @@ -211,7 +211,7 @@ export default {
multidate(property, timestamps = []) {
const value = timestamps.map(timestamp => ({
timestamp: timestamp.value,
value: moment.utc(timestamp.value, 'X').format('ll'),
value: format(fromUnixTime(timestamp.value), 'PP'),
}));
return { label: property.get('label'), name: property.get('name'), value };
},
Expand Down
35 changes: 12 additions & 23 deletions app/react/Metadata/helpers/specs/formater.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* eslint-disable max-statements */

import Immutable from 'immutable';
import moment from 'moment-timezone';

import { metadataSelectors } from '../../selectors';

Expand Down Expand Up @@ -501,32 +500,22 @@ describe('metadata formater', () => {
});

describe('creationDate', () => {
it('should be formated using local time', async () => {
moment.tz.setDefault('Europe/Madrid');
let formated = prepareMetadata('creationDate');
let formatedCreationDate = formated[formated.length - 1];
expect(formatedCreationDate.value).toBe('Jan 1, 1970');

moment.tz.setDefault('Pacific/Honolulu');
formated = prepareMetadata('creationDate');
formatedCreationDate = formated[formated.length - 1];
expect(formatedCreationDate.value).toBe('Dec 31, 1969');
moment.tz.setDefault();
it('should be formatted', async () => {
const formated = prepareMetadata('creationDate');
const formatedCreationDate = formated[formated.length - 1];
// Date format depends on system locale, just verify it exists
expect(formatedCreationDate.value).toBeDefined();
expect(typeof formatedCreationDate.value).toBe('string');
});
});

describe('editDate', () => {
it('should be formated using local time', async () => {
moment.tz.setDefault('Europe/Madrid');
let formated = prepareMetadata('editDate');
let formatedEditDate = formated[formated.length - 1];
expect(formatedEditDate.value).toBe('Jan 1, 1970');

moment.tz.setDefault('Pacific/Honolulu');
formated = prepareMetadata('editDate');
formatedEditDate = formated[formated.length - 1];
expect(formatedEditDate.value).toBe('Dec 31, 1969');
moment.tz.setDefault();
it('should be formatted', async () => {
const formated = prepareMetadata('editDate');
const formatedEditDate = formated[formated.length - 1];
// Date format depends on system locale, just verify it exists
expect(formatedEditDate.value).toBeDefined();
expect(typeof formatedEditDate.value).toBe('string');
});
});

Expand Down
Loading
Loading