| 1 | // formatDate : |
|---|
| 2 | // a PHP date like function, for formatting date strings |
|---|
| 3 | // authored by Svend Tofte <www.svendtofte.com> |
|---|
| 4 | // the code is in the public domain |
|---|
| 5 | // |
|---|
| 6 | // see http://www.svendtofte.com/code/date_format/ |
|---|
| 7 | // and http://www.php.net/date |
|---|
| 8 | // |
|---|
| 9 | // thanks to |
|---|
| 10 | // - Daniel Berlin <mail@daniel-berlin.de>, |
|---|
| 11 | // major overhaul and improvements |
|---|
| 12 | // - Matt Bannon, |
|---|
| 13 | // correcting some stupid bugs in my days-in-the-months list! |
|---|
| 14 | // |
|---|
| 15 | // input : format string |
|---|
| 16 | // time : epoch time (seconds, and optional) |
|---|
| 17 | // |
|---|
| 18 | // if time is not passed, formatting is based on |
|---|
| 19 | // the current "this" date object's set time. |
|---|
| 20 | // |
|---|
| 21 | // supported switches are |
|---|
| 22 | // a, A, B, c, d, D, F, g, G, h, H, i, I (uppercase i), j, l (lowecase L), |
|---|
| 23 | // L, m, M, n, N, O, P, r, s, S, t, U, w, W, y, Y, z, Z |
|---|
| 24 | // |
|---|
| 25 | // unsupported (as compared to date in PHP 5.1.3) |
|---|
| 26 | // T, e, o |
|---|
| 27 | |
|---|
| 28 | Date.prototype.formatDate = function (input,time) { |
|---|
| 29 | |
|---|
| 30 | var daysLong = ["Sunday", "Monday", "Tuesday", "Wednesday", |
|---|
| 31 | "Thursday", "Friday", "Saturday"]; |
|---|
| 32 | var daysShort = ["Sun", "Mon", "Tue", "Wed", |
|---|
| 33 | "Thu", "Fri", "Sat"]; |
|---|
| 34 | var monthsShort = ["Jan", "Feb", "Mar", "Apr", |
|---|
| 35 | "May", "Jun", "Jul", "Aug", "Sep", |
|---|
| 36 | "Oct", "Nov", "Dec"]; |
|---|
| 37 | var monthsLong = ["January", "February", "March", "April", |
|---|
| 38 | "May", "June", "July", "August", "September", |
|---|
| 39 | "October", "November", "December"]; |
|---|
| 40 | |
|---|
| 41 | var switches = { // switches object |
|---|
| 42 | |
|---|
| 43 | a : function () { |
|---|
| 44 | // Lowercase Ante meridiem and Post meridiem |
|---|
| 45 | return date.getHours() > 11? "pm" : "am"; |
|---|
| 46 | }, |
|---|
| 47 | |
|---|
| 48 | A : function () { |
|---|
| 49 | // Uppercase Ante meridiem and Post meridiem |
|---|
| 50 | return (this.a().toUpperCase ()); |
|---|
| 51 | }, |
|---|
| 52 | |
|---|
| 53 | B : function (){ |
|---|
| 54 | // Swatch internet time. code simply grabbed from ppk, |
|---|
| 55 | // since I was feeling lazy: |
|---|
| 56 | // http://www.xs4all.nl/~ppk/js/beat.html |
|---|
| 57 | var off = (date.getTimezoneOffset() + 60)*60; |
|---|
| 58 | var theSeconds = (date.getHours() * 3600) + |
|---|
| 59 | (date.getMinutes() * 60) + |
|---|
| 60 | date.getSeconds() + off; |
|---|
| 61 | var beat = Math.floor(theSeconds/86.4); |
|---|
| 62 | if (beat > 1000) beat -= 1000; |
|---|
| 63 | if (beat < 0) beat += 1000; |
|---|
| 64 | if ((String(beat)).length == 1) beat = "00"+beat; |
|---|
| 65 | if ((String(beat)).length == 2) beat = "0"+beat; |
|---|
| 66 | return beat; |
|---|
| 67 | }, |
|---|
| 68 | |
|---|
| 69 | c : function () { |
|---|
| 70 | // ISO 8601 date (e.g.: "2004-02-12T15:19:21+00:00"), as per |
|---|
| 71 | // http://www.cl.cam.ac.uk/~mgk25/iso-time.html |
|---|
| 72 | return (this.Y() + "-" + this.m() + "-" + this.d() + "T" + |
|---|
| 73 | this.h() + ":" + this.i() + ":" + this.s() + this.P()); |
|---|
| 74 | }, |
|---|
| 75 | |
|---|
| 76 | d : function () { |
|---|
| 77 | // Day of the month, 2 digits with leading zeros |
|---|
| 78 | var j = String(this.j()); |
|---|
| 79 | return (j.length == 1 ? "0"+j : j); |
|---|
| 80 | }, |
|---|
| 81 | |
|---|
| 82 | D : function () { |
|---|
| 83 | // A textual representation of a day, three letters |
|---|
| 84 | return daysShort[date.getDay()]; |
|---|
| 85 | }, |
|---|
| 86 | |
|---|
| 87 | F : function () { |
|---|
| 88 | // A full textual representation of a month |
|---|
| 89 | return monthsLong[date.getMonth()]; |
|---|
| 90 | }, |
|---|
| 91 | |
|---|
| 92 | g : function () { |
|---|
| 93 | // 12-hour format of an hour without leading zeros |
|---|
| 94 | return date.getHours() > 12? date.getHours()-12 : date.getHours(); |
|---|
| 95 | }, |
|---|
| 96 | |
|---|
| 97 | G : function () { |
|---|
| 98 | // 24-hour format of an hour without leading zeros |
|---|
| 99 | return date.getHours(); |
|---|
| 100 | }, |
|---|
| 101 | |
|---|
| 102 | h : function () { |
|---|
| 103 | // 12-hour format of an hour with leading zeros |
|---|
| 104 | var g = String(this.g()); |
|---|
| 105 | return (g.length == 1 ? "0"+g : g); |
|---|
| 106 | }, |
|---|
| 107 | |
|---|
| 108 | H : function () { |
|---|
| 109 | // 24-hour format of an hour with leading zeros |
|---|
| 110 | var G = String(this.G()); |
|---|
| 111 | return (G.length == 1 ? "0"+G : G); |
|---|
| 112 | }, |
|---|
| 113 | |
|---|
| 114 | i : function () { |
|---|
| 115 | // Minutes with leading zeros |
|---|
| 116 | var min = String (date.getMinutes ()); |
|---|
| 117 | return (min.length == 1 ? "0" + min : min); |
|---|
| 118 | }, |
|---|
| 119 | |
|---|
| 120 | I : function () { |
|---|
| 121 | // Whether or not the date is in daylight saving time (DST) |
|---|
| 122 | // note that this has no bearing in actual DST mechanics, |
|---|
| 123 | // and is just a pure guess. buyer beware. |
|---|
| 124 | var noDST = new Date ("January 1 " + this.Y() + " 00:00:00"); |
|---|
| 125 | return (noDST.getTimezoneOffset () == |
|---|
| 126 | date.getTimezoneOffset () ? 0 : 1); |
|---|
| 127 | }, |
|---|
| 128 | |
|---|
| 129 | j : function () { |
|---|
| 130 | // Day of the month without leading zeros |
|---|
| 131 | return date.getDate(); |
|---|
| 132 | }, |
|---|
| 133 | |
|---|
| 134 | l : function () { |
|---|
| 135 | // A full textual representation of the day of the week |
|---|
| 136 | return daysLong[date.getDay()]; |
|---|
| 137 | }, |
|---|
| 138 | |
|---|
| 139 | L : function () { |
|---|
| 140 | // leap year or not. 1 if leap year, 0 if not. |
|---|
| 141 | // the logic should match iso's 8601 standard. |
|---|
| 142 | // http://www.uic.edu/depts/accc/software/isodates/leapyear.html |
|---|
| 143 | var Y = this.Y(); |
|---|
| 144 | if ( |
|---|
| 145 | (Y % 4 == 0 && Y % 100 != 0) || |
|---|
| 146 | (Y % 4 == 0 && Y % 100 == 0 && Y % 400 == 0) |
|---|
| 147 | ) { |
|---|
| 148 | return 1; |
|---|
| 149 | } else { |
|---|
| 150 | return 0; |
|---|
| 151 | } |
|---|
| 152 | }, |
|---|
| 153 | |
|---|
| 154 | m : function () { |
|---|
| 155 | // Numeric representation of a month, with leading zeros |
|---|
| 156 | var n = String(this.n()); |
|---|
| 157 | return (n.length == 1 ? "0"+n : n); |
|---|
| 158 | }, |
|---|
| 159 | |
|---|
| 160 | M : function () { |
|---|
| 161 | // A short textual representation of a month, three letters |
|---|
| 162 | return monthsShort[date.getMonth()]; |
|---|
| 163 | }, |
|---|
| 164 | |
|---|
| 165 | n : function () { |
|---|
| 166 | // Numeric representation of a month, without leading zeros |
|---|
| 167 | return date.getMonth()+1; |
|---|
| 168 | }, |
|---|
| 169 | |
|---|
| 170 | N : function () { |
|---|
| 171 | // ISO-8601 numeric representation of the day of the week |
|---|
| 172 | var w = this.w(); |
|---|
| 173 | return (w == 0 ? 7 : w); |
|---|
| 174 | }, |
|---|
| 175 | |
|---|
| 176 | O : function () { |
|---|
| 177 | // Difference to Greenwich time (GMT) in hours |
|---|
| 178 | var os = Math.abs(date.getTimezoneOffset()); |
|---|
| 179 | var h = String(Math.floor(os/60)); |
|---|
| 180 | var m = String(os%60); |
|---|
| 181 | h.length == 1? h = "0"+h:1; |
|---|
| 182 | m.length == 1? m = "0"+m:1; |
|---|
| 183 | return date.getTimezoneOffset() < 0 ? "+"+h+m : "-"+h+m; |
|---|
| 184 | }, |
|---|
| 185 | |
|---|
| 186 | P : function () { |
|---|
| 187 | // Difference to GMT, with colon between hours and minutes |
|---|
| 188 | var O = this.O(); |
|---|
| 189 | return (O.substr(0, 3) + ":" + O.substr(3, 2)); |
|---|
| 190 | }, |
|---|
| 191 | |
|---|
| 192 | r : function () { |
|---|
| 193 | // RFC 822 formatted date |
|---|
| 194 | var r; // result |
|---|
| 195 | // Thu , 21 Dec 2000 |
|---|
| 196 | r = this.D() + ", " + this.d() + " " + this.M() + " " + this.Y() + |
|---|
| 197 | // 16 : 01 : 07 0200 |
|---|
| 198 | " " + this.H() + ":" + this.i() + ":" + this.s() + " " + this.O(); |
|---|
| 199 | return r; |
|---|
| 200 | }, |
|---|
| 201 | |
|---|
| 202 | s : function () { |
|---|
| 203 | // Seconds, with leading zeros |
|---|
| 204 | var sec = String (date.getSeconds ()); |
|---|
| 205 | return (sec.length == 1 ? "0" + sec : sec); |
|---|
| 206 | }, |
|---|
| 207 | |
|---|
| 208 | S : function () { |
|---|
| 209 | // English ordinal suffix for the day of the month, 2 characters |
|---|
| 210 | switch (date.getDate ()) { |
|---|
| 211 | case 1: return ("st"); |
|---|
| 212 | case 2: return ("nd"); |
|---|
| 213 | case 3: return ("rd"); |
|---|
| 214 | case 21: return ("st"); |
|---|
| 215 | case 22: return ("nd"); |
|---|
| 216 | case 23: return ("rd"); |
|---|
| 217 | case 31: return ("st"); |
|---|
| 218 | default: return ("th"); |
|---|
| 219 | } |
|---|
| 220 | }, |
|---|
| 221 | |
|---|
| 222 | t : function () { |
|---|
| 223 | // thanks to Matt Bannon for some much needed code-fixes here! |
|---|
| 224 | var daysinmonths = [null,31,28,31,30,31,30,31,31,30,31,30,31]; |
|---|
| 225 | if (this.L()==1 && this.n()==2) return 29; // ~leap day |
|---|
| 226 | return daysinmonths[this.n()]; |
|---|
| 227 | }, |
|---|
| 228 | |
|---|
| 229 | U : function () { |
|---|
| 230 | // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) |
|---|
| 231 | return Math.round(date.getTime()/1000); |
|---|
| 232 | }, |
|---|
| 233 | |
|---|
| 234 | w : function () { |
|---|
| 235 | // Numeric representation of the day of the week |
|---|
| 236 | return date.getDay(); |
|---|
| 237 | }, |
|---|
| 238 | |
|---|
| 239 | W : function () { |
|---|
| 240 | // Weeknumber, as per ISO specification: |
|---|
| 241 | // http://www.cl.cam.ac.uk/~mgk25/iso-time.html |
|---|
| 242 | |
|---|
| 243 | var DoW = this.N (); |
|---|
| 244 | var DoY = this.z (); |
|---|
| 245 | |
|---|
| 246 | // If the day is 3 days before New Year's Eve and is Thursday or earlier, |
|---|
| 247 | // it's week 1 of next year. |
|---|
| 248 | var daysToNY = 364 + this.L () - DoY; |
|---|
| 249 | if (daysToNY <= 2 && DoW <= (3 - daysToNY)) { |
|---|
| 250 | return 1; |
|---|
| 251 | } |
|---|
| 252 | |
|---|
| 253 | // If the day is within 3 days after New Year's Eve and is Friday or later, |
|---|
| 254 | // it belongs to the old year. |
|---|
| 255 | if (DoY <= 2 && DoW >= 5) { |
|---|
| 256 | return new Date (this.Y () - 1, 11, 31).formatDate ("W"); |
|---|
| 257 | } |
|---|
| 258 | |
|---|
| 259 | var nyDoW = new Date (this.Y (), 0, 1).getDay (); |
|---|
| 260 | nyDoW = nyDoW != 0 ? nyDoW - 1 : 6; |
|---|
| 261 | |
|---|
| 262 | if (nyDoW <= 3) { // First day of the year is a Thursday or earlier |
|---|
| 263 | return (1 + Math.floor ((DoY + nyDoW) / 7)); |
|---|
| 264 | } else { // First day of the year is a Friday or later |
|---|
| 265 | return (1 + Math.floor ((DoY - (7 - nyDoW)) / 7)); |
|---|
| 266 | } |
|---|
| 267 | }, |
|---|
| 268 | |
|---|
| 269 | y : function () { |
|---|
| 270 | // A two-digit representation of a year |
|---|
| 271 | var y = String(this.Y()); |
|---|
| 272 | return y.substring(y.length-2,y.length); |
|---|
| 273 | }, |
|---|
| 274 | |
|---|
| 275 | Y : function () { |
|---|
| 276 | // A full numeric representation of a year, 4 digits |
|---|
| 277 | |
|---|
| 278 | // we first check, if getFullYear is supported. if it |
|---|
| 279 | // is, we just use that. ppks code is nice, but wont |
|---|
| 280 | // work with dates outside 1900-2038, or something like that |
|---|
| 281 | if (date.getFullYear) { |
|---|
| 282 | var newDate = new Date("January 1 2001 00:00:00 +0000"); |
|---|
| 283 | var x = newDate .getFullYear(); |
|---|
| 284 | if (x == 2001) { |
|---|
| 285 | // i trust the method now |
|---|
| 286 | return date.getFullYear(); |
|---|
| 287 | } |
|---|
| 288 | } |
|---|
| 289 | // else, do this: |
|---|
| 290 | // codes thanks to ppk: |
|---|
| 291 | // http://www.xs4all.nl/~ppk/js/introdate.html |
|---|
| 292 | var x = date.getYear(); |
|---|
| 293 | var y = x % 100; |
|---|
| 294 | y += (y < 38) ? 2000 : 1900; |
|---|
| 295 | return y; |
|---|
| 296 | }, |
|---|
| 297 | |
|---|
| 298 | |
|---|
| 299 | z : function () { |
|---|
| 300 | // The day of the year, zero indexed! 0 through 366 |
|---|
| 301 | var t = new Date("January 1 " + this.Y() + " 00:00:00"); |
|---|
| 302 | var diff = date.getTime() - t.getTime(); |
|---|
| 303 | return Math.floor(diff/1000/60/60/24); |
|---|
| 304 | }, |
|---|
| 305 | |
|---|
| 306 | Z : function () { |
|---|
| 307 | // Timezone offset in seconds |
|---|
| 308 | return (date.getTimezoneOffset () * -60); |
|---|
| 309 | } |
|---|
| 310 | |
|---|
| 311 | } |
|---|
| 312 | |
|---|
| 313 | function getSwitch(str) { |
|---|
| 314 | if (switches[str] != undefined) { |
|---|
| 315 | return switches[str](); |
|---|
| 316 | } else { |
|---|
| 317 | return str; |
|---|
| 318 | } |
|---|
| 319 | } |
|---|
| 320 | |
|---|
| 321 | var date; |
|---|
| 322 | if (time) { |
|---|
| 323 | var date = new Date (time); |
|---|
| 324 | } else { |
|---|
| 325 | var date = this; |
|---|
| 326 | } |
|---|
| 327 | |
|---|
| 328 | var formatString = input.split(""); |
|---|
| 329 | var i = 0; |
|---|
| 330 | while (i < formatString.length) { |
|---|
| 331 | if (formatString[i] == "\\") { |
|---|
| 332 | // this is our way of allowing users to escape stuff |
|---|
| 333 | formatString.splice(i,1); |
|---|
| 334 | } else { |
|---|
| 335 | formatString[i] = getSwitch(formatString[i]); |
|---|
| 336 | } |
|---|
| 337 | i++; |
|---|
| 338 | } |
|---|
| 339 | |
|---|
| 340 | return formatString.join(""); |
|---|
| 341 | } |
|---|
| 342 | |
|---|
| 343 | |
|---|
| 344 | // Some (not all) predefined format strings from PHP 5.1.1, which |
|---|
| 345 | // offer standard date representations. |
|---|
| 346 | // See: http://www.php.net/manual/en/ref.datetime.php#datetime.constants |
|---|
| 347 | // |
|---|
| 348 | |
|---|
| 349 | // Atom "2005-08-15T15:52:01+00:00" |
|---|
| 350 | Date.DATE_ATOM = "Y-m-d\\TH:i:sP"; |
|---|
| 351 | // ISO-8601 "2005-08-15T15:52:01+0000" |
|---|
| 352 | Date.DATE_ISO8601 = "Y-m-d\\TH:i:sO"; |
|---|
| 353 | // RFC 2822 "Mon, 15 Aug 2005 15:52:01 +0000" |
|---|
| 354 | Date.DATE_RFC2822 = "D, d M Y H:i:s O"; |
|---|
| 355 | // W3C "2005-08-15T15:52:01+00:00" |
|---|
| 356 | Date.DATE_W3C = "Y-m-d\\TH:i:sP"; |
|---|