Mercurial > urweb
comparison lib/js/urweb.js @ 1615:7d459f223ac2
Switch to YUI strftime
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Sat, 26 Nov 2011 10:14:05 -0500 |
parents | 37f5a23446b2 |
children | 15e0c935c91b |
comparison
equal
deleted
inserted
replaced
1614:efe1a2e9e4de | 1615:7d459f223ac2 |
---|---|
156 return null; | 156 return null; |
157 } | 157 } |
158 } | 158 } |
159 | 159 |
160 /* | 160 /* |
161 strftime for Javascript | 161 strftime() implementation from: |
162 Copyright (c) 2008, Philip S Tellis <philip@bluesmoon.info> | 162 YUI 3.4.1 (build 4118) |
163 All rights reserved. | 163 Copyright 2011 Yahoo! Inc. All rights reserved. |
164 | 164 Licensed under the BSD License. |
165 This code is distributed under the terms of the BSD licence | 165 http://yuilibrary.com/license/ |
166 | 166 */ |
167 Redistribution and use of this software in source and binary forms, with or without modification, | 167 |
168 are permitted provided that the following conditions are met: | 168 var xPad=function (x, pad, r) |
169 | |
170 * Redistributions of source code must retain the above copyright notice, this list of conditions | |
171 and the following disclaimer. | |
172 * Redistributions in binary form must reproduce the above copyright notice, this list of | |
173 conditions and the following disclaimer in the documentation and/or other materials provided | |
174 with the distribution. | |
175 * The names of the contributors to this file may not be used to endorse or promote products | |
176 derived from this software without specific prior written permission. | |
177 | |
178 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED | |
179 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | |
180 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
181 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
182 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
183 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR | |
184 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
185 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
186 */ | |
187 | |
188 Date.ext = {}; | |
189 Date.ext.util = {}; | |
190 Date.ext.util.xPad=function(x, pad, r) | |
191 { | 169 { |
192 if(typeof(r) == 'undefined') | 170 if(typeof r === "undefined") |
193 { | 171 { |
194 r=10; | 172 r=10; |
173 } | |
174 pad = pad.toString(); | |
175 for( ; parseInt(x, 10)<r && r>1; r/=10) { | |
176 x = pad + x; | |
177 } | |
178 return x.toString(); | |
179 }; | |
180 | |
181 var YDateEn = { | |
182 a: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], | |
183 A: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], | |
184 b: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], | |
185 B: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], | |
186 c: "%a %d %b %Y %T %Z", | |
187 p: ["AM", "PM"], | |
188 P: ["am", "pm"], | |
189 r: "%I:%M:%S %p", | |
190 x: "%d/%m/%y", | |
191 X: "%T" | |
192 }; | |
193 | |
194 var Dt = { | |
195 formats: { | |
196 a: function (d, l) { return l.a[d.getDay()]; }, | |
197 A: function (d, l) { return l.A[d.getDay()]; }, | |
198 b: function (d, l) { return l.b[d.getMonth()]; }, | |
199 B: function (d, l) { return l.B[d.getMonth()]; }, | |
200 C: function (d) { return xPad(parseInt(d.getFullYear()/100, 10), 0); }, | |
201 d: ["getDate", "0"], | |
202 e: ["getDate", " "], | |
203 g: function (d) { return xPad(parseInt(Dt.formats.G(d)%100, 10), 0); }, | |
204 G: function (d) { | |
205 var y = d.getFullYear(); | |
206 var V = parseInt(Dt.formats.V(d), 10); | |
207 var W = parseInt(Dt.formats.W(d), 10); | |
208 | |
209 if(W > V) { | |
210 y++; | |
211 } else if(W===0 && V>=52) { | |
212 y--; | |
213 } | |
214 | |
215 return y; | |
216 }, | |
217 H: ["getHours", "0"], | |
218 I: function (d) { var I=d.getHours()%12; return xPad(I===0?12:I, 0); }, | |
219 j: function (d) { | |
220 var gmd_1 = new Date("" + d.getFullYear() + "/1/1 GMT"); | |
221 var gmdate = new Date("" + d.getFullYear() + "/" + (d.getMonth()+1) + "/" + d.getDate() + " GMT"); | |
222 var ms = gmdate - gmd_1; | |
223 var doy = parseInt(ms/60000/60/24, 10)+1; | |
224 return xPad(doy, 0, 100); | |
225 }, | |
226 k: ["getHours", " "], | |
227 l: function (d) { var I=d.getHours()%12; return xPad(I===0?12:I, " "); }, | |
228 m: function (d) { return xPad(d.getMonth()+1, 0); }, | |
229 M: ["getMinutes", "0"], | |
230 p: function (d, l) { return l.p[d.getHours() >= 12 ? 1 : 0 ]; }, | |
231 P: function (d, l) { return l.P[d.getHours() >= 12 ? 1 : 0 ]; }, | |
232 s: function (d, l) { return parseInt(d.getTime()/1000, 10); }, | |
233 S: ["getSeconds", "0"], | |
234 u: function (d) { var dow = d.getDay(); return dow===0?7:dow; }, | |
235 U: function (d) { | |
236 var doy = parseInt(Dt.formats.j(d), 10); | |
237 var rdow = 6-d.getDay(); | |
238 var woy = parseInt((doy+rdow)/7, 10); | |
239 return xPad(woy, 0); | |
240 }, | |
241 V: function (d) { | |
242 var woy = parseInt(Dt.formats.W(d), 10); | |
243 var dow1_1 = (new Date("" + d.getFullYear() + "/1/1")).getDay(); | |
244 var idow = woy + (dow1_1 > 4 || dow1_1 <= 1 ? 0 : 1); | |
245 if(idow === 53 && (new Date("" + d.getFullYear() + "/12/31")).getDay() < 4) | |
246 { | |
247 idow = 1; | |
248 } | |
249 else if(idow === 0) | |
250 { | |
251 idow = Dt.formats.V(new Date("" + (d.getFullYear()-1) + "/12/31")); | |
252 } | |
253 | |
254 return xPad(idow, 0); | |
255 }, | |
256 w: "getDay", | |
257 W: function (d) { | |
258 var doy = parseInt(Dt.formats.j(d), 10); | |
259 var rdow = 7-Dt.formats.u(d); | |
260 var woy = parseInt((doy+rdow)/7, 10); | |
261 return xPad(woy, 0, 10); | |
262 }, | |
263 y: function (d) { return xPad(d.getFullYear()%100, 0); }, | |
264 Y: "getFullYear", | |
265 z: function (d) { | |
266 var o = d.getTimezoneOffset(); | |
267 var H = xPad(parseInt(Math.abs(o/60), 10), 0); | |
268 var M = xPad(Math.abs(o%60), 0); | |
269 return (o>0?"-":"+") + H + M; | |
270 }, | |
271 Z: function (d) { | |
272 var tz = d.toString().replace(/^.*:\d\d( GMT[+-]\d+)? \(?([A-Za-z ]+)\)?\d*$/, "$2").replace(/[a-z ]/g, ""); | |
273 if(tz.length > 4) { | |
274 tz = Dt.formats.z(d); | |
275 } | |
276 return tz; | |
277 }, | |
278 "%": function (d) { return "%"; } | |
279 }, | |
280 | |
281 aggregates: { | |
282 c: "locale", | |
283 D: "%m/%d/%y", | |
284 F: "%Y-%m-%d", | |
285 h: "%b", | |
286 n: "\n", | |
287 r: "%I:%M:%S %p", | |
288 R: "%H:%M", | |
289 t: "\t", | |
290 T: "%H:%M:%S", | |
291 x: "locale", | |
292 X: "locale" | |
293 }, | |
294 | |
295 format : function (oDate, format) { | |
296 var replace_aggs = function (m0, m1) { | |
297 var f = Dt.aggregates[m1]; | |
298 return (f === "locale" ? YDateEn[m1] : f); | |
299 }; | |
300 | |
301 var replace_formats = function (m0, m1) { | |
302 var f = Dt.formats[m1]; | |
303 switch(typeof f) { | |
304 case "string": | |
305 return oDate[f](); | |
306 case "function": | |
307 return f.call(oDate, oDate, YDateEn); | |
308 case "array": | |
309 case "object": | |
310 if(typeof(f[0]) === "string") | |
311 return xPad(oDate[f[0]](), f[1]); | |
312 default: | |
313 return m1; | |
314 } | |
315 }; | |
316 | |
317 while(format.match(/%[cDFhnrRtTxX]/)) { | |
318 format = format.replace(/%([cDFhnrRtTxX])/g, replace_aggs); | |
195 } | 319 } |
196 for( ; parseInt(x, 10)<r && r>1; r/=10) | 320 |
197 x = pad.toString() + x; | 321 var str = format.replace(/%([aAbBCdegGHIjklmMpPsSuUVwWyYzZ%])/g, replace_formats); |
198 return x.toString(); | 322 |
323 replace_aggs = replace_formats = undefined; | |
324 | |
325 return str; | |
326 } | |
199 }; | 327 }; |
200 Date.prototype.locale = 'en-US'; | 328 |
201 if(document.getElementsByTagName('html') && document.getElementsByTagName('html')[0].lang) | 329 // End of YUI code |
202 { | 330 |
203 Date.prototype.locale = document.getElementsByTagName('html')[0].lang; | |
204 } | |
205 Date.ext.locales = { }; | |
206 Date.ext.locales.en = { | |
207 a: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], | |
208 A: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], | |
209 b: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], | |
210 B: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], | |
211 c: '%a %d %b %Y %T %Z', | |
212 p: ['AM', 'PM'], | |
213 P: ['am', 'pm'], | |
214 x: '%d/%m/%y', | |
215 X: '%T' | |
216 }; | |
217 Date.ext.locales['en-US'] = Date.ext.locales.en; | |
218 Date.ext.locales['en-US'].c = '%a %d %b %Y %r %Z'; | |
219 Date.ext.locales['en-US'].x = '%D'; | |
220 Date.ext.locales['en-US'].X = '%r'; | |
221 Date.ext.locales['en-GB'] = Date.ext.locales.en; | |
222 Date.ext.locales['en-AU'] = Date.ext.locales['en-GB']; | |
223 Date.ext.formats = { | |
224 a: function(d) { return Date.ext.locales[d.locale].a[d.getDay()]; }, | |
225 A: function(d) { return Date.ext.locales[d.locale].A[d.getDay()]; }, | |
226 b: function(d) { return Date.ext.locales[d.locale].b[d.getMonth()]; }, | |
227 B: function(d) { return Date.ext.locales[d.locale].B[d.getMonth()]; }, | |
228 c: 'toLocaleString', | |
229 C: function(d) { return Date.ext.util.xPad(parseInt(d.getFullYear()/100, 10), 0); }, | |
230 d: ['getDate', '0'], | |
231 e: ['getDate', ' '], | |
232 g: function(d) { return Date.ext.util.xPad(parseInt(Date.ext.util.G(d)/100, 10), 0); }, | |
233 G: function(d) { | |
234 var y = d.getFullYear(); | |
235 var V = parseInt(Date.ext.formats.V(d), 10); | |
236 var W = parseInt(Date.ext.formats.W(d), 10); | |
237 | |
238 if(W > V) { | |
239 y++; | |
240 } else if(W===0 && V>=52) { | |
241 y--; | |
242 } | |
243 | |
244 return y; | |
245 }, | |
246 H: ['getHours', '0'], | |
247 I: function(d) { var I=d.getHours()%12; return Date.ext.util.xPad(I===0?12:I, 0); }, | |
248 j: function(d) { | |
249 var ms = d - new Date('' + d.getFullYear() + '/1/1 GMT'); | |
250 ms += d.getTimezoneOffset()*60000; | |
251 var doy = parseInt(ms/60000/60/24, 10)+1; | |
252 return Date.ext.util.xPad(doy, 0, 100); | |
253 }, | |
254 m: function(d) { return Date.ext.util.xPad(d.getMonth()+1, 0); }, | |
255 M: ['getMinutes', '0'], | |
256 p: function(d) { return Date.ext.locales[d.locale].p[d.getHours() >= 12 ? 1 : 0 ]; }, | |
257 P: function(d) { return Date.ext.locales[d.locale].P[d.getHours() >= 12 ? 1 : 0 ]; }, | |
258 S: ['getSeconds', '0'], | |
259 u: function(d) { var dow = d.getDay(); return dow===0?7:dow; }, | |
260 U: function(d) { | |
261 var doy = parseInt(Date.ext.formats.j(d), 10); | |
262 var rdow = 6-d.getDay(); | |
263 var woy = parseInt((doy+rdow)/7, 10); | |
264 return Date.ext.util.xPad(woy, 0); | |
265 }, | |
266 V: function(d) { | |
267 var woy = parseInt(Date.ext.formats.W(d), 10); | |
268 var dow1_1 = (new Date('' + d.getFullYear() + '/1/1')).getDay(); | |
269 var idow = woy + (dow1_1 > 4 || dow1_1 <= 1 ? 0 : 1); | |
270 if(idow == 53 && (new Date('' + d.getFullYear() + '/12/31')).getDay() < 4) | |
271 { | |
272 idow = 1; | |
273 } | |
274 else if(idow === 0) | |
275 { | |
276 idow = Date.ext.formats.V(new Date('' + (d.getFullYear()-1) + '/12/31')); | |
277 } | |
278 | |
279 return Date.ext.util.xPad(idow, 0); | |
280 }, | |
281 w: 'getDay', | |
282 W: function(d) { | |
283 var doy = parseInt(Date.ext.formats.j(d), 10); | |
284 var rdow = 7-Date.ext.formats.u(d); | |
285 var woy = parseInt((doy+rdow)/7, 10); | |
286 return Date.ext.util.xPad(woy, 0, 10); | |
287 }, | |
288 y: function(d) { return Date.ext.util.xPad(d.getFullYear()%100, 0); }, | |
289 Y: 'getFullYear', | |
290 z: function(d) { | |
291 var o = d.getTimezoneOffset(); | |
292 var H = Date.ext.util.xPad(parseInt(Math.abs(o/60), 10), 0); | |
293 var M = Date.ext.util.xPad(o%60, 0); | |
294 return (o>0?'-':'+') + H + M; | |
295 }, | |
296 Z: function(d) { return d.toString().replace(/^.*\(([^)]+)\)$/, '$1'); }, | |
297 '%': function(d) { return '%'; } | |
298 }; | |
299 Date.ext.aggregates = { | |
300 c: 'locale', | |
301 D: '%m/%d/%y', | |
302 h: '%b', | |
303 n: '\n', | |
304 r: '%I:%M:%S %p', | |
305 R: '%H:%M', | |
306 t: '\t', | |
307 T: '%H:%M:%S', | |
308 x: 'locale', | |
309 X: 'locale' | |
310 }; | |
311 Date.ext.aggregates.z = Date.ext.formats.z(new Date()); | |
312 Date.ext.aggregates.Z = Date.ext.formats.Z(new Date()); | |
313 Date.ext.unsupported = { }; | |
314 function strftime(fmt, thisTime) | 331 function strftime(fmt, thisTime) |
315 { | 332 { |
316 var thisDate = new Date(); | 333 var thisDate = new Date(); |
317 thisDate.setTime(thisTime / 1000); | 334 thisDate.setTime(thisTime / 1000); |
318 | 335 return Dt.format(thisDate, fmt); |
319 if(!(thisDate.locale in Date.ext.locales)) | |
320 { | |
321 if(thisDate.locale.replace(/-[a-zA-Z]+$/, '') in Date.ext.locales) | |
322 { | |
323 thisDate.locale = thisDate.locale.replace(/-[a-zA-Z]+$/, ''); | |
324 } | |
325 else | |
326 { | |
327 thisDate.locale = 'en-US'; | |
328 } | |
329 } | |
330 | |
331 var d = thisDate; | |
332 while(fmt.match(/%[cDhnrRtTxXzZ]/)) | |
333 { | |
334 fmt = fmt.replace(/%([cDhnrRtTxXzZ])/g, function(m0, m1) | |
335 { | |
336 var f = Date.ext.aggregates[m1]; | |
337 return (f == 'locale' ? Date.ext.locales[d.locale][m1] : f); | |
338 }); | |
339 } | |
340 | |
341 var str = fmt.replace(/%([aAbBCdegGHIjmMpPSuUVwWyY%])/g, function(m0, m1) | |
342 { | |
343 var f = Date.ext.formats[m1]; | |
344 if(typeof(f) == 'string') { | |
345 return d[f](); | |
346 } else if(typeof(f) == 'function') { | |
347 return f.call(d, d); | |
348 } else if(typeof(f) == 'object' && typeof(f[0]) == 'string') { | |
349 return Date.ext.util.xPad(d[f[0]](), f[1]); | |
350 } else { | |
351 return m1; | |
352 } | |
353 }); | |
354 d=null; | |
355 return str; | |
356 }; | 336 }; |
357 | |
358 // End of code from Philip S Tellis | |
359 | 337 |
360 | 338 |
361 // Error handling | 339 // Error handling |
362 | 340 |
363 function whine(msg) { | 341 function whine(msg) { |