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

[NoQA] feat: Remove moment from the project (Except Datepicker) #28175

Merged
merged 14 commits into from
Oct 6, 2023
1 change: 1 addition & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ const CONST = {
SQL_DATE_TIME: 'YYYY-MM-DD HH:mm:ss',
FNS_FORMAT_STRING: 'yyyy-MM-dd',
LOCAL_TIME_FORMAT: 'h:mm a',
YEAR_MONTH_FORMAT: 'yyyyMM',
WEEKDAY_TIME_FORMAT: 'eeee',
MONTH_DAY_ABBR_FORMAT: 'MMM d',
SHORT_DATE_FORMAT: 'MM-dd',
Expand Down
2 changes: 1 addition & 1 deletion src/components/AutoUpdateTime.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const propTypes = {

function AutoUpdateTime(props) {
/**
* @returns {moment} Returns the locale moment object
* @returns {Date} Returns the locale Date object
*/
const getCurrentUserLocalTime = useCallback(
() => DateUtils.getLocalDateFromDatetime(props.preferredLocale, null, props.timezone.selected),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import moment from 'moment';
import CONST from '../../../CONST';
import {getDaysInMonth, startOfMonth, getDay, addDays, format} from 'date-fns';

/**
* Generates a matrix representation of a month's calendar given the year and month.
Expand All @@ -26,25 +25,25 @@ export default function generateMonthMatrix(year, month) {
}

// Get the number of days in the month and the first day of the month
const daysInMonth = moment([year, month]).daysInMonth();
const firstDay = moment([year, month, 1]).locale(CONST.LOCALES.EN);
const firstDayOfMonth = startOfMonth(new Date(year, month, 1));
const daysInMonth = getDaysInMonth(firstDayOfMonth);

// Create a matrix to hold the calendar days
const matrix = [];
let currentWeek = [];

// Add null values for days before the first day of the month
for (let i = 0; i < firstDay.weekday(); i++) {
for (let i = 0; i < getDay(firstDayOfMonth); i++) {
currentWeek.push(null);
}

// Add calendar days to the matrix
for (let i = 1; i <= daysInMonth; i++) {
const day = moment([year, month, i]).locale(CONST.LOCALES.EN);
currentWeek.push(day.date());
const currentDate = addDays(firstDayOfMonth, i - 1);
currentWeek.push(Number(format(currentDate, 'd')));

// Start a new row when the current week is full
if (day.weekday() === 6) {
if (getDay(currentDate) === 6) {
matrix.push(currentWeek);
currentWeek = [];
}
Expand Down
5 changes: 3 additions & 2 deletions src/libs/DateUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ function setLocale(localeString) {

/**
* Gets the user's stored time zone NVP and returns a localized
* Moment object for the given ISO-formatted datetime string
* Date object for the given ISO-formatted datetime string
*
* @private
* @param {String} locale
* @param {String} datetime
* @param {String} [currentSelectedTimezone]
* @returns {Moment}
* @returns {Date}
*
*/
function getLocalDateFromDatetime(locale, datetime, currentSelectedTimezone = timezone.selected) {
Expand Down Expand Up @@ -343,6 +343,7 @@ const DateUtils = {
setTimezoneUpdated,
getMicroseconds,
getDBTime,
setLocale,
subtractMillisecondsFromDateTime,
getDateStringFromISOTimestamp,
getStatusUntilDate,
Expand Down
4 changes: 2 additions & 2 deletions src/libs/EmojiUtils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import _ from 'underscore';
import moment from 'moment';
import {getUnixTime} from 'date-fns';
import Str from 'expensify-common/lib/str';
import Onyx from 'react-native-onyx';
import lodashGet from 'lodash/get';
Expand Down Expand Up @@ -220,7 +220,7 @@ function getFrequentlyUsedEmojis(newEmoji) {
let frequentEmojiList = [...frequentlyUsedEmojis];

const maxFrequentEmojiCount = CONST.EMOJI_FREQUENT_ROW_COUNT * CONST.EMOJI_NUM_PER_ROW - 1;
const currentTimestamp = moment().unix();
const currentTimestamp = getUnixTime(new Date());
_.each([].concat(newEmoji), (emoji) => {
let currentEmojiCount = 1;
const emojiIndex = _.findIndex(frequentEmojiList, (e) => e.code === emoji.code);
Expand Down
4 changes: 2 additions & 2 deletions src/libs/actions/IOU.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Onyx from 'react-native-onyx';
import _ from 'underscore';
import lodashGet from 'lodash/get';
import Str from 'expensify-common/lib/str';
import moment from 'moment';
import {format} from 'date-fns';
import CONST from '../../CONST';
import ROUTES from '../../ROUTES';
import ONYXKEYS from '../../ONYXKEYS';
Expand Down Expand Up @@ -96,7 +96,7 @@ Onyx.connect({
* @param {String} id
*/
function resetMoneyRequestInfo(id = '') {
const created = currentDate || moment().format('YYYY-MM-DD');
const created = currentDate || format(new Date(), CONST.DATE.FNS_FORMAT_STRING);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is yyyy-MM-dd unlike YYYY-MM-DD as it was previously.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, its the same, moment uses own formats, date-fns uses IANA and doesnt support YYYY-MM-DD

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this comment, the output of the date here is same as from moment, right? @allroundexperts @waterim

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

confirmed its the same in DM

Onyx.merge(ONYXKEYS.IOU, {
id,
amount: 0,
Expand Down
4 changes: 2 additions & 2 deletions src/libs/actions/MapboxToken.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import _ from 'underscore';
import moment from 'moment';
import {isAfter} from 'date-fns';
import Onyx from 'react-native-onyx';
import {AppState} from 'react-native';
import lodashGet from 'lodash/get';
Expand Down Expand Up @@ -42,7 +42,7 @@ const setExpirationTimer = () => {
}, REFRESH_INTERVAL);
};

const hasTokenExpired = () => moment().isAfter(currentToken.expiration);
const hasTokenExpired = () => isAfter(new Date(), currentToken.expiration);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is incorrect. This should be isAfter(currentToken.expiration, new Date()) instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, have you tested the format of currentToken.expiration? It might be a string which will cause this to return false always.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"I think this is incorrect. This should be isAfter(currentToken.expiration, new Date()) instead."
Actually no, this is correct:
We use the isAfter function to compare the current date (new Date()) with currentToken.expiration.
The isTokenExpired variable will be true if the current date is after the expiration date, and false otherwise.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you post a screenshot of two dates using moment and isAfter function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, one moment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new Date()
new Date(currentToken.expiration)
@allroundexperts

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm talking about the input values themselves that you used for comparison.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get it, will show now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks correct


const clearToken = () => {
console.debug('[MapboxToken] Deleting the token stored in Onyx');
Expand Down
4 changes: 2 additions & 2 deletions src/libs/actions/Report.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import lodashGet from 'lodash/get';
import ExpensiMark from 'expensify-common/lib/ExpensiMark';
import Onyx from 'react-native-onyx';
import Str from 'expensify-common/lib/str';
import moment from 'moment';
import {format as timezoneFormat, utcToZonedTime} from 'date-fns-tz';
import ONYXKEYS from '../../ONYXKEYS';
import * as Pusher from '../Pusher/pusher';
import LocalNotification from '../Notification/LocalNotification';
Expand Down Expand Up @@ -1636,7 +1636,7 @@ function hasAccountIDEmojiReacted(accountID, users, skinTone) {
* @param {Number} [skinTone]
*/
function addEmojiReaction(reportID, reportActionID, emoji, skinTone = preferredSkinTone) {
const createdAt = moment().utc().format(CONST.DATE.SQL_DATE_TIME);
const createdAt = timezoneFormat(utcToZonedTime(new Date(), 'UTC'), CONST.DATE.FNS_DB_FORMAT_STRING);
waterim marked this conversation as resolved.
Show resolved Hide resolved
const optimisticData = [
{
onyxMethod: Onyx.METHOD.MERGE,
Expand Down
4 changes: 2 additions & 2 deletions src/libs/actions/User.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import _ from 'underscore';
import lodashGet from 'lodash/get';
import Onyx from 'react-native-onyx';
import moment from 'moment';
import {isBefore} from 'date-fns';
import ONYXKEYS from '../../ONYXKEYS';
import * as API from '../API';
import CONST from '../../CONST';
Expand Down Expand Up @@ -460,7 +460,7 @@ function isBlockedFromConcierge(blockedFromConciergeNVP) {
return false;
}

return moment().isBefore(moment(blockedFromConciergeNVP.expiresAt), 'day');
return isBefore(new Date(), new Date(blockedFromConciergeNVP.expiresAt));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is incorrect again. It should be isBefore(new Date(blockedFromConciergeNVP.expiresAt), new Date())

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is correct again:
If new Date() is before new Date(blockedFromConciergeNVP.expiresAt) - it will be true

}

function triggerNotifications(onyxUpdates) {
Expand Down
7 changes: 4 additions & 3 deletions src/pages/EnablePayments/AdditionalDetailsStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import {withOnyx} from 'react-native-onyx';
import {View} from 'react-native';
import moment from 'moment/moment';
import {subYears} from 'date-fns';
import {parsePhoneNumber} from 'awesome-phonenumber';
import IdologyQuestions from './IdologyQuestions';
import ScreenWrapper from '../../components/ScreenWrapper';
Expand Down Expand Up @@ -80,8 +80,9 @@ const fieldNameTranslationKeys = {
};

function AdditionalDetailsStep({walletAdditionalDetails, translate, currentUserPersonalDetails}) {
const minDate = moment().subtract(CONST.DATE_BIRTH.MAX_AGE, 'Y').toDate();
const maxDate = moment().subtract(CONST.DATE_BIRTH.MIN_AGE_FOR_PAYMENT, 'Y').toDate();
const currentDate = new Date();
const minDate = subYears(currentDate, CONST.DATE_BIRTH.MAX_AGE);
const maxDate = subYears(currentDate, CONST.DATE_BIRTH.MIN_AGE_FOR_PAYMENT);
const shouldAskForFullSSN = walletAdditionalDetails.errorCode === CONST.WALLET.ERROR.SSN;

/**
Expand Down
6 changes: 3 additions & 3 deletions src/pages/ReimbursementAccount/IdentityForm.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import {View} from 'react-native';
import PropTypes from 'prop-types';
import moment from 'moment/moment';
import {subYears} from 'date-fns';
import _ from 'underscore';
import TextInput from '../../components/TextInput';
import styles from '../../styles/styles';
Expand Down Expand Up @@ -134,8 +134,8 @@ function IdentityForm(props) {
const dobErrorText = (props.errors.dob ? props.translate('bankAccount.error.dob') : '') || (props.errors.dobAge ? props.translate('bankAccount.error.age') : '');
const identityFormInputKeys = ['firstName', 'lastName', 'dob', 'ssnLast4'];

const minDate = moment().subtract(CONST.DATE_BIRTH.MAX_AGE, 'Y').toDate();
const maxDate = moment().subtract(CONST.DATE_BIRTH.MIN_AGE_FOR_PAYMENT, 'Y').toDate();
const minDate = subYears(new Date(), CONST.DATE_BIRTH.MAX_AGE);
const maxDate = subYears(new Date(), CONST.DATE_BIRTH.MIN_AGE_FOR_PAYMENT);

return (
<View style={props.style}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import moment from 'moment';
import PropTypes from 'prop-types';
import React, {useCallback} from 'react';
import {withOnyx} from 'react-native-onyx';
import lodashGet from 'lodash/get';
import {subYears} from 'date-fns';
import CONST from '../../../../CONST';
import ONYXKEYS from '../../../../ONYXKEYS';
import ROUTES from '../../../../ROUTES';
Expand Down Expand Up @@ -81,8 +81,8 @@ function DateOfBirthPage({translate, privatePersonalDetails}) {
inputID="dob"
label={translate('common.date')}
defaultValue={privatePersonalDetails.dob || ''}
minDate={moment().subtract(CONST.DATE_BIRTH.MAX_AGE, 'years').toDate()}
maxDate={moment().subtract(CONST.DATE_BIRTH.MIN_AGE, 'years').toDate()}
minDate={subYears(new Date(), CONST.DATE_BIRTH.MAX_AGE)}
maxDate={subYears(new Date(), CONST.DATE_BIRTH.MIN_AGE)}
waterim marked this conversation as resolved.
Show resolved Hide resolved
/>
</Form>
)}
Expand Down
13 changes: 7 additions & 6 deletions src/pages/wallet/WalletStatementPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, {useEffect} from 'react';
import PropTypes from 'prop-types';
import lodashGet from 'lodash/get';
import {withOnyx} from 'react-native-onyx';
import moment from 'moment';
import {format, getMonth, getYear} from 'date-fns';
import Str from 'expensify-common/lib/str';
import Navigation from '../../libs/Navigation/Navigation';
import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
Expand All @@ -19,6 +19,7 @@ import CONST from '../../CONST';
import FullPageOfflineBlockingView from '../../components/BlockingViews/FullPageOfflineBlockingView';
import {withNetwork} from '../../components/OnyxProvider';
import networkPropTypes from '../../components/networkPropTypes';
import DateUtils from '../../libs/DateUtils';

const propTypes = {
/** The route object passed to this page from the navigator */
Expand Down Expand Up @@ -55,15 +56,15 @@ function WalletStatementPage(props) {
const yearMonth = lodashGet(props.route.params, 'yearMonth', null);

useEffect(() => {
const currentYearMonth = moment().format('YYYYMM');
const currentYearMonth = format(new Date(), CONST.DATE.YEAR_MONTH_FORMAT);
if (!yearMonth || yearMonth.length !== 6 || yearMonth > currentYearMonth) {
Navigation.dismissModal();
}
// eslint-disable-next-line react-hooks/exhaustive-deps -- we want this effect to run only on mount
}, []);

useEffect(() => {
moment.locale(props.preferredLocale);
DateUtils.setLocale(props.preferredLocale);
}, [props.preferredLocale]);

const processDownload = () => {
Expand All @@ -84,9 +85,9 @@ function WalletStatementPage(props) {
User.generateStatementPDF(yearMonth);
};

const year = yearMonth.substring(0, 4) || moment().year();
const month = yearMonth.substring(4) || moment().month();
const monthName = moment(month, 'M').format('MMMM');
const year = yearMonth.substring(0, 4) || getYear(new Date());
const month = yearMonth.substring(4) || getMonth(new Date());
const monthName = format(new Date(year, month), 'MMMM');
waterim marked this conversation as resolved.
Show resolved Hide resolved
const title = `${monthName} ${year} statement`;
const url = `${CONFIG.EXPENSIFY.EXPENSIFY_URL}statement.php?period=${yearMonth}`;

Expand Down
10 changes: 5 additions & 5 deletions tests/actions/ReportTest.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import _ from 'underscore';
import Onyx from 'react-native-onyx';
import lodashGet from 'lodash/get';
import moment from 'moment';
import {utcToZonedTime} from 'date-fns-tz';
import {beforeEach, beforeAll, afterEach, describe, it, expect} from '@jest/globals';
import ONYXKEYS from '../../src/ONYXKEYS';
import CONST from '../../src/CONST';
Expand Down Expand Up @@ -275,7 +275,7 @@ describe('actions/Report', () => {
.then(() => {
// The report will be read
expect(ReportUtils.isUnread(report)).toBe(false);
expect(moment.utc(report.lastReadTime).valueOf()).toBeGreaterThanOrEqual(moment.utc(currentTime).valueOf());
expect(utcToZonedTime(report.lastReadTime, 'UTC').getTime()).toBeGreaterThanOrEqual(utcToZonedTime(currentTime, 'UTC').getTime());
waterim marked this conversation as resolved.
Show resolved Hide resolved

// And no longer show the green dot for unread mentions in the LHN
expect(ReportUtils.isUnreadWithMention(report)).toBe(false);
Expand All @@ -301,7 +301,7 @@ describe('actions/Report', () => {
// The report will be read, the green dot for unread mentions will go away, and the lastReadTime updated
expect(ReportUtils.isUnread(report)).toBe(false);
expect(ReportUtils.isUnreadWithMention(report)).toBe(false);
expect(moment.utc(report.lastReadTime).valueOf()).toBeGreaterThanOrEqual(moment.utc(currentTime).valueOf());
expect(utcToZonedTime(report.lastReadTime, 'UTC').getTime()).toBeGreaterThanOrEqual(utcToZonedTime(currentTime, 'UTC').getTime());
expect(report.lastMessageText).toBe('Current User Comment 1');

// When another comment is added by the current user
Expand All @@ -313,7 +313,7 @@ describe('actions/Report', () => {
.then(() => {
// The report will be read and the lastReadTime updated
expect(ReportUtils.isUnread(report)).toBe(false);
expect(moment.utc(report.lastReadTime).valueOf()).toBeGreaterThanOrEqual(moment.utc(currentTime).valueOf());
expect(utcToZonedTime(report.lastReadTime, 'UTC').getTime()).toBeGreaterThanOrEqual(utcToZonedTime(currentTime, 'UTC').getTime());
expect(report.lastMessageText).toBe('Current User Comment 2');

// When another comment is added by the current user
Expand All @@ -325,7 +325,7 @@ describe('actions/Report', () => {
.then(() => {
// The report will be read and the lastReadTime updated
expect(ReportUtils.isUnread(report)).toBe(false);
expect(moment.utc(report.lastReadTime).valueOf()).toBeGreaterThanOrEqual(moment.utc(currentTime).valueOf());
expect(utcToZonedTime(report.lastReadTime, 'UTC').getTime()).toBeGreaterThanOrEqual(utcToZonedTime(currentTime, 'UTC').getTime());
expect(report.lastMessageText).toBe('Current User Comment 3');

const USER_1_BASE_ACTION = {
Expand Down
Loading
Loading