From aa33ec8af68c39474efd1f3033658dc5ce5be8e4 Mon Sep 17 00:00:00 2001 From: Kimmo Puputti Date: Mon, 6 Nov 2017 16:26:28 +0200 Subject: [PATCH] Add date/time format util --- src/util/dates.js | 47 ++++++++++++++++++++++++++++++++++++++++++ src/util/dates.test.js | 19 ++++++++++++++++- src/util/test-data.js | 2 +- 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/util/dates.js b/src/util/dates.js index 59470b15..94c31328 100644 --- a/src/util/dates.js +++ b/src/util/dates.js @@ -22,3 +22,50 @@ export const nightsBetween = (startDate, endDate) => { } return nights; }; + +/** + * Format the given date + * + * @param {Object} intl Intl object from react-intl + * @param {String} todayString translation for the current day + * @param {Date} d Date to be formatted + * + * @returns {String} formatted date + */ +export const formatDate = (intl, todayString, d) => { + const paramsValid = intl && d instanceof Date && typeof todayString === 'string'; + if (!paramsValid) { + throw new Error(`Invalid params for formatDate: (${intl}, ${todayString}, ${d})`); + } + const now = moment(intl.now()); + const formattedTime = intl.formatTime(d); + let formattedDate; + + if (now.isSame(d, 'day')) { + // e.g. "Today, 9:10pm" + formattedDate = todayString; + } else if (now.isSame(d, 'week')) { + // e.g. "Wed, 8:00pm" + formattedDate = intl.formatDate(d, { + weekday: 'short', + }); + } else if (now.isSame(d, 'year')) { + // e.g. "Aug 22, 7:40pm" + formattedDate = intl.formatDate(d, { + month: 'short', + day: 'numeric', + }); + } else { + // e.g. "Jul 17 2016, 6:02pm" + const date = intl.formatDate(d, { + month: 'short', + day: 'numeric', + }); + const year = intl.formatDate(d, { + year: 'numeric', + }); + formattedDate = `${date} ${year}`; + } + + return `${formattedDate}, ${formattedTime}`; +}; diff --git a/src/util/dates.test.js b/src/util/dates.test.js index 0cfbf335..99eacbd4 100644 --- a/src/util/dates.test.js +++ b/src/util/dates.test.js @@ -1,4 +1,5 @@ -import { nightsBetween } from './dates'; +import { fakeIntl } from './test-data'; +import { nightsBetween, formatDate } from './dates'; describe('date utils', () => { describe('nightsBetween()', () => { @@ -22,4 +23,20 @@ describe('date utils', () => { expect(nightsBetween(start, end)).toEqual(2); }); }); + + describe('formatDate()', () => { + /* + NOTE: These are not really testing the formatting properly since + the fakeIntl object has to be used in the tests. + */ + + it('formats a date today', () => { + const d = new Date(Date.UTC(2017, 10, 23, 13, 51)); + expect(formatDate(fakeIntl, 'Today', d)).toEqual('Today, 13:51'); + }); + it('formats a date', () => { + const d = new Date(Date.UTC(2017, 10, 22, 13, 51)); + expect(formatDate(fakeIntl, 'Today', d)).toEqual('2017-11-22, 13:51'); + }); + }); }); diff --git a/src/util/test-data.js b/src/util/test-data.js index 6031aa86..c4ad814c 100644 --- a/src/util/test-data.js +++ b/src/util/test-data.js @@ -154,7 +154,7 @@ export const fakeIntl = { formatPlural: d => d, formatRelative: d => d, formatTime: d => `${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}`, - now: d => d, + now: () => Date.UTC(2017, 10, 23, 12, 59), }; const noop = () => null;