1 /** 2 * @fileOverview Extensions/helper methods for Date objects 3 */ 4 5 /** 6 * Get the week number for this date 7 * @param {Number} [dowOffset=0] the day of week the week "starts" on for your locale - it can be from 0 to 6. If dowOffset is 1 (Monday), the week returned is the ISO 8601 week number. 8 * @returns {Number} the week number for this date. 9 * @author <a href="http://www.meanfreepath.com">Nick Baicoianu at MeanFreePath</a> 10 */ 11 Date.prototype.getWeekOfYear = function getWeekOfYear(dowOffset) { 12 dowOffset = typeof(dowOffset) == 'int' ? dowOffset : 0; //default dowOffset to zero 13 var newYear = new Date(this.getFullYear(),0,1); 14 var day = newYear.getDay() - dowOffset; //the day of week the year begins on 15 day = (day >= 0 ? day : day + 7); 16 var daynum = Math.floor((this.getTime() - newYear.getTime() - 17 (this.getTimezoneOffset()-newYear.getTimezoneOffset())*60000)/86400000) + 1; 18 var weeknum; 19 //if the year starts before the middle of a week 20 if (day < 4) { 21 weeknum = Math.floor((daynum+day-1)/7) + 1; 22 if (weeknum > 52) { 23 nYear = new Date(this.getFullYear() + 1,0,1); 24 nday = nYear.getDay() - dowOffset; 25 nday = nday >= 0 ? nday : nday + 7; 26 /*if the next year starts before the middle of 27 the week, it is week #1 of that year*/ 28 weeknum = nday < 4 ? 1 : 53; 29 } 30 } 31 else { 32 weeknum = Math.floor((daynum+day-1)/7); 33 } 34 return weeknum; 35 }; 36 37 /** 38 * A Hash of Arrays, containing localized Days of the Week as strings, using either language or language-country letter location codes (e.g. 'en' or 'en-us') 39 * @type {Object} 40 * @example 41 * //Adding French Candaian days of the week - this will only apply to users with French-Canadian language settings 42 * //Use the language code only to apply to all variations of the language. Country specific variations have precedence. 43 * Date.prototype.daysOfWeek['fr-ca'] = [ 44 * 'dimanche', 45 * 'lundi', 46 * 'mardi', 47 * 'mercredi', 48 * 'jeudi', 49 * 'vendredi', 50 * 'samedi' 51 * ]; 52 */ 53 Date.prototype.daysOfWeek = { 54 'en' : [ 55 'Sunday', 56 'Monday', 57 'Tuesday', 58 'Wednesday', 59 'Thursday', 60 'Friday', 61 'Saturday' 62 ] 63 }; 64 65 /** 66 * Hash of Arrays, containing localized Months of the Year as strings, using either language or language-country letter location codes (e.g. 'en' or 'en-us') 67 * @type {Object} 68 * @example 69 * //Adding Spanish months of the year - this will apply to users with Spanish language settings in any country 70 * //Use the language-country code only to apply to specific variations of the language. Country specific variations have precedence. 71 * Date.prototype.daysOfWeek['es'] = [ 72 * 'enero', 73 * 'febrero', 74 * 'marzo', 75 * 'abril', 76 * 'mayo', 77 * 'junio', 78 * 'julio', 79 * 'agosto', 80 * 'septiembre', 81 * 'octubre', 82 * 'noviembre', 83 * 'diciembre' 84 * ]; 85 */ 86 Date.prototype.monthsOfYear = { 87 'en' : [ 88 'January', 89 'February', 90 'March', 91 'April', 92 'May', 93 'June', 94 'July', 95 'August', 96 'September', 97 'October', 98 'November', 99 'December' 100 ] 101 }; 102 103 /** 104 * Get the days of the week in the best match for the current browser language settings. If the current language/country isn't available, falls back to language only, then English as last resort. 105 * @param {String} [lang] try to force the language to use. Can be a language-country code just a language code. If the specified language/country isn't available, falls back to language only, then English 106 * @returns {String[]} days of the week in an Array (index starts at 0) 107 * @see Date#daysOfWeek 108 * @example 109 * var t = new Date(); 110 * var days = t.getDaysOfWeek('fr-ca'); //Attempt to get the days of the week as an Array, in this order: French-Canadian, French, English 111 */ 112 Date.prototype.getDaysOfWeek = function getDaysOfWeek(lang) { 113 if (!Object.isUndefined(lang) && !Object.isString(lang)) { 114 throw new TypeError(); 115 } 116 117 lang = (lang || window.navigator.language || window.navigator.userLanguage).toLowerCase(); 118 if (!(lang in this.daysOfWeek)) { 119 lang = lang.split('-')[0]; 120 } 121 if (!(lang in this.daysOfWeek)) { 122 lang = 'en'; 123 } 124 125 return this.daysOfWeek[lang]; 126 }; 127 128 /** 129 * Get the months of the year in the best match for the current browser language settings. If the current language/country isn't available, falls back to language only, then English as last resort. 130 * @param {String} [lang] try to force the language to use. Can be a language-country code just a language code. If the specified language/country isn't available, falls back to language only, then English 131 * @returns {String[]} months of the year in an Array (index starts at 0) 132 * @see Date#monthsOfYear 133 * @example 134 * var t = new Date(); 135 * var months = t.getMonthsOfYear('es-bo'); //Attempt to get the months of the year as an Array, in this order: Bolivian-Spanish, Spanish, English 136 */ 137 Date.prototype.getMonthsOfYear = function getMonthsOfYear(lang) { 138 lang = (lang || window.navigator.language || window.navigator.userLanguage).toLowerCase(); 139 if (!(lang in this.monthsOfYear)) { 140 lang = lang.split('-')[0]; 141 } 142 if (!(lang in this.monthsOfYear)) { 143 lang = 'en'; 144 } 145 146 return this.monthsOfYear[lang]; 147 }; 148 149 150 /** 151 * Get the number of Days in the current Month, including calculations for February in Leap Years 152 * @returns {Number} the number of Days in the current Month 153 */ 154 Date.prototype.getDaysInMonth = function getDaysInMonth() { 155 var lengths = [ 156 31, 157 28, 158 31, 159 30, 160 31, 161 30, 162 31, 163 31, 164 30, 165 31, 166 30, 167 31 168 ]; 169 170 if (this.getMonth() === 1 && this.isLeapYear()) { 171 return 29; 172 } 173 else { 174 return lengths[this.getMonth()]; 175 } 176 }; 177 178 /** 179 * Determine if current Year is a leap Year 180 * @returns {Boolean} true if current Year is a leap year, false if not 181 */ 182 Date.prototype.isLeapYear = function isLeapYear() { 183 return (((this.getFullYear() % 4 === 0) && (this.getFullYear() % 100 !== 0)) || this.getFullYear() % 400 === 0); 184 }; 185 186 /** 187 * Get day of the year 188 * @returns {Integer} the day of the year 189 */ 190 Date.prototype.getDayOfYear = function getDayOfYear() { 191 var days = 0; 192 for (var i = 0; i < this.getMonth(); i++) { 193 var tmpDate = new Date(this.getFullYear(), i, 1); 194 days += tmpDate.getDaysInMonth(); 195 } 196 197 days += this.getDate(); 198 199 return days; 200 }; 201 202 /** 203 * Generate a formatted string from a Date object according to the specified template. 204 * Supports most of the same characters for date strings as the PHP date function, except date characters to be replaced must have '%' characters wrapping them. 205 * The following characters are supported, see {@link http://www.php.net/date} for more info<br /> 206 * Days: d, D, j, l, N, S, w, z<br /> 207 * Week: W<br /> 208 * Month: F, m, M, n, t<br /> 209 * Year: L, o, Y, y<br /> 210 * Time: a, A, g, G, h, H, i, s<br /> 211 * @param {String} format the template for the new String. 212 * @returns {String} the template with valid characters replaced with respective values 213 * @example 214 * var d = new Date(); 215 * var message = d.formatDate('%l%, %F% %d% %Y%'); // "Thursday, January 22 2009" 216 */ 217 Date.prototype.formatDate = function formatDate(format) { 218 if(!Object.isString(format)) { 219 throw new TypeError(); 220 } 221 var values = { 222 // Day 223 'd' : this.getDate().toPaddedString(), 224 'D' : this.getDaysOfWeek()[this.getDay()].substr(0, 3), 225 'j' : this.getDate(), 226 'l' : this.getDaysOfWeek()[this.getDay()], 227 'N' : this.getDay() + 1, 228 'S' : '', 229 'w' : this.getDay(), 230 'z' : this.getDayOfYear(), 231 // Week 232 'W' : this.getWeekOfYear(1), 233 // Month 234 'F' : this.getMonthsOfYear()[this.getMonth()], 235 'm' : (this.getMonth() + 1).toPaddedString(), 236 'M' : this.getMonthsOfYear()[this.getMonth()].substr(0, 3), 237 'n' : this.getMonth() + 1, 238 't' : this.getDaysInMonth(), 239 // Year 240 'L' : this.isLeapYear() ? 1 : 0, 241 'o' : this.getWeekOfYear(1) === 0 ? this.getFullYear() - 1 : this.getFullYear(), 242 'Y' : this.getFullYear(), 243 'y' : this.getYear(), 244 // Time 245 'a' : this.getHours() < 12 ? 'am' : 'pm', 246 'A' : this.getHours() < 12 ? 'AM' : 'PM', 247 'g' : this.getHours() < 12 ? this.getHours() + 1 : this.getHours() - 11, 248 'G' : this.getHours(), 249 'h' : (this.getHours() < 12 ? this.getHours() + 1 : this.getHours() - 11).toPaddedString(), 250 'H' : this.getHours().toPaddedString(), 251 'i' : this.getMinutes().toPaddedString(), 252 's' : this.getSeconds().toPaddedString() 253 }; 254 255 var keys = Object.getKeys(values).map(function (char) {return '%' + char + '%';}); 256 257 var str = format.replaceMulti(keys, Object.getValues(values)); 258 259 return str; 260 };