1 /* 2 * GregRataDie.js - Represent the RD date number in the Gregorian calendar 3 * 4 * Copyright © 2014-2015, 2018, JEDLSoft 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 var MathUtils = require("./MathUtils.js"); 21 var GregorianCal = require("./GregorianCal.js"); 22 var RataDie = require("./RataDie.js"); 23 24 /** 25 * @class 26 * Construct a new Gregorian RD date number object. The constructor parameters can 27 * contain any of the following properties: 28 * 29 * <ul> 30 * <li><i>unixtime<i> - sets the time of this instance according to the given 31 * unix time. Unix time is the number of milliseconds since midnight on Jan 1, 1970. 32 * 33 * <li><i>julianday</i> - sets the time of this instance according to the given 34 * Julian Day instance or the Julian Day given as a float 35 * 36 * <li><i>year</i> - any integer, including 0 37 * 38 * <li><i>month</i> - 1 to 12, where 1 means January, 2 means February, etc. 39 * 40 * <li><i>day</i> - 1 to 31 41 * 42 * <li><i>hour</i> - 0 to 23. A formatter is used to display 12 hour clocks, but this representation 43 * is always done with an unambiguous 24 hour representation 44 * 45 * <li><i>minute</i> - 0 to 59 46 * 47 * <li><i>second</i> - 0 to 59 48 * 49 * <li><i>millisecond</i> - 0 to 999 50 * 51 * <li><i>date</i> - use the given intrinsic Javascript date to initialize this one. 52 * </ul> 53 * 54 * If the constructor is called with another Gregorian date instance instead of 55 * a parameter block, the other instance acts as a parameter block and its 56 * settings are copied into the current instance.<p> 57 * 58 * If the constructor is called with no arguments at all or if none of the 59 * properties listed above are present, then the RD is calculate based on 60 * the current date at the time of instantiation. <p> 61 * 62 * If any of the properties from <i>year</i> through <i>millisecond</i> are not 63 * specified in the params, it is assumed that they have the smallest possible 64 * value in the range for the property (zero or one).<p> 65 * 66 * 67 * @private 68 * @constructor 69 * @extends RataDie 70 * @param {Object=} params parameters that govern the settings and behaviour of this Gregorian RD date 71 */ 72 var GregRataDie = function(params) { 73 this.cal = params && params.cal || new GregorianCal(); 74 /** @type {number|undefined} */ 75 this.rd = NaN; 76 RataDie.call(this, params); 77 }; 78 79 GregRataDie.prototype = new RataDie(); 80 GregRataDie.prototype.parent = RataDie; 81 GregRataDie.prototype.constructor = GregRataDie; 82 83 /** 84 * the cumulative lengths of each month, for a non-leap year 85 * @private 86 * @const 87 * @type Array.<number> 88 */ 89 GregRataDie.cumMonthLengths = [ 90 0, /* Jan */ 91 31, /* Feb */ 92 59, /* Mar */ 93 90, /* Apr */ 94 120, /* May */ 95 151, /* Jun */ 96 181, /* Jul */ 97 212, /* Aug */ 98 243, /* Sep */ 99 273, /* Oct */ 100 304, /* Nov */ 101 334, /* Dec */ 102 365 103 ]; 104 105 /** 106 * the cumulative lengths of each month, for a leap year 107 * @private 108 * @const 109 * @type Array.<number> 110 */ 111 GregRataDie.cumMonthLengthsLeap = [ 112 0, /* Jan */ 113 31, /* Feb */ 114 60, /* Mar */ 115 91, /* Apr */ 116 121, /* May */ 117 152, /* Jun */ 118 182, /* Jul */ 119 213, /* Aug */ 120 244, /* Sep */ 121 274, /* Oct */ 122 305, /* Nov */ 123 335, /* Dec */ 124 366 125 ]; 126 127 /** 128 * Calculate the Rata Die (fixed day) number of the given date. 129 * 130 * @private 131 * @param {Object} date the date components to calculate the RD from 132 */ 133 GregRataDie.prototype._setDateComponents = function(date) { 134 var year = parseInt(date.year, 10) || 0; 135 var month = parseInt(date.month, 10) || 1; 136 var day = parseInt(date.day, 10) || 1; 137 var hour = parseInt(date.hour, 10) || 0; 138 var minute = parseInt(date.minute, 10) || 0; 139 var second = parseInt(date.second, 10) || 0; 140 var millisecond = parseInt(date.millisecond, 10) || 0; 141 142 var years = 365 * (year - 1) + 143 Math.floor((year-1)/4) - 144 Math.floor((year-1)/100) + 145 Math.floor((year-1)/400); 146 147 var dayInYear = (month > 1 ? GregRataDie.cumMonthLengths[month-1] : 0) + 148 day + 149 (GregorianCal.prototype.isLeapYear.call(this.cal, year) && month > 2 ? 1 : 0); 150 var rdtime = (hour * 3600000 + 151 minute * 60000 + 152 second * 1000 + 153 millisecond) / 154 86400000; 155 /* 156 debug("getRataDie: converting " + JSON.stringify(this)); 157 debug("getRataDie: year is " + years); 158 debug("getRataDie: day in year is " + dayInYear); 159 debug("getRataDie: rdtime is " + rdtime); 160 debug("getRataDie: rd is " + (years + dayInYear + rdtime)); 161 */ 162 163 /** 164 * @type {number|undefined} the RD number of this Gregorian date 165 */ 166 this.rd = years + dayInYear + rdtime; 167 }; 168 169 /** 170 * Return the rd number of the particular day of the week on or before the 171 * given rd. eg. The Sunday on or before the given rd. 172 * @private 173 * @param {number} rd the rata die date of the reference date 174 * @param {number} dayOfWeek the day of the week that is being sought relative 175 * to the current date 176 * @return {number} the rd of the day of the week 177 */ 178 GregRataDie.prototype._onOrBefore = function(rd, dayOfWeek) { 179 return rd - MathUtils.mod(Math.floor(rd) - dayOfWeek, 7); 180 }; 181 182 module.exports = GregRataDie; 183