Make JetStream 2
[WebKit-https.git] / PerformanceTests / JetStream2 / worker / bomb-subtests / date-format-xparb.js
1 /*
2  * Copyright (C) 2004 Baron Schwartz <baron at sequent dot org>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by the
6  * Free Software Foundation, version 2.1.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
11  * details.
12  */
13
14 Date.parseFunctions = {count:0};
15 Date.parseRegexes = [];
16 Date.formatFunctions = {count:0};
17
18 Date.prototype.dateFormat = function(format) {
19     if (Date.formatFunctions[format] == null) {
20         Date.createNewFormat(format);
21     }
22     var func = Date.formatFunctions[format];
23     return this[func]();
24 }
25
26 Date.createNewFormat = function(format) {
27     var funcName = "format" + Date.formatFunctions.count++;
28     Date.formatFunctions[format] = funcName;
29     var code = "Date.prototype." + funcName + " = function(){return ";
30     var special = false;
31     var ch = '';
32     for (var i = 0; i < format.length; ++i) {
33         ch = format.charAt(i);
34         if (!special && ch == "\\") {
35             special = true;
36         }
37         else if (special) {
38             special = false;
39             code += "'" + String.escape(ch) + "' + ";
40         }
41         else {
42             code += Date.getFormatCode(ch);
43         }
44     }
45     eval(code.substring(0, code.length - 3) + ";}");
46 }
47
48 Date.getFormatCode = function(character) {
49     switch (character) {
50     case "d":
51         return "String.leftPad(this.getDate(), 2, '0') + ";
52     case "D":
53         return "Date.dayNames[this.getDay()].substring(0, 3) + ";
54     case "j":
55         return "this.getDate() + ";
56     case "l":
57         return "Date.dayNames[this.getDay()] + ";
58     case "S":
59         return "this.getSuffix() + ";
60     case "w":
61         return "this.getDay() + ";
62     case "z":
63         return "this.getDayOfYear() + ";
64     case "W":
65         return "this.getWeekOfYear() + ";
66     case "F":
67         return "Date.monthNames[this.getMonth()] + ";
68     case "m":
69         return "String.leftPad(this.getMonth() + 1, 2, '0') + ";
70     case "M":
71         return "Date.monthNames[this.getMonth()].substring(0, 3) + ";
72     case "n":
73         return "(this.getMonth() + 1) + ";
74     case "t":
75         return "this.getDaysInMonth() + ";
76     case "L":
77         return "(this.isLeapYear() ? 1 : 0) + ";
78     case "Y":
79         return "this.getFullYear() + ";
80     case "y":
81         return "('' + this.getFullYear()).substring(2, 4) + ";
82     case "a":
83         return "(this.getHours() < 12 ? 'am' : 'pm') + ";
84     case "A":
85         return "(this.getHours() < 12 ? 'AM' : 'PM') + ";
86     case "g":
87         return "((this.getHours() %12) ? this.getHours() % 12 : 12) + ";
88     case "G":
89         return "this.getHours() + ";
90     case "h":
91         return "String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + ";
92     case "H":
93         return "String.leftPad(this.getHours(), 2, '0') + ";
94     case "i":
95         return "String.leftPad(this.getMinutes(), 2, '0') + ";
96     case "s":
97         return "String.leftPad(this.getSeconds(), 2, '0') + ";
98     case "O":
99         return "this.getGMTOffset() + ";
100     case "T":
101         return "this.getTimezone() + ";
102     case "Z":
103         return "(this.getTimezoneOffset() * -60) + ";
104     default:
105         return "'" + String.escape(character) + "' + ";
106     }
107 }
108
109 Date.parseDate = function(input, format) {
110     if (Date.parseFunctions[format] == null) {
111         Date.createParser(format);
112     }
113     var func = Date.parseFunctions[format];
114     return Date[func](input);
115 }
116
117 Date.createParser = function(format) {
118     var funcName = "parse" + Date.parseFunctions.count++;
119     var regexNum = Date.parseRegexes.length;
120     var currentGroup = 1;
121     Date.parseFunctions[format] = funcName;
122
123     var code = "Date." + funcName + " = function(input){\n"
124         + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1;\n"
125         + "var d = new Date();\n"
126         + "y = d.getFullYear();\n"
127         + "m = d.getMonth();\n"
128         + "d = d.getDate();\n"
129         + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n"
130         + "if (results && results.length > 0) {"
131     var regex = "";
132
133     var special = false;
134     var ch = '';
135     for (var i = 0; i < format.length; ++i) {
136         ch = format.charAt(i);
137         if (!special && ch == "\\") {
138             special = true;
139         }
140         else if (special) {
141             special = false;
142             regex += String.escape(ch);
143         }
144         else {
145             obj = Date.formatCodeToRegex(ch, currentGroup);
146             currentGroup += obj.g;
147             regex += obj.s;
148             if (obj.g && obj.c) {
149                 code += obj.c;
150             }
151         }
152     }
153
154     code += "if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n"
155         + "{return new Date(y, m, d, h, i, s);}\n"
156         + "else if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n"
157         + "{return new Date(y, m, d, h, i);}\n"
158         + "else if (y > 0 && m >= 0 && d > 0 && h >= 0)\n"
159         + "{return new Date(y, m, d, h);}\n"
160         + "else if (y > 0 && m >= 0 && d > 0)\n"
161         + "{return new Date(y, m, d);}\n"
162         + "else if (y > 0 && m >= 0)\n"
163         + "{return new Date(y, m);}\n"
164         + "else if (y > 0)\n"
165         + "{return new Date(y);}\n"
166         + "}return null;}";
167
168     Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$");
169     eval(code);
170 }
171
172 Date.formatCodeToRegex = function(character, currentGroup) {
173     switch (character) {
174     case "D":
175         return {g:0,
176         c:null,
177         s:"(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)"};
178     case "j":
179     case "d":
180         return {g:1,
181             c:"d = parseInt(results[" + currentGroup + "], 10);\n",
182             s:"(\\d{1,2})"};
183     case "l":
184         return {g:0,
185             c:null,
186             s:"(?:" + Date.dayNames.join("|") + ")"};
187     case "S":
188         return {g:0,
189             c:null,
190             s:"(?:st|nd|rd|th)"};
191     case "w":
192         return {g:0,
193             c:null,
194             s:"\\d"};
195     case "z":
196         return {g:0,
197             c:null,
198             s:"(?:\\d{1,3})"};
199     case "W":
200         return {g:0,
201             c:null,
202             s:"(?:\\d{2})"};
203     case "F":
204         return {g:1,
205             c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "].substring(0, 3)], 10);\n",
206             s:"(" + Date.monthNames.join("|") + ")"};
207     case "M":
208         return {g:1,
209             c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "]], 10);\n",
210             s:"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"};
211     case "n":
212     case "m":
213         return {g:1,
214             c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n",
215             s:"(\\d{1,2})"};
216     case "t":
217         return {g:0,
218             c:null,
219             s:"\\d{1,2}"};
220     case "L":
221         return {g:0,
222             c:null,
223             s:"(?:1|0)"};
224     case "Y":
225         return {g:1,
226             c:"y = parseInt(results[" + currentGroup + "], 10);\n",
227             s:"(\\d{4})"};
228     case "y":
229         return {g:1,
230             c:"var ty = parseInt(results[" + currentGroup + "], 10);\n"
231                 + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
232             s:"(\\d{1,2})"};
233     case "a":
234         return {g:1,
235             c:"if (results[" + currentGroup + "] == 'am') {\n"
236                 + "if (h == 12) { h = 0; }\n"
237                 + "} else { if (h < 12) { h += 12; }}",
238             s:"(am|pm)"};
239     case "A":
240         return {g:1,
241             c:"if (results[" + currentGroup + "] == 'AM') {\n"
242                 + "if (h == 12) { h = 0; }\n"
243                 + "} else { if (h < 12) { h += 12; }}",
244             s:"(AM|PM)"};
245     case "g":
246     case "G":
247     case "h":
248     case "H":
249         return {g:1,
250             c:"h = parseInt(results[" + currentGroup + "], 10);\n",
251             s:"(\\d{1,2})"};
252     case "i":
253         return {g:1,
254             c:"i = parseInt(results[" + currentGroup + "], 10);\n",
255             s:"(\\d{2})"};
256     case "s":
257         return {g:1,
258             c:"s = parseInt(results[" + currentGroup + "], 10);\n",
259             s:"(\\d{2})"};
260     case "O":
261         return {g:0,
262             c:null,
263             s:"[+-]\\d{4}"};
264     case "T":
265         return {g:0,
266             c:null,
267             s:"[A-Z]{3}"};
268     case "Z":
269         return {g:0,
270             c:null,
271             s:"[+-]\\d{1,5}"};
272     default:
273         return {g:0,
274             c:null,
275             s:String.escape(character)};
276     }
277 }
278
279 Date.prototype.getTimezone = function() {
280     return this.toString().replace(
281         /^.*? ([A-Z]{3}) [0-9]{4}.*$/, "$1").replace(
282         /^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, "$1$2$3");
283 }
284
285 Date.prototype.getGMTOffset = function() {
286     return (this.getTimezoneOffset() > 0 ? "-" : "+")
287         + String.leftPad(Math.floor(this.getTimezoneOffset() / 60), 2, "0")
288         + String.leftPad(this.getTimezoneOffset() % 60, 2, "0");
289 }
290
291 Date.prototype.getDayOfYear = function() {
292     var num = 0;
293     Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
294     for (var i = 0; i < this.getMonth(); ++i) {
295         num += Date.daysInMonth[i];
296     }
297     return num + this.getDate() - 1;
298 }
299
300 Date.prototype.getWeekOfYear = function() {
301     // Skip to Thursday of this week
302     var now = this.getDayOfYear() + (4 - this.getDay());
303     // Find the first Thursday of the year
304     var jan1 = new Date(this.getFullYear(), 0, 1);
305     var then = (7 - jan1.getDay() + 4);
306     document.write(then);
307     return String.leftPad(((now - then) / 7) + 1, 2, "0");
308 }
309
310 Date.prototype.isLeapYear = function() {
311     var year = this.getFullYear();
312     return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
313 }
314
315 Date.prototype.getFirstDayOfMonth = function() {
316     var day = (this.getDay() - (this.getDate() - 1)) % 7;
317     return (day < 0) ? (day + 7) : day;
318 }
319
320 Date.prototype.getLastDayOfMonth = function() {
321     var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7;
322     return (day < 0) ? (day + 7) : day;
323 }
324
325 Date.prototype.getDaysInMonth = function() {
326     Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
327     return Date.daysInMonth[this.getMonth()];
328 }
329
330 Date.prototype.getSuffix = function() {
331     switch (this.getDate()) {
332         case 1:
333         case 21:
334         case 31:
335             return "st";
336         case 2:
337         case 22:
338             return "nd";
339         case 3:
340         case 23:
341             return "rd";
342         default:
343             return "th";
344     }
345 }
346
347 String.escape = function(string) {
348     return string.replace(/('|\\)/g, "\\$1");
349 }
350
351 String.leftPad = function (val, size, ch) {
352     var result = new String(val);
353     if (ch == null) {
354         ch = " ";
355     }
356     while (result.length < size) {
357         result = ch + result;
358     }
359     return result;
360 }
361
362 Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
363 Date.monthNames =
364    ["January",
365     "February",
366     "March",
367     "April",
368     "May",
369     "June",
370     "July",
371     "August",
372     "September",
373     "October",
374     "November",
375     "December"];
376 Date.dayNames =
377    ["Sunday",
378     "Monday",
379     "Tuesday",
380     "Wednesday",
381     "Thursday",
382     "Friday",
383     "Saturday"];
384 Date.y2kYear = 50;
385 Date.monthNumbers = {
386     Jan:0,
387     Feb:1,
388     Mar:2,
389     Apr:3,
390     May:4,
391     Jun:5,
392     Jul:6,
393     Aug:7,
394     Sep:8,
395     Oct:9,
396     Nov:10,
397     Dec:11};
398 Date.patterns = {
399     ISO8601LongPattern:"Y-m-d H:i:s",
400     ISO8601ShortPattern:"Y-m-d",
401     ShortDatePattern: "n/j/Y",
402     LongDatePattern: "l, F d, Y",
403     FullDateTimePattern: "l, F d, Y g:i:s A",
404     MonthDayPattern: "F d",
405     ShortTimePattern: "g:i A",
406     LongTimePattern: "g:i:s A",
407     SortableDateTimePattern: "Y-m-d\\TH:i:s",
408     UniversalSortableDateTimePattern: "Y-m-d H:i:sO",
409     YearMonthPattern: "F, Y"};
410
411 var date = new Date("1/1/2007 1:11:11");
412
413 for (i = 0; i < 4000; ++i) {
414     var shortFormat = date.dateFormat("Y-m-d");
415     var longFormat = date.dateFormat("l, F d, Y g:i:s A");
416     date.setTime(date.getTime() + 84266956);
417 }
418
419 // FIXME: Find a way to validate this test.
420 // https://bugs.webkit.org/show_bug.cgi?id=114849
421
422 postMessage("done");
423 close();