jquery.dateFunction.js 11 KB

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