/** * JTSage-DateBox * @fileOverview Widget binder. Used only in the test enviroment. * @author J.T.Sage <jtsage+datebox@gmail.com> * @author {@link https://github.com/jtsage/jtsage-datebox/contributors|GitHub Contributors} * @license {@link https://github.com/jtsage/jtsage-datebox/blob/master/LICENSE.txt|MIT} * @version 5.2.0 */ /** * Enhance the date object for easier use. * * These are direct extensions to the JavaScript date object * * All methods are also chainable, which is not true of some implementations * in a browser. * * @memberOf JTSageDateBox * @namespace JTSageDateBox._enhanceDate */ JTSageDateBox._enhanceDate = function() { Object.assign(this._date.prototype, { /** * Return a copy of the date, not altering the original * * You may specify partial arrays only as deep as the most * precise element you want to adjust or override. Zeros will * not alter that element. Overrides takes precedence over adjustments * * @param {array} adjust [y,m,d,h,i,s,ms] Adjust part of the date * @param {array} override [y,m,d,h,i,s,ms] Override part of the date * @return {object} JavaScript date object * @memberOf JTSageDateBox._enhanceDate */ copy : function( adjust, override ) { adjust = Object.assign( [0,0,0,0,0,0,0], adjust ); override = Object.assign( [0,0,0,0,0,0,0], override ); return new Date( ( ( override[ 0 ] > 0 ) ? override[ 0 ] : this.get( 0 ) + adjust[ 0 ] ), ( ( override[ 1 ] > 0 ) ? override[ 1 ] : this.get( 1 ) + adjust[ 1 ] ), ( ( override[ 2 ] > 0 ) ? override[ 2 ] : this.get( 2 ) + adjust[ 2 ] ), ( ( override[ 3 ] > 0 ) ? override[ 3 ] : this.get( 3 ) + adjust[ 3 ] ), ( ( override[ 4 ] > 0 ) ? override[ 4 ] : this.get( 4 ) + adjust[ 4 ] ), ( ( override[ 5 ] > 0 ) ? override[ 5 ] : this.get( 5 ) + adjust[ 5 ] ), ( ( override[ 6 ] > 0 ) ? override[ 5 ] : this.get( 6 ) + adjust[ 6 ] )); }, /** * Adjust the date by a relative amount. * @param {number} type Element to shift, 0 = year, 5 = seconds * @param {number} amount Offset amount, positive or negative * @return {object} JavaScript date object * @memberOf JTSageDateBox._enhanceDate */ adj : function (type, amount) { // Adjust the date. Yes, this is chainable if ( typeof amount !== "number" || typeof type !== "number" ) { throw new Error( "Invalid Arguments" ); } switch ( type ) { case 0 : this.setD( 0, this.get( 0 ) + amount ); break; case 1 : this.setD( 1, this.get( 1 ) + amount ); break; case 2 : this.setD( 2, this.get( 2 ) + amount ); break; case 3 : amount *= 60; /* falls through */ case 4 : amount *= 60; /* falls through */ case 5 : amount *= 1000; /* falls through */ case 6 : this.setTime( this.getTime() + amount ); break; } return this; }, /** * Set part of the date, chainable * * @param {number} type Element to set, 0 = year, 5 = seconds * @param {number} amount Value to set * @return {object} JavaScript date object * @memberOf JTSageDateBox._enhanceDate */ setD : function(type, amount) { // A chainable version of setWhatever() switch ( type ) { case 0 : this.setFullYear( amount ); break; case 1 : this.setMonth( amount ); break; case 2 : this.setDate( amount ); break; case 3 : this.setHours( amount ); break; case 4 : this.setMinutes( amount ); break; case 5 : this.setSeconds( amount ); break; case 6 : this.setMilliseconds( amount ); break; } return this; }, /** * Get part of the date * * @param {number} type Element to set, 0 = year, 5 = seconds * @return {number} Date part * @memberOf JTSageDateBox._enhanceDate */ get : function(type) { // Chainable version of get. Also shorter. switch ( type ) { case 0 : return this.getFullYear(); case 1 : return this.getMonth(); case 2 : return this.getDate(); case 3 : return this.getHours(); case 4 : return this.getMinutes(); case 5 : return this.getSeconds(); case 6 : return this.getMilliseconds(); } return false; }, /** * Get the hour in 12 hour format - midnight = 12, 13:00 = 1 * @return {number} Hour * @memberOf JTSageDateBox._enhanceDate */ get12hr : function() { if ( this.get( 3 ) === 0 ) { return 12; } if ( this.get( 3 ) < 13 ) { return this.get( 3 ); } return this.get( 3 ) - 12; }, /** * Get an ISO-8601 version of the date : YYYY-MM-DD * * @return {string} ISO-8601 String * @memberOf JTSageDateBox._enhanceDate */ iso : function() { var arr = [0,0,0], i = 0; for ( i=0; i < 3; i++ ) { arr[ i ] = this.get( i ); if ( i === 1 ) { arr[ i ]++; } if ( arr[i] < 10 ) { arr[ i ] = "0" + String( arr[ i ] ); } } return arr.join( "-" ); }, /** * Retrieve a numericly comparable representation of the date : YYYYMMDD * * @return {number} Date as an integer * @memberOf JTSageDateBox._enhanceDate */ comp : function () { return parseInt( this.iso().replace( /-/g, "" ), 10 ); }, /** * Get the number of seconds since epoch * * @return {number} Seconds * @memberOf JTSageDateBox._enhanceDate */ getEpoch : function() { return Math.floor( this.getTime() / 1000 ); }, /** * Get the number of days since epoch * * @return {number} Days * @memberOf JTSageDateBox._enhanceDate */ getEpochDays : function() { return Math.floor( this.getTime() / ( 1000*60*60*24 ) ); }, /** * Get the date as an array * * @return {array} [y,m,d,h,i,s] * @memberOf JTSageDateBox._enhanceDate */ getArray : function() { var arr = [ 0, 0, 0, 0, 0, 0 ], i = 0; for ( i = 0; i < 6; i++ ) { arr[i] = this.get( i ); } return arr; }, /** * Set date to the first valid day of the current month. * * @param {number} day Day of week. Zero based * @return {object} JavaScript date object * @memberOf JTSageDateBox._enhanceDate */ setFirstDay : function (day) { // Grabs first valid (day) of current month this.setD( 2, 1 ).adj( 2, ( day - this.getDay() ) ); if ( this.get( 2 ) > 10 ) { this.adj( 2, 7 ); } return this; }, /** * Set the week number. * * Types : * - 0 : Sunday Based * - 1 : Monday Based * - 4 : Thursday Based (ISO-8601 standard) * * @param {number} type Type of week calculation. Day of week probably * @param {number} number Week number * @return {object} JavaScript date object * @memberOf JTSageDateBox._enhanceDate */ setDWeek : function (type,num) { if ( type === 4 ) { return this.setD(1,0).setD(2,1).setFirstDay(4).adj(2,-3).adj(2,(num-1)*7); } return this.setD(1,0).setD(2,1).setFirstDay(type).adj(2,(num-1)*7); }, /** * Get the week number. * * Types : * - 0 : Sunday Based * - 1 : Monday Based * - 4 : Thursday Based (ISO-8601 standard) * * @param {number} type Type of calculation * @return {number} Week number * @memberOf JTSageDateBox._enhanceDate */ getDWeek : function (type) { var t1, t2; switch ( type ) { case 0: t1 = this.copy([0,-1*this.getMonth()]).setFirstDay(0); return Math.floor( ( this.getTime() - ( t1.getTime() + ( ( this.getTimezoneOffset() - t1.getTimezoneOffset() ) * 60000 ))) / 6048e5 ) + 1; case 1: t1 = this.copy([0,-1*this.getMonth()]).setFirstDay(1); return Math.floor( ( this.getTime() - ( t1.getTime() + ( ( this.getTimezoneOffset() - t1.getTimezoneOffset() ) * 60000 ))) / 6048e5 ) + 1; case 4: // this line is some bullshit. but it does work. // (trap for dec 29, 30, or 31st being in the new year's week - these // are the only 3 that can possibly fall like this) if ( this.getMonth() === 11 && this.getDate() > 28 ) { return 1; } t1 = this.copy([0,-1*this.getMonth()],true).setFirstDay(4).adj(2,-3); t2 = Math.floor( ( this.getTime() - ( t1.getTime() + ( ( this.getTimezoneOffset() - t1.getTimezoneOffset() ) * 60000 ))) / 6048e5 ) + 1; if ( t2 < 1 ) { t1 = this.copy([-1,-1*this.getMonth()]).setFirstDay(4).adj(2,-3); return Math.floor((this.getTime() - t1.getTime()) / 6048e5) + 1; } return t2; default: return 0; } } }); };