UNPKG

@talend/react-components

Version:
265 lines (258 loc) 7.37 kB
import { format } from 'date-fns/format'; import { setSeconds } from 'date-fns/setSeconds'; import { date as dateUtils } from '@talend/utils'; import { convertDateToTimezone, extractDateOnly } from '../Date/date-extraction'; import getErrorMessage from '../shared/error-messages'; import { checkTime, pad, strToTime, timeToStr } from '../Time/time-extraction'; const INTERNAL_INVALID_DATE = new Date('INTERNAL_INVALID_DATE'); export function DateTimePickerException(code, message) { this.message = getErrorMessage(message); this.code = code; } function isEmpty(value) { return value === undefined || value === null || value === ''; } /** * Extract time * @param date {Date} The date to extract * @param useSeconds {boolean} Indicates if we should extract seconds * @param useUTC {boolean} Indicates if date is in UTC * @param timezone {string} Indicates if use specific timezone * @returns {*} */ function extractTimeOnly(date, { useSeconds, useUTC, timezone }) { let hours = date.getHours(); let minutes = date.getMinutes(); let seconds = date.getSeconds(); if (useUTC) { hours = date.getUTCHours(); minutes = date.getUTCMinutes(); seconds = date.getUTCSeconds(); } else if (timezone) { const converted = dateUtils.convertToTimeZone(date, { timeZone: timezone }); hours = converted.getHours(); minutes = converted.getMinutes(); seconds = converted.getSeconds(); } return { hours: pad(hours, 2), minutes: pad(minutes, 2), seconds: useSeconds ? pad(seconds, 2) : '00' }; } /** * Convert hour minutes and seconds into seconds * @param hours {string} * @param minutes {string} * @param seconds {string} * @returns {number} */ function timeToSeconds(hours, minutes, seconds) { checkTime({ hours, minutes, seconds }); return Number(hours) * 3600 + Number(minutes) * 60 + Number(seconds); } /** * Set the time to the provided date * @param date {Date} Date in current TZ * @param time {{hours: string, minutes: string, seconds: string}} Time in current TZ * @returns {Date} * @throws DateTimePickerException */ function dateAndTimeToDateTime(date, time, options) { if (isEmpty(date) && isEmpty(time)) { return null; } else if (isEmpty(date)) { throw new DateTimePickerException('INVALID_DATE_EMPTY', 'INVALID_DATE_EMPTY'); } else if (isEmpty(time)) { throw new DateTimePickerException('INVALID_TIME_EMPTY', 'INVALID_TIME_EMPTY'); } let timeObject = time; if (typeof time === 'string') { timeObject = strToTime(time, options.useSeconds); } const { hours, minutes, seconds } = timeObject; const timeInSeconds = timeToSeconds(hours, minutes, seconds); const localTimezoneDate = setSeconds(date, timeInSeconds); return convertDateToTimezone(localTimezoneDate, options); } function dateAndTimeToStr(date = '', time = '', options) { const dateStr = date instanceof Date ? format(date, dateUtils.formatToUnicode(options.dateFormat)) : date; const timeStr = typeof time === 'string' ? time : timeToStr(time, options.useSeconds); return `${dateStr} ${timeStr}`.trim(); } /** * Extract parts (date, time, date/time, textInput) from a Date * @param datetime {Date} * @param options {Object} * @returns * {{ * date: Date, * time: { hours: string, minutes: string, seconds: string }, * }} */ function extractPartsFromDateTime(datetime, options) { if (isNaN(datetime.getTime())) { return { date: undefined, time: undefined, datetime: undefined }; } return { date: extractDateOnly(datetime, options), time: extractTimeOnly(datetime, options), datetime }; } /** * Extract parts (date, time, date/time, textInput) from a string * @param textInput {string} * @param options {Object} * @returns * {{ * date: Date, * time: { hours: string, minutes: string, seconds: string }, * datetime: Date, * textInput: string * }} */ function extractPartsFromTextInput(textInput, options) { if (textInput === '') { return { date: '', time: '', errors: [], errorMessage: null }; } let date; let time; let datetime; let errors = []; try { const splitMatches = textInput.split(/\s/); date = splitMatches[0]; time = splitMatches[1]; datetime = dateAndTimeToDateTime(new Date(date), time, options); } catch (error) { datetime = INTERNAL_INVALID_DATE; errors = [error]; } return { date, time, datetime, errors, errorMessage: errors[0] ? errors[0].message : null }; } /** * Extract parts (date, time, date/time, textInput) from a value with * different possible types * @param value {string | Date | number} * @param options {Object} * @returns * {{ * date: Date, * time: { hours: string, minutes: string, seconds: string }, * datetime: Date, * textInput: string * }} */ function extractParts(value, options) { const typeOfValue = typeof value; if (typeOfValue === 'number') { return extractPartsFromDateTime(new Date(value), options); } else if (typeOfValue === 'string') { return extractPartsFromTextInput(value, options); } else if (value instanceof Date) { return extractPartsFromDateTime(value, options); } return { date: undefined, time: undefined, errors: [] }; } /** * re-compute state (date/datetime/textInput) on date change. * @param datePickerPayload {Object} payload passed by date picker * @param time {string | {hours: string, minutes: string, seconds: string}} * time stored in DateTimeManager state * @param options {Object} */ function updatePartsOnDateChange(datePickerPayload, time, options) { const { errors = [], date, textInput: dateTextInput } = datePickerPayload; let datetime; const nextErrors = errors; if (errors.length > 0) { datetime = INTERNAL_INVALID_DATE; } else { try { datetime = dateAndTimeToDateTime(date, time, options); } catch (error) { datetime = INTERNAL_INVALID_DATE; nextErrors.push(error); } } return { date: date || dateTextInput, time, datetime, textInput: dateAndTimeToStr(dateTextInput || date, time, options), errors, errorMessage: nextErrors[0] ? nextErrors[0].message : null }; } /** * re-compute state (time/datetime/textInput) on time change. * @param timePickerPayload {Object} payload passed by time picker * @param date {Date|string|number} date stored in DateTimeManager state * @param options {Object} */ function updatePartsOnTimeChange(timePickerPayload, date, options) { const { errors = [], time, textInput: timeTextInput } = timePickerPayload; let datetime; const nextErrors = errors; if (errors.length > 0) { datetime = INTERNAL_INVALID_DATE; } else { try { datetime = dateAndTimeToDateTime(date, time, options); } catch (error) { datetime = INTERNAL_INVALID_DATE; nextErrors.push(error); } } return { time: time || timeTextInput, datetime, textInput: dateAndTimeToStr(date, time || timeTextInput, options), errors, errorMessage: nextErrors[0] ? nextErrors[0].message : null }; } export { extractParts, extractPartsFromDateTime, extractPartsFromTextInput, updatePartsOnDateChange, updatePartsOnTimeChange }; //# sourceMappingURL=datetime-extraction.js.map