From b441150c472b4653d3d8944c40b428aa34c5ce60 Mon Sep 17 00:00:00 2001 From: npsedhain Date: Thu, 25 Mar 2021 10:47:06 +0545 Subject: [PATCH 1/4] Make the date utils locale aware. --- src/libs/DateUtils.js | 91 +++++++++---------- src/pages/home/report/ReportActionItemDate.js | 2 +- 2 files changed, 42 insertions(+), 51 deletions(-) diff --git a/src/libs/DateUtils.js b/src/libs/DateUtils.js index ce32d4939663..83f631aac17f 100644 --- a/src/libs/DateUtils.js +++ b/src/libs/DateUtils.js @@ -1,7 +1,6 @@ import moment from 'moment'; import 'moment-timezone'; import Onyx from 'react-native-onyx'; -import Str from 'expensify-common/lib/str'; import ONYXKEYS from '../ONYXKEYS'; import CONST from '../CONST'; @@ -15,13 +14,15 @@ Onyx.connect({ * Gets the user's stored time-zone NVP and returns a localized * Moment object for the given timestamp * + * @param {String} locale * @param {Number} timestamp * * @returns {Moment} * * @private */ -function getLocalMomentFromTimestamp(timestamp) { +function getLocalMomentFromTimestamp(locale, timestamp) { + moment.locale(locale); return moment.unix(timestamp).tz(timezone); } @@ -33,32 +34,48 @@ function getLocalMomentFromTimestamp(timestamp) { * Jan 20 at 5:30 PM within the past year * Jan 20, 2019 at 5:30 PM anything over 1 year ago * + * @param {String} locale * @param {Number} timestamp * @param {Boolean} includeTimeZone * * @returns {String} */ -function timestampToDateTime(timestamp, includeTimeZone = false) { - const date = getLocalMomentFromTimestamp(timestamp); - const isThisYear = moment().format('YYYY') === date.format('YYYY'); - const isToday = moment().format('D MMM YYYY') === date.format('D MMM YYYY'); - const yesterday = moment().add(-1, 'day').format('D MMM YYYY'); - const isYesterday = yesterday === date.format('D MMM YYYY'); +function timestampToDateTime(locale, timestamp, includeTimeZone = false) { + const date = getLocalMomentFromTimestamp(locale, timestamp); - let format = 'LT'; - if (isYesterday) { - format = `[Yesterday at] ${format}`; - } else if (!isToday) { - format = `MMM D [at] ${format}`; - } else if (!isThisYear) { - format = `MMM D, YYYY [at] ${format}`; - } + moment.calendarFormat = function (myMoment, now) { + const diff = myMoment.diff(now, 'days', true); - if (includeTimeZone) { - format = `${format} [UTC]Z`; - } + let retVal = 'sameElse'; - return date.format(format); + if (diff < -1) { + retVal = 'lastWeek'; + } else if (diff < 0) { + retVal = 'lastDay'; + } else if (diff < 1) { + retVal = 'sameDay'; + } else if (diff < 2) { + retVal = 'nextDay'; + } else if (diff < 7) { + retVal = 'nextWeek'; + } + + if (includeTimeZone) { + retVal = 'timeZone'; + } + + return retVal; + }; + + return moment().calendar(date, { + sameDay: '[Today at] LT', + nextDay: '[Tomorrow at] LT', + nextWeek: 'MMM D [at] LT', + lastDay: '[Yesterday at] LT', + lastWeek: 'MMM D [at] LT', + sameElse: 'MMM D, YYYY [at] LT', + timeZone: 'LT [UTC]Z', + }); } /** @@ -74,41 +91,15 @@ function timestampToDateTime(timestamp, includeTimeZone = false) { * Jan 20 within the past year * Jan 20, 2019 anything over 1 year * + * @param {String} locale * @param {Number} timestamp * * @returns {String} */ -function timestampToRelative(timestamp) { - const date = getLocalMomentFromTimestamp(timestamp); - const durationFromLocalNow = moment.duration( - date.diff(getLocalMomentFromTimestamp(moment().unix())), - ); - const round = num => Math.floor(Math.abs(num)); - - if (date.isAfter(moment().subtract(60, 'seconds'))) { - return '< 1 minute ago'; - } - - if (date.isAfter(moment().subtract(60, 'minutes'))) { - const minutes = round(durationFromLocalNow.asMinutes()); - return `${minutes} ${Str.pluralize('minute', 'minutes', minutes)} ago`; - } - - if (date.isAfter(moment().subtract(24, 'hours'))) { - const hours = round(durationFromLocalNow.asHours()); - return `${hours} ${Str.pluralize('hour', 'hours', hours)} ago`; - } - - if (date.isAfter(moment().subtract(30, 'days'))) { - const days = round(durationFromLocalNow.asDays()); - return `${days} ${Str.pluralize('day', 'days', days)} ago`; - } - - if (date.isAfter(moment().subtract(1, 'year'))) { - return date.format('MMM D'); - } +function timestampToRelative(locale, timestamp) { + const date = getLocalMomentFromTimestamp(locale, timestamp); - return date.format('MMM D, YYYY'); + return moment(date).fromNow(); } /** diff --git a/src/pages/home/report/ReportActionItemDate.js b/src/pages/home/report/ReportActionItemDate.js index fc4d33a0d236..d4b490c3fee9 100644 --- a/src/pages/home/report/ReportActionItemDate.js +++ b/src/pages/home/report/ReportActionItemDate.js @@ -11,7 +11,7 @@ const propTypes = { const ReportActionItemDate = props => ( - {DateUtils.timestampToDateTime(props.timestamp)} + {DateUtils.timestampToDateTime('en', props.timestamp)} ); From e7bcb450d7bc53cd0b0b82a45b8de27088b4e5b4 Mon Sep 17 00:00:00 2001 From: npsedhain Date: Fri, 26 Mar 2021 04:21:30 +0545 Subject: [PATCH 2/4] Append the timezone to each format. --- src/libs/DateUtils.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/libs/DateUtils.js b/src/libs/DateUtils.js index 83f631aac17f..732f5945ecf7 100644 --- a/src/libs/DateUtils.js +++ b/src/libs/DateUtils.js @@ -42,6 +42,7 @@ function getLocalMomentFromTimestamp(locale, timestamp) { */ function timestampToDateTime(locale, timestamp, includeTimeZone = false) { const date = getLocalMomentFromTimestamp(locale, timestamp); + const TZ = '[UTC]Z'; moment.calendarFormat = function (myMoment, now) { const diff = myMoment.diff(now, 'days', true); @@ -60,21 +61,27 @@ function timestampToDateTime(locale, timestamp, includeTimeZone = false) { retVal = 'nextWeek'; } - if (includeTimeZone) { - retVal = 'timeZone'; - } - return retVal; }; - return moment().calendar(date, { + if (includeTimeZone) { + return moment(date).calendar({ + sameDay: `[Today at] LT ${TZ}`, + nextDay: `[Tomorrow at] LT ${TZ}`, + nextWeek: `MMM D [at] LT ${TZ}`, + lastDay: `[Yesterday at] LT ${TZ}`, + lastWeek: `MMM D [at] LT ${TZ}`, + sameElse: `MMM D, YYYY [at] LT ${TZ}`, + }); + } + + return moment(date).calendar({ sameDay: '[Today at] LT', nextDay: '[Tomorrow at] LT', nextWeek: 'MMM D [at] LT', lastDay: '[Yesterday at] LT', lastWeek: 'MMM D [at] LT', sameElse: 'MMM D, YYYY [at] LT', - timeZone: 'LT [UTC]Z', }); } From c2c4e4ed6515902c51b0120d6f5c3b19d972fefa Mon Sep 17 00:00:00 2001 From: npsedhain Date: Fri, 26 Mar 2021 04:24:29 +0545 Subject: [PATCH 3/4] Remove the calendar format override. --- src/libs/DateUtils.js | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/libs/DateUtils.js b/src/libs/DateUtils.js index 732f5945ecf7..217c1d40c0dc 100644 --- a/src/libs/DateUtils.js +++ b/src/libs/DateUtils.js @@ -44,26 +44,6 @@ function timestampToDateTime(locale, timestamp, includeTimeZone = false) { const date = getLocalMomentFromTimestamp(locale, timestamp); const TZ = '[UTC]Z'; - moment.calendarFormat = function (myMoment, now) { - const diff = myMoment.diff(now, 'days', true); - - let retVal = 'sameElse'; - - if (diff < -1) { - retVal = 'lastWeek'; - } else if (diff < 0) { - retVal = 'lastDay'; - } else if (diff < 1) { - retVal = 'sameDay'; - } else if (diff < 2) { - retVal = 'nextDay'; - } else if (diff < 7) { - retVal = 'nextWeek'; - } - - return retVal; - }; - if (includeTimeZone) { return moment(date).calendar({ sameDay: `[Today at] LT ${TZ}`, From fb91d0566463fc9db7be4e83641e1a74fd3df439 Mon Sep 17 00:00:00 2001 From: npsedhain Date: Fri, 26 Mar 2021 08:03:19 +0545 Subject: [PATCH 4/4] Simplify the timezone logic. --- src/libs/DateUtils.js | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/libs/DateUtils.js b/src/libs/DateUtils.js index 217c1d40c0dc..29114258de0f 100644 --- a/src/libs/DateUtils.js +++ b/src/libs/DateUtils.js @@ -42,26 +42,15 @@ function getLocalMomentFromTimestamp(locale, timestamp) { */ function timestampToDateTime(locale, timestamp, includeTimeZone = false) { const date = getLocalMomentFromTimestamp(locale, timestamp); - const TZ = '[UTC]Z'; - - if (includeTimeZone) { - return moment(date).calendar({ - sameDay: `[Today at] LT ${TZ}`, - nextDay: `[Tomorrow at] LT ${TZ}`, - nextWeek: `MMM D [at] LT ${TZ}`, - lastDay: `[Yesterday at] LT ${TZ}`, - lastWeek: `MMM D [at] LT ${TZ}`, - sameElse: `MMM D, YYYY [at] LT ${TZ}`, - }); - } + const tz = includeTimeZone ? ' [UTC]Z' : ''; return moment(date).calendar({ - sameDay: '[Today at] LT', - nextDay: '[Tomorrow at] LT', - nextWeek: 'MMM D [at] LT', - lastDay: '[Yesterday at] LT', - lastWeek: 'MMM D [at] LT', - sameElse: 'MMM D, YYYY [at] LT', + sameDay: `[Today at] LT${tz}`, + nextDay: `[Tomorrow at] LT${tz}`, + nextWeek: `MMM D [at] LT${tz}`, + lastDay: `[Yesterday at] LT${tz}`, + lastWeek: `MMM D [at] LT${tz}`, + sameElse: `MMM D, YYYY [at] LT${tz}`, }); }