diff --git a/packages/date/src/index.js b/packages/date/src/index.js index bcc1e4d32be6df..8580f97062f27a 100644 --- a/packages/date/src/index.js +++ b/packages/date/src/index.js @@ -395,7 +395,7 @@ export function dateI18n( dateFormat, dateValue = new Date(), gmt = false ) { /** * Check whether a date is considered in the future according to the WordPress settings. * - * @param {(Date|string)} dateValue Date object or string. + * @param {string} dateValue Date String or Date object in the Defined WP Timezone. * * @return {boolean} Is in the future. */ @@ -406,4 +406,19 @@ export function isInTheFuture( dateValue ) { return momentObject.isAfter( now ); } +/** + * Create and return a JavaScript Date Object from a date string in the WP timezone. + * + * @param {string?} dateString Date formatted in the WP timezone. + * + * @return {Date} Date + */ +export function getDate( dateString ) { + if ( ! dateString ) { + return momentLib.tz( 'WP' ).toDate(); + } + + return momentLib.tz( dateString, 'WP' ).toDate(); +} + setupWPTimezone(); diff --git a/packages/date/src/test/index.js b/packages/date/src/test/index.js new file mode 100644 index 00000000000000..f18e2b0915825f --- /dev/null +++ b/packages/date/src/test/index.js @@ -0,0 +1,40 @@ +/** + * Internal dependencies + */ +import { isInTheFuture, getDate, setSettings, __experimentalGetSettings } from '../'; + +describe( 'isInTheFuture', () => { + it( 'should return true if the date is in the future', () => { + // Create a Date object 1 minute in the future. + const date = new Date( Number( getDate() ) + ( 1000 * 60 ) ); + + expect( isInTheFuture( date ) ).toBe( true ); + } ); + + it( 'should return true if the date is in the past', () => { + // Create a Date object 1 minute in the past. + const date = new Date( Number( getDate() ) - ( 1000 * 60 ) ); + + expect( isInTheFuture( date ) ).toBe( false ); + } ); + + it( 'should ignore the timezone', () => { + const settings = __experimentalGetSettings(); + + // Set a timezone in the future + setSettings( { + ...settings, + timezone: { offset: '4', string: '' }, + } ); + // Create a Date object 1 minute in the past. + let date = new Date( Number( getDate() ) - ( 1000 * 60 ) ); + expect( isInTheFuture( date ) ).toBe( false ); + + // Create a Date object 1 minute in the future. + date = new Date( Number( getDate() ) + ( 1000 * 60 ) ); + expect( isInTheFuture( date ) ).toBe( true ); + + // Restore default settings + setSettings( settings ); + } ); +} ); diff --git a/packages/editor/src/store/selectors.js b/packages/editor/src/store/selectors.js index f405c90cbe272b..a4e426507f8167 100644 --- a/packages/editor/src/store/selectors.js +++ b/packages/editor/src/store/selectors.js @@ -32,7 +32,7 @@ import { getFreeformContentHandlerName, isUnmodifiedDefaultBlock, } from '@wordpress/blocks'; -import { isInTheFuture } from '@wordpress/date'; +import { isInTheFuture, getDate } from '@wordpress/date'; import { removep } from '@wordpress/autop'; import { select } from '@wordpress/data'; import deprecated from '@wordpress/deprecated'; @@ -333,7 +333,7 @@ export function isCurrentPostPublished( state ) { const post = getCurrentPost( state ); return [ 'publish', 'private' ].indexOf( post.status ) !== -1 || - ( post.status === 'future' && ! isInTheFuture( new Date( Number( new Date( post.date ) ) + ONE_MINUTE_IN_MS ) ) ); + ( post.status === 'future' && ! isInTheFuture( new Date( Number( getDate( post.date ) ) - ONE_MINUTE_IN_MS ) ) ); } /** @@ -493,7 +493,7 @@ export function hasAutosave( state ) { export function isEditedPostBeingScheduled( state ) { const date = getEditedPostAttribute( state, 'date' ); // Offset the date by one minute (network latency) - const checkedDate = new Date( Number( new Date( date ) ) + ONE_MINUTE_IN_MS ); + const checkedDate = new Date( Number( getDate( date ) ) - ONE_MINUTE_IN_MS ); return isInTheFuture( checkedDate ); }