1/* 2* $Id: dateextensions.js 43 2006-08-17 19:11:44Z wingedfox $ 3* $HeadURL: https://svn.debugger.ru/repos/jslibs/BrowserExtensions/tags/BrowserExtensions.003/dateextensions.js $ 4* 5* Extension implements additional methods to operate with Date object 6* @author Ilya Lebedev <ilya@lebedev.net> 7* @modified $Date: 2006-08-17 23:11:44 +0400 (Чтв, 17 Авг 2006) $ 8* @version $Rev: 43 $ 9* @license LGPL 2.1 or later 10*/ 11var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); 12var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat'); 13 14/* 15* leap year check 16* 17* @return bool check result 18* @access public 19*/ 20Date.prototype.isLeapYear = function () { 21 var y = this.getFullYear(); 22 return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0; 23} 24/* 25* the day of year number 26* 27* @return int day of year 28* @access public 29*/ 30Date.prototype.getDayOfYear = function () { 31 var md = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334], 32 m = this.getMonth(), 33 d = this.getDate()+md[m]; 34 return this.isLeapYear()&&m>2?d+1:d; 35} 36/* 37* return year according to Iso notation 38* 39* @return int year number 40* @access public 41*/ 42Date.prototype.getIsoYear = function () { 43 var d = this.getDayOfYear(), 44 j1 = (new Date(this.getFullYear(),0,1)).getIsoDay(), 45 y = this.getFullYear(); 46 if (d <= (8 - j1) && j1 > 4) { 47 return y-1; 48 } else if (((this.isLeapYear()?366:365) - d) < (4 - this.getIsoDay())) { 49 return y+1; 50 } else { 51 return y; 52 } 53} 54/* 55* find day number in ISO notation (Mon = 1, Sun=7) 56* 57* @return day number 58* @access public 59*/ 60Date.prototype.getIsoDay = function () { 61 var y = this.getFullYear(), 62 yy = (y-1) % 100, 63 c = (y-1) - yy, 64 g = yy + Math.floor(yy/4), 65 j1 = 1 + ((((Math.floor(c / 100) % 4) * 5) + g) % 7); 66 return (1 + ((this.getDayOfYear() + (j1 - 1) - 1) % 7)); 67} 68/* 69* return week number in ISO notation 70* 71* @return int week number 72* @access public 73*/ 74Date.prototype.getIsoWeek = function () { 75 var y = this.getFullYear(), 76 yi = this.getIsoYear(), 77 j1 = (new Date(y,0,1)).getIsoDay(); 78 if ( yi < y ) { 79 if (j1 == 5 || (j1 == 6 && (new Date(yi,0,1)).isLeapYear())) { 80 w = 53; 81 } else { 82 w = 52; 83 } 84 } else if (yi > y) { 85 w = 1; 86 } else { 87 var w = Math.floor((this.getDayOfYear() + (7-this.getIsoDay()) + (j1 - 1)) / 7); 88 if (j1 > 4) w -= 1; 89 } 90 return w; 91} 92/* 93* Converts Date object to formatted string 94* 95* @description 96* Possible formatting options 97* %a - abbreviated weekday name according to the current locale 98* %A - full weekday name according to the current locale 99* %b - abbreviated month name according to the current locale 100* %B - full month name according to the current locale 101* %c - preferred date and time representation for the current locale 102* %C - century number (the year divided by 100 and truncated to an integer, range 00 to 99) 103* %d - day of the month as a decimal number (range 01 to 31) 104* %D - same as %m/%d/%y 105* %e - day of the month as a decimal number, a single digit is preceded by a space (range ' 1' to '31') 106* %g - like %G, but without the century. 107* %G - The 4-digit year corresponding to the ISO week number (see %V). 108* self has the same format and value as %Y, except that if the ISO week number belongs 109* to the previous or next year, that year is used instead. 110* %h - same as %b 111* %H - hour as a decimal number using a 24-hour clock (range 00 to 23) 112* %I - hour as a decimal number using a 12-hour clock (range 01 to 12) 113* %j - day of the year as a decimal number (range 001 to 366) 114* %m - month as a decimal number (range 01 to 12) 115* %M - minute as a decimal number 116* %n - newline character 117* %p - either `am' or `pm' according to the given time value, or the corresponding strings for the current locale 118* %r - time in a.m. and p.m. notation 119* %R - time in 24 hour notation 120* %S - second as a decimal number 121* %t - tab character 122* %T - current time, equal to %H:%M:%S 123* %V - The ISO 8601:1988 week number of the current year as a decimal number, range 01 to 53, 124* where week 1 is the first week that has at least 4 days in the current year, 125* and with Monday as the first day of the week. 126* (Use %G or %g for the year component that corresponds to the week number for the specified timestamp.) 127* %u - weekday as a decimal number [1,7], with 1 representing Monday 128* %U - week number of the current year as a decimal number, starting with the first Sunday as the first day of the first week 129* %w - day of the week as a decimal, Sunday being 0 130* %W - week number of the current year as a decimal number, starting with the first Monday as the first day of the first week 131* %x - preferred date representation for the current locale without the time 132* %X - preferred time representation for the current locale without the date 133* %y - year as a decimal number without a century (range 00 to 99) 134* %Y - year as a decimal number including the century 135* %Z or %z - time zone or name or abbreviation 136* 137* @link http://php.net/strftime 138* 139* @param string optional date format 140* @param string optional single char spacer, used to pad short values 141* @return string formatted Date 142* @access public 143*/ 144Date.prototype.toFormatString = function (fmt, spacer) { 145 var self = this; 146 if (!fmt) return this.toString(); 147 if (typeof spacer != 'string') spacer = "0"; 148 if (spacer.length > 1) spacer.length = 1; 149 150 return fmt.replace(/%\w+/g,function(a) { 151 a = a.replace(/[%\s]/,""); 152 switch (a) { 153 case "a" : return DAY_NAMES[self.getDay()]; 154 case "A" : return DAY_NAMES[self.getDay()+7]; 155 case "b" : 156 case "h" : return MONTH_NAMES[self.getMonth()]; 157 case "B" : return MONTH_NAMES[self.getMonth()+12]; 158 case "c" : return; //??? 159 case "C" : return Math.round(self.getFullYear()/100); 160 case "d" : return String(self.getDate()).padLeft(2,spacer); 161 case "D" : return self.toFormatString("%m/%d/%y", spacer);//String(self.getMonth()+1).padLeft(2,"0")+"/"+String(self.getDate()+1).padLeft(2,"0")+"/"+String(self.getFullYear()).slice(-2); 162 case "e" : return String(self.getDate()+1).padLeft(2); 163 case "g" : return self.getIsoYear().slice(-2); 164 case "G" : return self.getIsoYear(); 165 case "H" : return String(self.getHours()).padLeft(2,spacer); 166 case "I" : return (self.getHours()>12?self.getHours()-12:self.getHours()).padLeft(2,spacer); 167 case "j" : return String(self.getDayOfYear()).padLeft(3,spacer); 168 case "m" : return String(self.getMonth()+1).padLeft(2,spacer); 169 case "M" : return String(self.getMinutes()).padLeft(2,spacer); 170 case "n" : return "\n"; 171 case "p" : return (self.getHours()>12?"PM":"AM"); 172 case "r" : return self.toFormatString("%I", spacer)+":"+self.toFormatString("%M", spacer)+":"+self.toFormatString("%S", spacer)+" "+self.toFormatString("%p", spacer); 173 case "R" : return self.toFormatString("%H", spacer)+":"+self.toFormatString("%M", spacer); 174 case "S" : return String(self.getSeconds()).padLeft(2,spacer); 175 case "t" : return "\t"; 176 case "T" : return self.toFormatString("%H", spacer)+":"+self.toFormatString("%M", spacer)+":"+self.toFormatString("%S", spacer); 177 case "u" : return self.getIsoDay(); 178 case "U" : return String(parseInt((self.getDayOfYear() - 1 - self.getIsoDay() + 13) / 7 - 1)).padLeft(2,"0"); 179 case "V" : return String(self.getIsoWeek()).padLeft(2,spacer); 180 case "w" : return self.getDay(); 181 case "W" : return String(parseInt((self.getDayOfYear() - 1 - self.getDay() + 13) / 7 - 1)).padLeft(2,"0"); 182 case "x" : return; // ??? 183 case "X" : return; // ??? 184 case "y" : return String(self.getFullYear()).slice(-2); 185 case "Y" : return self.getFullYear(); 186 case "z" : return; // ??? 187 case "Z" : return self.getTimezoneOffset() / 60; 188 } 189 return a; 190 } 191 ) 192} 193