UNPKG

fluro

Version:

Promise based HTTP Fluro client for the browser and node.js

898 lines (632 loc) 34.3 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>fluro.date.js - Documentation</title> <script src="scripts/prettify/prettify.js"></script> <script src="scripts/prettify/lang-css.js"></script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc.css"> <script src="scripts/nav.js" defer></script> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <input type="checkbox" id="nav-trigger" class="nav-trigger" /> <label for="nav-trigger" class="navicon-button x"> <div class="navicon"></div> </label> <label for="nav-trigger" class="overlay"></label> <nav > <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="access.html">access</a><ul class='methods'><li data-type='method'><a href="access.html#.addEventListener">addEventListener</a></li><li data-type='method'><a href="access.html#.can">can</a></li><li data-type='method'><a href="access.html#.canDeleteItem">canDeleteItem</a></li><li data-type='method'><a href="access.html#.canEditItem">canEditItem</a></li><li data-type='method'><a href="access.html#.canKnowOf">canKnowOf</a></li><li data-type='method'><a href="access.html#.canViewItem">canViewItem</a></li><li data-type='method'><a href="access.html#.has">has</a></li><li data-type='method'><a href="access.html#.isAuthor">isAuthor</a></li><li data-type='method'><a href="access.html#.removeAllListeners">removeAllListeners</a></li><li data-type='method'><a href="access.html#.removeEventListener">removeEventListener</a></li><li data-type='method'><a href="access.html#.retrieveActionableRealms">retrieveActionableRealms</a></li><li data-type='method'><a href="access.html#.retrieveCurrentSession">retrieveCurrentSession</a></li><li data-type='method'><a href="access.html#.setDefaultApplication">setDefaultApplication</a></li></ul></li><li><a href="api.html">api</a><ul class='methods'><li data-type='method'><a href="api.html#.delete">delete</a></li><li data-type='method'><a href="api.html#.generateEndpointURL">generateEndpointURL</a></li><li data-type='method'><a href="api.html#.get">get</a></li><li data-type='method'><a href="api.html#.post">post</a></li><li data-type='method'><a href="api.html#.put">put</a></li></ul></li><li><a href="app.device.html">device</a></li><li><a href="asset.html">asset</a><ul class='methods'><li data-type='method'><a href="asset.html#.avatarUrl">avatarUrl</a></li><li data-type='method'><a href="asset.html#.downloadUrl">downloadUrl</a></li><li data-type='method'><a href="asset.html#.filesize">filesize</a></li><li data-type='method'><a href="asset.html#.getUrl">getUrl</a></li><li data-type='method'><a href="asset.html#.imageUrl">imageUrl</a></li><li data-type='method'><a href="asset.html#.playerUrl">playerUrl</a></li><li data-type='method'><a href="asset.html#.posterUrl">posterUrl</a></li><li data-type='method'><a href="asset.html#.typeFromMime">typeFromMime</a></li></ul></li><li><a href="auth.html">auth</a><ul class='methods'><li data-type='method'><a href="auth.html#.addEventListener">addEventListener</a></li><li data-type='method'><a href="auth.html#.changeAccount">changeAccount</a></li><li data-type='method'><a href="auth.html#.getCurrentToken">getCurrentToken</a></li><li data-type='method'><a href="auth.html#.getCurrentUser">getCurrentUser</a></li><li data-type='method'><a href="auth.html#.impersonate">impersonate</a></li><li data-type='method'><a href="auth.html#.login">login</a></li><li data-type='method'><a href="auth.html#.logout">logout</a></li><li data-type='method'><a href="auth.html#.refreshAccessToken">refreshAccessToken</a></li><li data-type='method'><a href="auth.html#.removeAllListeners">removeAllListeners</a></li><li data-type='method'><a href="auth.html#.removeEventListener">removeEventListener</a></li><li data-type='method'><a href="auth.html#.retrieveUserFromResetToken">retrieveUserFromResetToken</a></li><li data-type='method'><a href="auth.html#.sendResetPasswordRequest">sendResetPasswordRequest</a></li><li data-type='method'><a href="auth.html#.set">set</a></li><li data-type='method'><a href="auth.html#.signup">signup</a></li><li data-type='method'><a href="auth.html#.updateUserWithToken">updateUserWithToken</a></li></ul></li><li><a href="cache.html">cache</a><ul class='methods'><li data-type='method'><a href="cache.html#.get">get</a></li><li data-type='method'><a href="cache.html#.reset">reset</a></li></ul></li><li><a href="components.html">components</a><ul class='methods'><li data-type='method'><a href="components.html#.hydrateModel">hydrateModel</a></li></ul></li><li><a href="content.html">content</a><ul class='methods'><li data-type='method'><a href="content.html#.duplicate">duplicate</a></li><li data-type='method'><a href="content.html#.external">external</a></li><li data-type='method'><a href="content.html#.filter">filter</a></li><li data-type='method'><a href="content.html#.form">form</a></li><li data-type='method'><a href="content.html#.get">get</a></li><li data-type='method'><a href="content.html#.getMultiple">getMultiple</a></li><li data-type='method'><a href="content.html#.keys">keys</a></li><li data-type='method'><a href="content.html#.list">list</a></li><li data-type='method'><a href="content.html#.query">query</a></li><li data-type='method'><a href="content.html#.related">related</a></li><li data-type='method'><a href="content.html#.retrieve">retrieve</a></li><li data-type='method'><a href="content.html#.slug">slug</a></li><li data-type='method'><a href="content.html#.submitInteraction">submitInteraction</a></li><li data-type='method'><a href="content.html#.submitPost">submitPost</a></li><li data-type='method'><a href="content.html#.thread">thread</a></li><li data-type='method'><a href="content.html#.values">values</a></li></ul></li><li><a href="date.html">date</a><ul class='methods'><li data-type='method'><a href="date.html#.countdown">countdown</a></li><li data-type='method'><a href="date.html#.dateFromID">dateFromID</a></li><li data-type='method'><a href="date.html#.formatDate">formatDate</a></li><li data-type='method'><a href="date.html#.getAge">getAge</a></li><li data-type='method'><a href="date.html#.groupEventByDate">groupEventByDate</a></li><li data-type='method'><a href="date.html#.isDifferentTimezoneThanUser">isDifferentTimezoneThanUser</a></li><li data-type='method'><a href="date.html#.isMultiDayEvent">isMultiDayEvent</a></li><li data-type='method'><a href="date.html#.localDate">localDate</a></li><li data-type='method'><a href="date.html#.militaryTimestamp">militaryTimestamp</a></li><li data-type='method'><a href="date.html#.readableEventDate">readableEventDate</a></li><li data-type='method'><a href="date.html#.readableEventTime">readableEventTime</a></li><li data-type='method'><a href="date.html#.timeago">timeago</a></li><li data-type='method'><a href="date.html#.timeline">timeline</a></li><li data-type='method'><a href="date.html#.timestampToAmPm">timestampToAmPm</a></li><li data-type='method'><a href="date.html#.timezones">timezones</a></li></ul></li><li><a href="fluro.html">fluro</a></li><li><a href="types.html">types</a><ul class='methods'><li data-type='method'><a href="types.html#.all">all</a></li><li data-type='method'><a href="types.html#.basicTypes">basicTypes</a></li><li data-type='method'><a href="types.html#.get">get</a></li><li data-type='method'><a href="types.html#.mapDefinitionItems">mapDefinitionItems</a></li><li data-type='method'><a href="types.html#.parentType">parentType</a></li><li data-type='method'><a href="types.html#.postableTypes">postableTypes</a></li><li data-type='method'><a href="types.html#.readable">readable</a></li><li data-type='method'><a href="types.html#.reloadTerminology">reloadTerminology</a></li><li data-type='method'><a href="types.html#.retrieve">retrieve</a></li><li data-type='method'><a href="types.html#.subTypes">subTypes</a></li><li data-type='method'><a href="types.html#.term">term</a></li></ul></li><li><a href="utils.html">utils</a><ul class='methods'><li data-type='method'><a href="utils.html#.arrayIDs">arrayIDs</a></li><li data-type='method'><a href="utils.html#.comma">comma</a></li><li data-type='method'><a href="utils.html#.currencySymbol">currencySymbol</a></li><li data-type='method'><a href="utils.html#.errorMessage">errorMessage</a></li><li data-type='method'><a href="utils.html#.extractFromArray">extractFromArray</a></li><li data-type='method'><a href="utils.html#.formatCurrency">formatCurrency</a></li><li data-type='method'><a href="utils.html#.getDefaultValueForField">getDefaultValueForField</a></li><li data-type='method'><a href="utils.html#.getFlattenedFields">getFlattenedFields</a></li><li data-type='method'><a href="utils.html#.getStringID">getStringID</a></li><li data-type='method'><a href="utils.html#.guid">guid</a></li><li data-type='method'><a href="utils.html#.hash">hash</a></li><li data-type='method'><a href="utils.html#.injectScript">injectScript</a></li><li data-type='method'><a href="utils.html#.machineName">machineName</a></li><li data-type='method'><a href="utils.html#.mapParameters">mapParameters</a></li><li data-type='method'><a href="utils.html#.matchInArray">matchInArray</a></li><li data-type='method'><a href="utils.html#.processCardPrioritySort">processCardPrioritySort</a></li></ul></li><li><a href="video.html">video</a><ul class='methods'><li data-type='method'><a href="video.html#.hhmmss">hhmmss</a></li><li data-type='method'><a href="video.html#.readableMilliseconds">readableMilliseconds</a></li><li data-type='method'><a href="video.html#.readableSeconds">readableSeconds</a></li></ul></li></ul> </nav> <div id="main"> <h1 class="page-title">fluro.date.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>import _ from 'lodash'; import moment from 'moment-timezone'; import FluroUtils from './fluro.utils'; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// var DEFAULT_TIMEZONE; if (!(typeof window === 'undefined')) { DEFAULT_TIMEZONE = Intl.DateTimeFormat().resolvedOptions().timeZone; } /////////////////////////////////////////////////////////////////////////////// /** * @alias date * @classdesc A static service that provides useful functions for working with dates and timestamps. * @class * @hideconstructor */ const FluroDate = { defaultTimezone: DEFAULT_TIMEZONE, moment, } /////////////////////////////////////////////////////////////////////////////// /** * A function that returns all of the available timezones. Often used to populate a select box * @alias date.timezones * @return {Array} An array of all availble timezones. */ FluroDate.timezones = function() { return moment.tz.names(); } /////////////////////////////////////////////////////////////////////////////// /** * A function that converts a timestamp string '7:30' to '0730'; * @alias date.militaryTimestamp * @return {String} */ FluroDate.militaryTimestamp = function(input, withColon) { var s = input; if (!s || !String(s)) { console.log('reset to 0000', input) s = '0000'; } s = String(parseInt(String(s).split(':').join(''))).slice(0, 4); if (s.length &lt; 1) { s = '0000' + s; } else if (s.length &lt; 2) { s = '000' + s; } else if (s.length &lt; 3) { s = '00' + s; } else if (s.length &lt; 4) { s = '0' + s; } var hours = parseInt(s.substring(0, 2)); var mins = parseInt(s.substring(2)); hours = Math.max(hours, 0) mins = Math.max(mins, 0) hours = Math.min(hours, 23) mins = Math.min(mins, 59) if (String(hours).length &lt; 2) { hours = `0${hours}`; } if (String(mins).length &lt; 2) { mins = `0${mins}`; } if (withColon) { return `${hours}:${mins}`; } else { return `${hours}${mins}`; } } /////////////////////////////////////////////////////////////////////////////// /** * A function that converts a timestamp string '13:30' to '1:30pm'; * @alias date.timestampToAmPm * @return {String} A formatted timestamp string */ FluroDate.timestampToAmPm = function(input) { var s = FluroDate.militaryTimestamp(input); var am = true; var hours = parseInt(s.substring(0, 2)); var mins = parseInt(s.substring(2)); if (hours > 12) { am = false; hours = hours - 12; } hours = Math.max(hours, 0) mins = Math.max(mins, 0) hours = Math.min(hours, 12) mins = Math.min(mins, 59) if (String(mins).length &lt; 2) { mins = `0${mins}`; } return `${hours}:${mins}${am ? 'am' : 'pm'}`; // return s; } /////////////////////////////////////////////////////////////////////////////// FluroDate.currentTimezone = function() { return moment.tz.guess(); } /////////////////////////////////////////////////////////////////////////////// /** * A function that returns all of the available timezones. Often used to populate a select box * @alias date.isDifferentTimezoneThanUser * @return {Boolean} True if the specified timezone is different than the viewing user */ FluroDate.isDifferentTimezoneThanUser = function(timezone) { var browserTimezone = moment.tz.guess(); if (!timezone) { // console.log('NO TIMEZONE') return false; } timezone = String(timezone); if (browserTimezone == timezone) { // console.log('TIMEZONE IS SAME') return false; } var now = new Date(); var current = moment.tz(now, browserTimezone).utcOffset(); var checked = moment.tz(now, timezone).utcOffset(); if (current == checked) { return false; } return true; } /////////////////////////////////////////////////////////////////////////////// /** * A function that will return a date in context of a specified timezone * If no timezone is specified then the default timezone of the current clock will be used. * This will return dates that are incorrect on purpose. So that it can appear to the user as if they were in another timezone. * As Javascript dates are always in the context of the timezone they are being viewed in, this function will give you a date that is technically * not the Universal point in time of the date, but rather a time that reads in your timezone as if you were in the specified timezone. * @alias date.localDate * @param {Date} date Either a javascript date object, or a string timestamp representing a javascript date object * @param {String} specifiedTimezone The timezone to retrieve the date in eg. Australia/Melbourne * @return {Date} A javascript date object transformed to match the specified timezone */ FluroDate.localDate = function(d, specifiedTimezone) { // console.log('LOCAL DATE', d, specifiedTimezone); //Date var date; // = new Date(d); if (!d) { date = new Date(); } else { date = new Date(d); } /////////////////////////////////////////// var timezoneOffset; var browserOffset = date.getTimezoneOffset(); /////////////////////////////////////////// // if (!specifiedTimezone) { // specifiedTimezone = FluroDate.defaultTimezone; // } if (specifiedTimezone) { timezoneOffset = moment.tz(date, specifiedTimezone).utcOffset(); browserOffset = moment(date).utcOffset(); var difference = (timezoneOffset - browserOffset); var offsetDifference = difference * 60 * 1000; var prevDate = new Date(date); date.setTime(date.getTime() + offsetDifference); } return date; } /////////////////////////////////////////////////////////////////////////////// /** * A helpful function that can quickly get an age from a supplied date string * @alias date.getAge * @return {Integer} The age in years * @example * fluro.date.getAge('2019-04-18T23:00:00.000Z') */ FluroDate.getAge = function(dateInput) { var date = FluroDate.localDate(dateInput); // var today = new Date(); var birthDate = new Date(dateInput); var age = today.getFullYear() - birthDate.getFullYear(); var m = today.getMonth() - birthDate.getMonth(); //If the date is on the cusp of the new year if (m &lt; 0 || (m === 0 &amp;&amp; today.getDate() &lt; birthDate.getDate())) { age--; } return age; } /////////////////////////////////////////////////////////////////////////////// /** * Parses a date and returns a human readable date string * @param {Date|String} date The date or string to parse * @param {String} format A string representing the format to output for formatting syntax see https://momentjs.com/docs/#/displaying/format/ * @param {String} timezone The timezone to use if needing to translate the date to another timezone eg. Australia/Melbourne * @return {String} A human readable string * @example * var date = new Date() * return fluro.date.formatDate(date, 'h:mma DDD MMM YYYY') * * var dateString = '2019-04-18T23:00:00.000Z' * return fluro.date.formatDate(dateString, 'D M YYYY', 'Australia/Melbourne') */ FluroDate.formatDate = function(dateString, format, timezone) { var date = FluroDate.localDate(dateString, timezone); if (timezone) { return moment(date).format(format); var d = moment(dateString).tz(timezone).format(format); // // console.log('DATE', dateString, d, timezone, format) return d; } else { return moment(date).format(format); } } /** * Parses a date and returns a 'timeago' string * @param {Date|String} date The date or string to parse * @return {String} A human readable string * @example * var date = new Date() * * //Returns 10 mins ago * return fluro.date.timeago(date) */ FluroDate.timeago = function(date, suffix) { return moment(date).fromNow(suffix); } /** * Parses an ObjectID and returns the date of creation * @param {String} id The id of the object to parse * @param {String} format A string representing the format to output for formatting syntax see https://momentjs.com/docs/#/displaying/format/ * @param {String} timezone The timezone to use if needing to translate the date to another timezone eg. Australia/Melbourne * @return {String} A human readable string * @example * * var id = '5ca3d64dd2bb085eb9d450db' * return dateFromID.formatDate(id, 'D M YYYY') */ FluroDate.dateFromID = function(id, format, timezone) { id = FluroUtils.getStringID(id); var date = new Date(parseInt(id.substring(0, 8), 16) * 1000); return FluroDate.formatDate(date, format, timezone); } /////////////////////////////////////// /** * Checks whether an event spans over multiple days * @param {Object} event A Fluro event object with a startDate and an endDate * @return {Boolean} True or False if the event spans multiple days * @example * * return fluro.date.isMultiDayEvent({startDate:...}) */ FluroDate.isMultiDayEvent = function(event) { var startDate; var endDate; //////////////////////////////////////// if (!event) return; //////////////////////////////////////// if (event.startDate) { startDate = FluroDate.localDate(event.startDate, event.timezone); } else { return; } if (!event.endDate) { return; } /////////////////////////////////////////////// endDate = FluroDate.localDate(event.endDate, event.timezone); /////////////////////////////////////////////// startDate = moment(startDate); endDate = moment(endDate); //////////////////////////////////////// return (String(startDate.format('D MMM YYYY')) != String(endDate.format('D MMM YYYY'))); } /////////////////////////////////////// /** * A helper function that can display a human-readable date for an event * taking into consideration the context of the current time, the event's start and end time. * This is often used as a string filter * and what is relevant * @alias date.readableEventDate * @param {Object} event An object that has both a startDate and endDate property, Usually an event object from the Fluro API * @param {String} style Whether to return a 'short', 'medium' or 'long' date * @return {String} The human readable date for the event * @example * //Returns 5:30pm 1 May * fluro.date.readableEventDate({"startDate": "2019-05-01T07:30:00.000Z", "endDate":"2019-05-01T07:30:00.000Z"}) * //Returns 5:30pm - 7:30pm 1 May * fluro.date.readableEventDate({"startDate": "2019-05-01T07:30:00.000Z", "endDate":"2019-05-01T09:30:00.000Z"}) * //Returns 1 - 5 May 2015 * fluro.date.readableEventDate({"startDate": "2015-05-01T07:30:00.000Z", "endDate":"2015-05-05T09:30:00.000Z"}) * //1 May - 21 Jun 2019 * fluro.date.readableEventDate({"startDate": "2019-05-01T07:30:00.000Z", "endDate":"2019-06-21T09:30:00.000Z"}) */ FluroDate.readableEventDate = function(event, style) { //////////////////////////////////////// var startDate; var endDate; //////////////////////////////////////// if (!event) return; //////////////////////////////////////// if (event.startDate) { startDate = FluroDate.localDate(event.startDate, event.timezone); } else { return; } if (event.endDate) { endDate = FluroDate.localDate(event.endDate, event.timezone); } else { endDate = startDate; } /////////////////////////////////////////////// var differentTimezone = event.timezone &amp;&amp; FluroDate.isDifferentTimezoneThanUser(event.timezone); var appendage = ''; if (differentTimezone) { appendage = `(${event.timezone})`; } /////////////////////////////////////////////// startDate = moment(startDate); endDate = moment(endDate); /////////////////////////////////////////////// var noEndDate = startDate.format('h:mma D MMM YYYY') == endDate.format('h:mma D MMM YYYY'); var sameYear = (startDate.format('YYYY') == endDate.format('YYYY')); var sameMonth = (startDate.format('MMM YYYY') == endDate.format('MMM YYYY')); var sameDay = (startDate.format('D MMM YYYY') == endDate.format('D MMM YYYY')); switch (style) { case 'short': // console.log('SHORT', startDate, endDate); if (noEndDate) { return `${startDate.format('D MMM')} ${appendage}` } if (sameDay) { //8am - 9am Thursday 21 May 2016 return `${startDate.format('D MMM')} ${appendage}` } if (sameMonth) { //20 - 21 May 2016 return `${startDate.format('D') + ' - ' + endDate.format('D MMM')} ${appendage}` } if (sameYear) { //20 Aug - 21 Sep 2016 return `${startDate.format('D') + ' - ' + endDate.format('D MMM')} ${appendage}` } //20 Aug 2015 - 21 Sep 2016 return `${startDate.format('D MMM Y') + ' - ' + endDate.format('D MMM Y')} ${appendage}` break; case 'day': // console.log('SHORT', startDate, endDate); if (noEndDate) { return `${startDate.format('dddd D MMMM')} ${appendage}` } if (sameDay) { //8am - 9am Thursday 21 May 2016 return `${startDate.format('dddd D MMMM')} ${appendage}` } if (sameMonth) { //20 - 21 May 2016 return `${startDate.format('D') + ' - ' + endDate.format('D MMMM Y')} ${appendage}` } if (sameYear) { //20 Aug - 21 Sep 2016 return `${startDate.format('D MMM') + ' - ' + endDate.format('D MMM Y')} ${appendage}` } //20 Aug 2015 - 21 Sep 2016 return `${startDate.format('D MMM Y') + ' - ' + endDate.format('D MMM Y')} ${appendage}` break; default: if (noEndDate) { return `${startDate.format('h:mma dddd D MMM Y')} ${appendage}`; } if (sameDay) { //8am - 9am Thursday 21 May 2016 return `${startDate.format('h:mma') + ' - ' + endDate.format('h:mma dddd D MMM Y')} ${appendage}`; } if (sameMonth) { //20 - 21 May 2016 return `${startDate.format('D') + ' - ' + endDate.format('D MMM Y')} ${appendage}`; } if (sameYear) { //20 Aug - 21 Sep 2016 return `${startDate.format('D MMM') + ' - ' + endDate.format('D MMM Y')} ${appendage}`; } //20 Aug 2015 - 21 Sep 2016 return `${startDate.format('D MMM Y') + ' - ' + endDate.format('D MMM Y')} ${appendage}`; break; } } /////////////////////////////////////// /** * A helper function that can display a human-readable time for an event * taking into consideration the context of the current time, the event's start and end time. * This is often used as a string filter * @alias date.readableEventTime * @param {Object} event An object that has both a startDate and endDate property, Usually an event object from the Fluro API * @return {String} The human readable time for the event * @example * //Returns 5:30pm * fluro.date.readableEventTime({"startDate": "2019-05-01T07:30:00.000Z", "endDate":null}) * //Returns 5:30pm - 7:30pm * fluro.date.readableEventTime({"startDate": "2019-05-01T07:30:00.000Z", "endDate":"2019-05-01T09:30:00.000Z"}) */ FluroDate.readableEventTime = function(event) { //////////////////////////////////////// var startDate; var endDate; //////////////////////////////////////// if (!event) return; //////////////////////////////////////// if (event.startDate) { startDate = FluroDate.localDate(event.startDate, event.timezone); } else { return; } if (event.endDate) { endDate = FluroDate.localDate(event.endDate, event.timezone); } else { endDate = startDate; } /////////////////////////////////////////////// startDate = moment(startDate); endDate = moment(endDate); /////////////////////////////////////////////// var noEndDate = startDate.format('h:mma D MMM YYYY') == endDate.format('h:mma D MMM YYYY'); var sameYear = (startDate.format('YYYY') == endDate.format('YYYY')); var sameMonth = (startDate.format('MMM YYYY') == endDate.format('MMM YYYY')); var sameDay = (startDate.format('D MMM YYYY') == endDate.format('D MMM YYYY')); if (noEndDate) { return startDate.format('h:mma') } if (sameDay) { //8am - 9am Thursday 21 May 2016 return startDate.format('h:mma') + ' - ' + endDate.format('h:mma'); } return FluroDate.readableEventDate(event); } /////////////////////////////////////// /** * @alias date.groupEventByDate * @param {Array} events The events we want to group * @return {Array} A grouped array of dates and events */ FluroDate.groupEventByDate = function(events) { return _.chain(events) .reduce(function(set, row, index) { var format = 'dddd D MMMM'; //////////////////////////////////// var startDate = new moment(row.startDate || _.get(row, 'event.startDate') || _.get(row, 'roster.event.startDate') || row.created); var timezone = row.timezone || _.get(row, 'event.timezone') || _.get(row, 'roster.event.timezone'); if (timezone) { startDate.tz(timezone); } //////////////////////////////////// // var startDate = row.startDate ? new moment(row.startDate) : new moment(row.created); if (moment().format('YYYY') != startDate.format('YYYY')) { format = 'dddd D MMMM YYYY'; } var groupingKey = startDate.format(format); var existing = set[groupingKey]; if (!existing) { existing = set[groupingKey] = { title: groupingKey, items: [], index, } } existing.items.push(row); return set; }, {}) .values() .orderBy('index') .value(); } /////////////////////////////////////// /** * @alias date.timeline * @param {Array} items The items we want to group on the timeline * @return {Array} A grouped array of dates */ FluroDate.timeline = function(items, dateKey, chronological) { if (!dateKey) { dateKey = 'created'; } ////////////////////////////////// items = _.orderBy(items, function(entry) { var date = new Date(_.get(entry, dateKey)); return date; }) ////////////////////////////////// if (chronological) { //Leave in the same order } else { items = items.reverse(); } ////////////////////////////////// return _.chain(items) .reduce(function(set, entry, index, options) { var date = new Date(_.get(entry, dateKey)); var valid = date instanceof Date &amp;&amp; !isNaN(date); if(!valid) { return set; } //////////////////////////////////////// var dayKey; var monthKey; var yearKey; var specifiedTimezone = options.timezone || entry.timezone; if (specifiedTimezone &amp;&amp; FluroDate.isDifferentTimezoneThanUser(specifiedTimezone)) { dayKey = `${moment(date).tz(specifiedTimezone).format('D MMM YYYY')}`; // (${specifiedTimezone})`; monthKey = `${moment(date).tz(specifiedTimezone).format('MMM YYYY')}`; // (${specifiedTimezone})`; yearKey = `${moment(date).tz(specifiedTimezone).format('YYYY')}`; // (${specifiedTimezone})`; } else { dayKey = moment(date).format('D MMM YYYY'); monthKey = moment(date).format('MMM YYYY'); yearKey = moment(date).format('YYYY'); } //////////////////////////////////////// //Check if we already have an entry for this year var existingYear = set.lookup[yearKey]; if (!existingYear) { existingYear = set.lookup[yearKey] = { date, months: [], } //console.log('Push to year', set.years) //Add the year to our results set.years.push(existingYear); } //////////////////////////////////////// //Check if we already have an entry for this month var existingMonth = set.lookup[monthKey]; if (!existingMonth) { existingMonth = set.lookup[monthKey] = { date, days: [], } // console.log('Push to month', existingYear) existingYear.months.push(existingMonth); } //////////////////////////////////////// //Check if we already have an entry for this month var existingDay = set.lookup[dayKey]; if (!existingDay) { existingDay = set.lookup[dayKey] = { date, items: [], } // console.log('Push to day', existingMonth) existingMonth.days.push(existingDay); } // console.log('Push to item', existingDay) existingDay.items.push(entry); return set; }, { lookup: {}, years: [] }) .get('years') .value(); } /////////////////////////////////////// /** * A helper function that can return the pieces for a countdown clock relative to a specified date * @alias date.countdown * @param {Date} date The date we are counting down to * @return {Object} An object with days, minutes, hours, seconds, */ FluroDate.countdown = function(date, zeroPadded) { var now = new Date().getTime(); //////////////////////////////////////// var when = new Date(date).getTime(); var milliseconds = when - now; var oneSecond = 1000; var oneMinute = oneSecond * 60; var oneHour = oneMinute * 60; var oneDay = oneHour * 24; var seconds = (milliseconds % oneMinute) / oneSecond; var minutes = Math.floor((milliseconds % oneHour) / oneMinute); var hours = Math.floor((milliseconds % oneDay) / oneHour); var days = Math.floor(milliseconds / oneDay); if (zeroPadded) { function pad(input) { input = Math.ceil(input); if (String(input).length == 1) { return `0${input}`; } return String(input); } return { days: pad(days), minutes: pad(minutes), hours: pad(hours), seconds: pad(seconds), } } return { days, minutes, hours, seconds: Math.ceil(seconds), } } /////////////////////////////////////////////////////////////////////////////// export default FluroDate;</code></pre> </article> </section> </div> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.3</a> on Tue Jun 29 2021 08:38:17 GMT+1000 (Australian Eastern Standard Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme. </footer> <script>prettyPrint();</script> <script src="scripts/polyfill.js"></script> <script src="scripts/linenumber.js"></script> </body> </html>