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) {