1 /* 2 * PersAlsoRataDie.js - Represent an RD date in the Persian algorithmic 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 PersianAlgoCal = require("./PersianAlgoCal.js"); 22 var RataDie = require("./RataDie.js"); 23 24 /** 25 * @class 26 * Construct a new Persian 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, Gregorian 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 Farvardin, 2 means Ordibehesht, 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 Persian 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 Persian RD date 71 */ 72 var PersAlgoRataDie = function(params) { 73 this.cal = params && params.cal || new PersianAlgoCal(); 74 this.rd = NaN; 75 RataDie.call(this, params); 76 }; 77 78 PersAlgoRataDie.prototype = new RataDie(); 79 PersAlgoRataDie.prototype.parent = RataDie; 80 PersAlgoRataDie.prototype.constructor = PersAlgoRataDie; 81 82 /** 83 * The difference between a zero Julian day and the first Persian date 84 * @private 85 * @type number 86 */ 87 PersAlgoRataDie.prototype.epoch = 1948319.5; 88 89 /** 90 * @private 91 * @const 92 * @type Array.<number> 93 * the cumulative lengths of each month, for a non-leap year 94 */ 95 PersAlgoRataDie.cumMonthLengths = [ 96 0, // Farvardin 97 31, // Ordibehesht 98 62, // Khordad 99 93, // Tir 100 124, // Mordad 101 155, // Shahrivar 102 186, // Mehr 103 216, // Aban 104 246, // Azar 105 276, // Dey 106 306, // Bahman 107 336, // Esfand 108 365 109 ]; 110 111 /** 112 * Calculate the Rata Die (fixed day) number of the given date from the 113 * date components. 114 * 115 * @protected 116 * @param {Object} date the date components to calculate the RD from 117 */ 118 PersAlgoRataDie.prototype._setDateComponents = function(date) { 119 var year = this.cal.equivalentCycleYear(date.year); 120 var y = date.year - (date.year >= 0 ? 474 : 473); 121 var rdOfYears = 1029983 * Math.floor(y/2820) + 365 * (year - 1) + Math.floor((682 * year - 110) / 2816); 122 var dayInYear = (date.month > 1 ? PersAlgoRataDie.cumMonthLengths[date.month-1] : 0) + date.day; 123 var rdtime = (date.hour * 3600000 + 124 date.minute * 60000 + 125 date.second * 1000 + 126 date.millisecond) / 127 86400000; 128 129 /* 130 // console.log("getRataDie: converting " + JSON.stringify(this)); 131 console.log("getRataDie: year is " + year); 132 console.log("getRataDie: rd of years is " + rdOfYears); 133 console.log("getRataDie: day in year is " + dayInYear); 134 console.log("getRataDie: rdtime is " + rdtime); 135 console.log("getRataDie: rd is " + (rdOfYears + dayInYear + rdtime)); 136 */ 137 138 this.rd = rdOfYears + dayInYear + rdtime; 139 }; 140 141 /** 142 * Return the rd number of the particular day of the week on or before the 143 * given rd. eg. The Sunday on or before the given rd. 144 * @private 145 * @param {number} rd the rata die date of the reference date 146 * @param {number} dayOfWeek the day of the week that is being sought relative 147 * to the current date 148 * @return {number} the rd of the day of the week 149 */ 150 PersAlgoRataDie.prototype._onOrBefore = function(rd, dayOfWeek) { 151 return rd - MathUtils.mod(Math.floor(rd) - dayOfWeek - 3, 7); 152 }; 153 154 module.exports = PersAlgoRataDie;