From 2f377604ee6717cb6ff44ee29e964b6cda1c0fd9 Mon Sep 17 00:00:00 2001 From: Joe Fleming Date: Mon, 18 Dec 2017 12:21:38 -0700 Subject: [PATCH] Feat: Add date type (#271) * feat: add a date type * fix: date function doesn't pass input to moment moment doesn't take generic string input anymore, this relies on the native Date type, unless format is provided * fix: wrap formatdate's context input in Date type moment doesn't allow passing arbitrary strings in --- common/functions/date.js | 33 ++++++++++++++++++++++------- common/functions/formatdate.js | 2 +- common/types/date.js | 38 ++++++++++++++++++++++++++++++++++ common/types/index.js | 2 ++ 4 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 common/types/date.js diff --git a/common/functions/date.js b/common/functions/date.js index 082f63e84e088e..02d95b934db89e 100644 --- a/common/functions/date.js +++ b/common/functions/date.js @@ -1,25 +1,44 @@ import moment from 'moment'; +const getInputDate = (input) => { + // return current date if no input + if (!input) return new Date(); + + // attempt to cast to a number + const numInput = Number(input); + if (!isNaN(numInput)) return numInput; + + // return the input + return input; +}; + export const date = { name: 'date', - type: 'number', + type: 'date', context: { types: ['null'], }, - help: 'Returns the current time, or a time parsed from a string, as milliseconds since epoch', + help: 'Returns the current time, or a time parsed from a string, as milliseconds since epoch.', args: { _: { types: ['string', 'null'], - help: 'An optional date string to parse into milliseconds since epoch', + help: 'An optional date string to parse into milliseconds since epoch. ' + + 'Can be either a valid Javascript Date input or a string to parse using the format argument. ', }, format: { types: ['string', 'null'], - help: 'The momentJS format for parsing the optional date string (See https://momentjs.com/docs/#/displaying/)', + help: 'The momentJS format for parsing the optional date string (See https://momentjs.com/docs/#/displaying/).', }, }, fn: (context, args) => { - if (!args._) return moment().valueOf(); - if (!args.format) return moment(args._).valueOf(); - return moment(args._, args.format).valueOf(); + const inputDate = getInputDate(args._); + const outputDate = (args._ && args.format) ? moment(inputDate, args.format).toDate() : new Date(inputDate); + + if (isNaN(outputDate.getTime())) throw new Error(`Invalid date input: ${args._}`); + + return { + type: 'date', + value: outputDate, + }; }, }; diff --git a/common/functions/formatdate.js b/common/functions/formatdate.js index c4e24006a5147c..3a471bbc4912ed 100644 --- a/common/functions/formatdate.js +++ b/common/functions/formatdate.js @@ -14,6 +14,6 @@ export const formatdate = { }, }, fn: (context, args) => { - return moment(context).format(args._); + return moment(new Date(context)).format(args._); }, }; diff --git a/common/types/date.js b/common/types/date.js new file mode 100644 index 00000000000000..4554d5bfb8c3a9 --- /dev/null +++ b/common/types/date.js @@ -0,0 +1,38 @@ +export const date = { + name: 'date', + from: { + number: n => ({ + type: 'date', + value: new Date(n), + }), + string: s => ({ + type: 'date', + value: new Date(s), + }), + }, + to: { + string: d => d.value.toISOString(), + number: d => d.value.getTime(), + render: d => { + return { + type: 'render', + as: 'markdown', + value: { + content: String(d.value.toISOString()), + }, + }; + }, + datatable: (d) => { + return { + type: 'datatable', + columns: [ + { + name: 'value', + type: 'date', + }, + ], + rows: [{ value: d.value.getTime() }], + }; + }, + }, +}; diff --git a/common/types/index.js b/common/types/index.js index de2220f80a5252..fcb76ddc2d2e1e 100644 --- a/common/types/index.js +++ b/common/types/index.js @@ -1,6 +1,7 @@ import { boolean } from './boolean'; import { datatable } from './datatable'; import { dataurl } from './dataurl'; +import { date } from './date'; import { error } from './error'; import { filter } from './filter'; import { image } from './image'; @@ -16,6 +17,7 @@ export const typeSpecs = [ boolean, datatable, dataurl, + date, error, filter, image,