elliptical-datetime
Version:
Elliptical phrases to handle natural language dates and times
459 lines (392 loc) • 13.3 kB
JavaScript
import _regeneratorRuntime from 'babel-runtime/regenerator';
import _extends from 'babel-runtime/helpers/extends';
var _marked = [getDateTimeResults, getDateTimeOptions].map(_regeneratorRuntime.mark);
/** @jsx createElement */
import _ from 'lodash';
import { createElement } from 'elliptical';
import { InternalTime, TimeOfDay } from './time';
import moment from 'moment';
import { ambiguousTime, join, relativeDate } from './helpers';
import { InternalDate, Date as DatePhrase } from './date';
function isNoonOrMidnight(time) {
return (time.hour === 12 || time.hour === 0) && !time.minute && !time.second;
}
function timeIsInAMPM(time, ampm) {
if (ampm === 'am') {
return time.hour >= 0 && time.hour < 12;
} else if (ampm === 'pm') {
return time.hour >= 12 && time.hour < 24;
}
}
var TrueDate = {
describe: function describe(_ref) {
var props = _ref.props;
return createElement(
'sequence',
null,
createElement(
'choice',
{ merge: true },
createElement(InternalDate, _extends({}, props, { id: undefined })),
createElement(
'map',
{ 'function': function _function(result) {
return { date: result };
}, skipIncomplete: true },
createElement(DatePhrase, _extends({}, props, { nullify: true }))
)
)
);
}
};
function getDateTimeResults(result, props) {
var dates, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, date, _arr, _i, i;
return _regeneratorRuntime.wrap(function getDateTimeResults$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
dates = void 0;
if (result.date) {
if (result._ambiguousWeek) {
dates = _.map([0, 1, -1], function (weeks) {
return moment(result.date).add(weeks, 'weeks').toDate();
});
} else if (result._ambiguousCentury) {
dates = _.map([0, 100, -100], function (years) {
return moment(result.date).add(years, 'years').toDate();
});
} else if (result._ambiguousYear) {
if (result._ambiguousMonth) {
dates = _.flatMap([0, 1, -1], function (y) {
return _.map([0, 1, -1], function (m) {
return moment(result.date).add(y, 'years').add(m, 'months').toDate();
});
});
} else {
dates = _.map([0, 1, -1], function (years) {
return moment(result.date).add(years, 'years').toDate();
});
}
} else {
dates = [result.date];
}
} else {
dates = [undefined];
}
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
_context.prev = 5;
_iterator = dates[Symbol.iterator]();
case 7:
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
_context.next = 37;
break;
}
date = _step.value;
if (!(date && result.time)) {
_context.next = 14;
break;
}
_context.next = 12;
return join(date, result.time, props.timezoneOffset);
case 12:
_context.next = 34;
break;
case 14:
if (!(result.time && result.relativeDate)) {
_context.next = 19;
break;
}
_context.next = 17;
return join(relativeDate(result.relativeDate), result.time, props.timezoneOffset);
case 17:
_context.next = 34;
break;
case 19:
if (!date) {
_context.next = 24;
break;
}
_context.next = 22;
return join(date, props.defaultTime, props.timezoneOffset);
case 22:
_context.next = 34;
break;
case 24:
if (!result.time) {
_context.next = 34;
break;
}
_arr = [0, 1, -1];
_i = 0;
case 27:
if (!(_i < _arr.length)) {
_context.next = 34;
break;
}
i = _arr[_i];
_context.next = 31;
return join(relativeDate({ days: i }), result.time, props.timezoneOffset);
case 31:
_i++;
_context.next = 27;
break;
case 34:
_iteratorNormalCompletion = true;
_context.next = 7;
break;
case 37:
_context.next = 43;
break;
case 39:
_context.prev = 39;
_context.t0 = _context['catch'](5);
_didIteratorError = true;
_iteratorError = _context.t0;
case 43:
_context.prev = 43;
_context.prev = 44;
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
case 46:
_context.prev = 46;
if (!_didIteratorError) {
_context.next = 49;
break;
}
throw _iteratorError;
case 49:
return _context.finish(46);
case 50:
return _context.finish(43);
case 51:
case 'end':
return _context.stop();
}
}
}, _marked[0], this, [[5, 39, 43, 51], [44,, 46, 50]]);
}
function getDateTimeOptions(option, props) {
var _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, result;
return _regeneratorRuntime.wrap(function getDateTimeOptions$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_iteratorNormalCompletion2 = true;
_didIteratorError2 = false;
_iteratorError2 = undefined;
_context2.prev = 3;
_iterator2 = getDateTimeResults(option.result, props)[Symbol.iterator]();
case 5:
if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) {
_context2.next = 12;
break;
}
result = _step2.value;
_context2.next = 9;
return _.assign({}, option, { result: result });
case 9:
_iteratorNormalCompletion2 = true;
_context2.next = 5;
break;
case 12:
_context2.next = 18;
break;
case 14:
_context2.prev = 14;
_context2.t0 = _context2['catch'](3);
_didIteratorError2 = true;
_iteratorError2 = _context2.t0;
case 18:
_context2.prev = 18;
_context2.prev = 19;
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
case 21:
_context2.prev = 21;
if (!_didIteratorError2) {
_context2.next = 24;
break;
}
throw _iteratorError2;
case 24:
return _context2.finish(21);
case 25:
return _context2.finish(18);
case 26:
case 'end':
return _context2.stop();
}
}
}, _marked[1], this, [[3, 14, 18, 26], [19,, 21, 25]]);
}
// function filterDateTimeResult (result) {
// return true
// }
export var DateTime = {
id: 'elliptical-datetime:DateTime',
defaultProps: {
defaultTime: { hour: 8, minute: 0, second: 0 },
past: true,
future: true,
prepositions: false,
label: 'date and time'
},
filterResult: function filterResult(result, _ref2) {
var props = _ref2.props;
if (!props.past && moment().isAfter(result)) {
return false;
}
if (!props.future && moment().isBefore(result)) {
return false;
}
return true;
},
describe: function describe(_ref3) {
var props = _ref3.props;
return props.nullify ? null : createElement(
'map',
{ outbound: function outbound(option) {
return getDateTimeOptions(option, props);
}, limit: 1, skipIncomplete: true },
createElement(InternalDateTime, props)
);
}
};
function filterInternalDateTime(option) {
var result = option.result;
/*if (option.result.time && option.result.time._ambiguousAMPM &&
!option.result.timeOfDay) {
return false
} else */if (result.time && result.timeOfDay && isNoonOrMidnight(result.time)) {
return false;
} else if (result.time && result.timeOfDay && !result.time._ambiguousAMPM && !timeIsInAMPM(result.time, result.timeOfDay.impliedAMPM)) {
return false;
}
return true;
}
export var InternalDateTime = {
defaultProps: {
label: 'date and time'
},
mapResult: function mapResult(result) {
var time = result.time;
if (result.timeOfDay && result.time && result.time._ambiguousAMPM) {
time = ambiguousTime(result.time, result.timeOfDay.impliedAMPM);
} else if (result.timeOfDay && !result.time) {
time = { hour: result.timeOfDay.default };
}
var date = result.date && result.date.date;
if (result.relativeDate) {
date = relativeDate(result.relativeDate);
}
// console.log(result)
return {
date: date,
time: time,
_ambiguousYear: result.date && result.date._ambiguousYear,
_ambiguousCentury: result.date && result.date._ambiguousCentury,
_ambiguousWeek: result.date && result.date._ambiguousWeek,
_ambiguousMonth: result.date && result.date._ambiguousMonth,
_ambiguousAMPM: result.time && result.time._ambiguousAMPM,
_specificAMPM: result.time && result.time._specificAMPM
};
},
describe: function describe(_ref4) {
var props = _ref4.props;
return createElement(
'placeholder',
{
label: props.label,
arguments: props.phraseArguments || (props.phraseArguments ? [props.phraseArgument] : [props.label]) },
createElement(
'filter',
{ outbound: filterInternalDateTime, skipIncomplete: true },
createElement(
'choice',
null,
createElement(
'sequence',
{ unique: true },
createElement(
'sequence',
{ merge: true },
createElement(InternalTime, { id: 'time', ellipsis: true, prepositions: props.prepositions, seconds: false }),
createElement(
'sequence',
{ optional: true, limited: true, ellipsis: true, merge: true },
createElement(
'sequence',
{ id: 'timeOfDay', optional: true, limited: true },
createElement('literal', { text: ' the ' }),
createElement(TimeOfDay, { merge: true }),
createElement('literal', { text: ' of' })
),
createElement(
'sequence',
{ id: 'date' },
createElement('literal', { text: ' ' }),
createElement(TrueDate, { merge: true, prepositions: true })
)
),
createElement(
'sequence',
{ id: 'timeOfDay' },
createElement('list', { items: [' ', ' in the '], limit: 1 }),
createElement(TimeOfDay, { merge: true })
)
)
),
createElement(
'sequence',
{ unique: true },
createElement(
'sequence',
{ id: 'timeOfDay', optional: true, limited: true },
createElement('literal', { text: 'the ' }),
createElement(TimeOfDay, { merge: true }),
createElement('literal', { text: ' of ' })
),
createElement(
'choice',
{ merge: true, ellipsis: true },
createElement(TrueDate, { id: 'date', prepositions: props.prepositions }),
createElement(
'sequence',
null,
createElement('literal', { id: 'relativeDate', text: 'this ', value: { day: 0 } }),
createElement(TimeOfDay, { id: 'timeOfDay' })
),
createElement(
'placeholder',
{ label: 'date' },
createElement('literal', { text: 'tonight', value: { relativeDate: { day: 0 }, time: { hour: 20 } } })
)
),
createElement(
'sequence',
{ id: 'timeOfDay', optional: true, limited: true, ellipsis: true },
createElement('list', { items: [' ', ' in the '], limit: 1 }),
createElement(TimeOfDay, { merge: true })
),
createElement(
'sequence',
{ id: 'time', ellipsis: true },
createElement('literal', { text: ' ' }),
createElement(InternalTime, { merge: true, prepositions: true, seconds: false })
),
createElement(
'sequence',
{ id: 'timeOfDay' },
createElement('literal', { text: ' in the ' }),
createElement(TimeOfDay, { merge: true })
)
)
)
)
);
}
};