import parse from 'date-fns/parse' ; import isValid from 'date-fns/isValid' ; import formatDate from 'date-fns/format' ; import isWithinInterval from 'date-fns/isWithinInterval' ; import isEqual from 'date-fns/isEqual' ; import isBefore from 'date-fns/isBefore' ; import isAfter from 'date-fns/isAfter' ; import { utcToZonedTime , format as tzFormat , toDate } from 'date-fns-tz' ; import { DatePickerInputValueParserParameters } from './types' ; import { DateOrDateRangeType , DateRangeType } from '../Calendar' ; export const timezoneConvert = ( date , timeZone ? ) : DateOrDateRangeType => { const convert = ( dateToConvert ) => { if ( timeZone ) { /**
             * Prevent invalid IANA timezone error. This is likely to happen
             * when someone is editing properties in a Storybook examples.
             */ try { return utcToZonedTime ( dateToConvert , timeZone ) ; } catch { return dateToConvert ; } } return dateToConvert ; } ; return Array . isArray ( date ) ? ( date . map ( convert ) as DateRangeType ) : ( convert ( date ) as Date ) ; } ; export const timezoneFormat = ( date , timeZone ? ) => { if ( timeZone ) { /**
         * Prevent invalid IANA timezone error. This is likely to happen
         * when someone is editing properties in a Storybook examples.
         */ try { /**
             * Maintain the same date and time, but formatted in the given timezone
             * so next time the user edits the date it's not recalculated.
             */ return new Date ( tzFormat ( date , 'MMM dd yyyy HH:mm:ss OOOO' , { timeZone } ) ) ; } catch { return date ; } } return date ; } ; export const formatDateRange = ( dates , format ) => dates . map ( date => formatDate ( date , format ) ) . join ( ' - ' ) ; export const isDateValid = ( date , pattern ) => { return ( date . length === pattern . length && isValid ( parse ( date , pattern , new Date ( ) ) ) ) ; } ; export const isDateAfter = ( date , dateToCompare ) => isEqual ( date , dateToCompare ) || isAfter ( date , dateToCompare ) ; export const isDateBefore = ( date , dateToCompare ) => isEqual ( date , dateToCompare ) || isBefore ( date , dateToCompare ) ; export const isDateWithinInterval = ( date , minDate , maxDate ) => { if ( ! minDate && ! maxDate ) { return true ; } if ( minDate && maxDate ) { return isWithinInterval ( date , { start : minDate , end : maxDate } ) ; } if ( minDate ) { return isDateAfter ( date , minDate ) ; } if ( maxDate ) { return isDateBefore ( date , maxDate ) ; } return false ; } ; export const datePickerParseDateString = ( value , { customParser , dateFormat , timezone , minDate , maxDate } ) => { if ( ! value ) { return ; } const isValidDateString = isDateValid ( value , dateFormat ) ; const parsedNextValue = customParser && ! isValidDateString ? customParser ( value , { timezone } ) : parse ( value , dateFormat , new Date ( ) ) ; if ( ! parsedNextValue || ! isValid ( parsedNextValue ) ) { return ; } const nextTimezoneValue = timezoneFormat ( parsedNextValue , timezone ) ; if ( ! isDateWithinInterval ( nextTimezoneValue , minDate , maxDate ) ) { return ; } return nextTimezoneValue ; } ; export const isValidDateValue = ( dateValue ) : dateValue is DateOrDateRangeType => typeof dateValue !== 'string' ; export const getStartOfTheDayDate = ( date ? ) : Date | undefined => { if ( ! date ) { return date ; } const clonedDate = toDate ( date ) ; clonedDate . setHours ( 0 , 0 , 0 , 0 ) ; return clonedDate ; } ;