date.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. // ===================================================================
  2. // Original Author: Matt Kruse <matt@mattkruse.com>
  3. // WWW: http://www.mattkruse.com/
  4. //
  5. // NOTICE: You may use this code for any purpose, commercial or
  6. // private, without any further permission from the author. You may
  7. // remove this notice from your final code if you wish, however it is
  8. // appreciated by the author if at least my web site address is kept.
  9. //
  10. // You may *NOT* re-distribute this code in any way except through its
  11. // use. That means, you can include it in your product, or your web
  12. // site, or any other form where the code is actually being used. You
  13. // may not put the plain javascript up on your site for download or
  14. // include it in your javascript libraries for download.
  15. // If you wish to share this code with others, please just point them
  16. // to the URL instead.
  17. // Please DO NOT link directly to my .js files from your site. Copy
  18. // the files to your server and use them there. Thank you.
  19. // ===================================================================
  20. // HISTORY
  21. // ------------------------------------------------------------------
  22. // Jul 23, 2007: Add capital Y and D for Year and Date formats
  23. // Dec 19, 2006: Replaced calls to getYear() with getFullYear()
  24. // Dec 19, 2006: Removed parseDate() function
  25. // Dec 19, 2006: Modified getDateFromFormat() to return Date or null. Also made
  26. // pass null to Date constructor for values it doesn't know.
  27. // Dec 18, 2006: Packaged for use in crystal reports viewer
  28. // May 17, 2003: Fixed bug in parseDate() for dates <1970
  29. // March 11, 2003: Added parseDate() function
  30. // March 11, 2003: Added "NNN" formatting option. Doesn't match up
  31. // perfectly with SimpleDateFormat formats, but
  32. // backwards-compatability was required.
  33. // ------------------------------------------------------------------
  34. // These functions use the same 'format' strings as the
  35. // java.text.SimpleDateFormat class, with minor exceptions.
  36. // The format string consists of the following abbreviations:
  37. //
  38. // Field | Full Form | Short Form
  39. // -------------+--------------------+-----------------------
  40. // Year | yyyy (4 digits) | yy (2 digits), y (2 or 4 digits)
  41. // | YYYY (4 digits) | YY (2 digits), Y (2 or 4 digits)
  42. // Month | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits)
  43. // | NNN (abbr.) |
  44. // Day of Month | dd (2 digits) | d (1 or 2 digits)
  45. // | DD (2 digits) | D (1 or 2 digits)
  46. // Day of Week | EE (name) | E (abbr)
  47. // Hour (1-12) | hh (2 digits) | h (1 or 2 digits)
  48. // Hour (0-23) | HH (2 digits) | H (1 or 2 digits)
  49. // Hour (0-11) | KK (2 digits) | K (1 or 2 digits)
  50. // Hour (1-24) | kk (2 digits) | k (1 or 2 digits)
  51. // Minute | mm (2 digits) | m (1 or 2 digits)
  52. // Second | ss (2 digits) | s (1 or 2 digits)
  53. // AM/PM | a |
  54. //
  55. // NOTE THE DIFFERENCE BETWEEN MM and mm! Month=MM, not mm!
  56. // Examples:
  57. // "MMM d, y" matches: January 01, 2000
  58. // Dec 1, 1900
  59. // Nov 20, 00
  60. // "M/d/yy" matches: 01/20/00
  61. // 9/2/00
  62. // "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM"
  63. // ------------------------------------------------------------------
  64. if (typeof bobj == 'undefined') {
  65. bobj = {};
  66. }
  67. if (typeof bobj.external == 'undefined') {
  68. bobj.external = {};
  69. }
  70. if (typeof bobj.external.date == 'undefined') {
  71. bobj.external.date = {};
  72. }
  73. bobj.external.date.MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
  74. bobj.external.date.DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
  75. bobj.external.date.LZ = function(x) {return(x<0||x>9?"":"0")+x}
  76. // ------------------------------------------------------------------
  77. // isDate ( date_string, format_string )
  78. // Returns true if date string matches format of format string and
  79. // is a valid date. Else returns false.
  80. // It is recommended that you trim whitespace around the value before
  81. // passing it to this function, as whitespace is NOT ignored!
  82. // ------------------------------------------------------------------
  83. bobj.external.date.isDate = function(val,format) {
  84. var date=bobj.external.date.getDateFromFormat(val,format);
  85. if (!date) { return false; }
  86. return true;
  87. }
  88. // -------------------------------------------------------------------
  89. // compareDates(date1,date1format,date2,date2format)
  90. // Compare two date strings to see which is greater.
  91. // Returns:
  92. // 1 if date1 is greater than date2
  93. // 0 if date2 is greater than date1 of if they are the same
  94. // -1 if either of the dates is in an invalid format
  95. // -------------------------------------------------------------------
  96. bobj.external.date.compareDates = function(date1,dateformat1,date2,dateformat2) {
  97. var d1=bobj.external.date.getDateFromFormat(date1,dateformat1);
  98. var d2=bobj.external.date.getDateFromFormat(date2,dateformat2);
  99. if (!d1 || !d2) {
  100. return -1;
  101. }
  102. else if (d1.getTime() > d2.getTime()) {
  103. return 1;
  104. }
  105. return 0;
  106. }
  107. // ------------------------------------------------------------------
  108. // formatDate (date_object, format)
  109. // Returns a date in the output format specified.
  110. // The format string uses the same abbreviations as in getDateFromFormat()
  111. // ------------------------------------------------------------------
  112. bobj.external.date.formatDate = function(date,format) {
  113. format=format+"";
  114. var result="";
  115. var i_format=0;
  116. var c="";
  117. var token="";
  118. var y=date.getFullYear()+"";
  119. var M=date.getMonth()+1;
  120. var d=date.getDate();
  121. var E=date.getDay();
  122. var H=date.getHours();
  123. var m=date.getMinutes();
  124. var s=date.getSeconds();
  125. var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
  126. // Convert real date parts into formatted versions
  127. var value=new Object();
  128. while (y.length < 4) {y="0" + y}
  129. value["y"]=""+y;
  130. value["yyyy"]=y;
  131. value["yy"]=y.substring(2,4);
  132. value["Y"]=value["y"];
  133. value["YY"]=value["yy"];
  134. value["YYYY"]=value["yyyy"];
  135. value["M"]=M;
  136. value["MM"]=bobj.external.date.LZ(M);
  137. value["MMM"]=bobj.external.date.MONTH_NAMES[M-1];
  138. value["NNN"]=bobj.external.date.MONTH_NAMES[M+11];
  139. value["d"]=d;
  140. value["dd"]=bobj.external.date.LZ(d);
  141. value["D"]=value["d"];
  142. value["DD"]=value["dd"];
  143. value["E"]=bobj.external.date.DAY_NAMES[E+7];
  144. value["EE"]=bobj.external.date.DAY_NAMES[E];
  145. value["H"]=H;
  146. value["HH"]=bobj.external.date.LZ(H);
  147. if (H==0){value["h"]=12;}
  148. else if (H>12){value["h"]=H-12;}
  149. else {value["h"]=H;}
  150. value["hh"]=bobj.external.date.LZ(value["h"]);
  151. if (H>11){value["K"]=H-12;} else {value["K"]=H;}
  152. value["k"]=H+1;
  153. value["KK"]=bobj.external.date.LZ(value["K"]);
  154. value["kk"]=bobj.external.date.LZ(value["k"]);
  155. if (H > 11) { value["a"]="PM"; }
  156. else { value["a"]="AM"; }
  157. value["m"]=m;
  158. value["mm"]=bobj.external.date.LZ(m);
  159. value["s"]=s;
  160. value["ss"]=bobj.external.date.LZ(s);
  161. while (i_format < format.length) {
  162. c=format.charAt(i_format);
  163. token="";
  164. while ((format.charAt(i_format)==c) && (i_format < format.length)) {
  165. token += format.charAt(i_format++);
  166. }
  167. if (value[token] != null) { result=result + value[token]; }
  168. else { result=result + token; }
  169. }
  170. return result;
  171. }
  172. // ------------------------------------------------------------------
  173. // Utility functions for parsing in getDateFromFormat()
  174. // ------------------------------------------------------------------
  175. bobj.external.date._isInteger = function(val) {
  176. var digits="1234567890";
  177. for (var i=0; i < val.length; i++) {
  178. if (digits.indexOf(val.charAt(i))==-1) { return false; }
  179. }
  180. return true;
  181. }
  182. bobj.external.date._getInt = function(str,i,minlength,maxlength) {
  183. for (var x=maxlength; x>=minlength; x--) {
  184. var token=str.substring(i,i+x);
  185. if (token.length < minlength) { return null; }
  186. if (bobj.external.date._isInteger(token)) { return token; }
  187. }
  188. return null;
  189. }
  190. // ------------------------------------------------------------------
  191. // getDateFromFormat( date_string , format_string )
  192. //
  193. // This function takes a date string and a format string. It matches
  194. // If the date string matches the format string, it returns the date.
  195. // If it does not match, it returns null.
  196. // ------------------------------------------------------------------
  197. bobj.external.date.getDateFromFormat = function(val,format) {
  198. val=val+"";
  199. format=format+"";
  200. var i_val=0;
  201. var i_format=0;
  202. var c="";
  203. var token="";
  204. var token2="";
  205. var x,y;
  206. var year=null;
  207. var month=null;
  208. var date=null;
  209. var hh=null;
  210. var mm=null;
  211. var ss=null;
  212. var ampm="";
  213. while (i_format < format.length) {
  214. // Get next token from format string
  215. c=format.charAt(i_format);
  216. token="";
  217. while ((format.charAt(i_format)==c) && (i_format < format.length)) {
  218. token += format.charAt(i_format++);
  219. }
  220. // Extract contents of value based on format token
  221. if (token=="yyyy" || token=="YYYY" || token=="yy" || token=="YY" || token=="y" || token=="Y") {
  222. if (token=="yyyy" || token=="YYYY") { x=4;y=4; }
  223. if (token=="yy" || token=="YY") { x=2;y=2; }
  224. if (token=="y" || token=="Y") { x=2;y=4; }
  225. year=bobj.external.date._getInt(val,i_val,x,y);
  226. if (year==null) { return null; }
  227. i_val += year.length;
  228. if (year.length==2) {
  229. if (year > 70) { year=1900+(year-0); }
  230. else { year=2000+(year-0); }
  231. }
  232. }
  233. else if (token=="MMM"||token=="NNN"){
  234. month=0;
  235. for (var i=0; i<bobj.external.date.MONTH_NAMES.length; i++) {
  236. var month_name=bobj.external.date.MONTH_NAMES[i];
  237. if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
  238. if (token=="MMM"||(token=="NNN"&&i>11)) {
  239. month=i+1;
  240. if (month>12) { month -= 12; }
  241. i_val += month_name.length;
  242. break;
  243. }
  244. }
  245. }
  246. if ((month < 1)||(month>12)){return null;}
  247. }
  248. else if (token=="EE"||token=="E"){
  249. for (var i=0; i<bobj.external.date.DAY_NAMES.length; i++) {
  250. var day_name=bobj.external.date.DAY_NAMES[i];
  251. if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
  252. i_val += day_name.length;
  253. break;
  254. }
  255. }
  256. }
  257. else if (token=="MM"||token=="M") {
  258. month=bobj.external.date._getInt(val,i_val,token.length,2);
  259. if(month==null||(month<1)||(month>12)){return null;}
  260. i_val+=month.length;}
  261. else if (token=="dd"||token=="DD"||token=="d"||token=="D") {
  262. date=bobj.external.date._getInt(val,i_val,token.length,2);
  263. if(date==null||(date<1)||(date>31)){return null;}
  264. i_val+=date.length;}
  265. else if (token=="hh"||token=="h") {
  266. hh=bobj.external.date._getInt(val,i_val,token.length,2);
  267. if(hh==null||(hh<1)||(hh>12)){return null;}
  268. i_val+=hh.length;}
  269. else if (token=="HH"||token=="H") {
  270. hh=bobj.external.date._getInt(val,i_val,token.length,2);
  271. if(hh==null||(hh<0)||(hh>23)){return null;}
  272. i_val+=hh.length;}
  273. else if (token=="KK"||token=="K") {
  274. hh=bobj.external.date._getInt(val,i_val,token.length,2);
  275. if(hh==null||(hh<0)||(hh>11)){return null;}
  276. i_val+=hh.length;}
  277. else if (token=="kk"||token=="k") {
  278. hh=bobj.external.date._getInt(val,i_val,token.length,2);
  279. if(hh==null||(hh<1)||(hh>24)){return null;}
  280. i_val+=hh.length;hh--;}
  281. else if (token=="mm"||token=="m") {
  282. mm=bobj.external.date._getInt(val,i_val,token.length,2);
  283. if(mm==null||(mm<0)||(mm>59)){return null;}
  284. i_val+=mm.length;}
  285. else if (token=="ss"||token=="s") {
  286. ss=bobj.external.date._getInt(val,i_val,token.length,2);
  287. if(ss==null||(ss<0)||(ss>59)){return null;}
  288. i_val+=ss.length;}
  289. else if (token=="a") {
  290. if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
  291. else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
  292. else {return null;}
  293. i_val+=2;}
  294. else {
  295. if (val.substring(i_val,i_val+token.length)!=token) {return null;}
  296. else {i_val+=token.length;}
  297. }
  298. }
  299. // If there are any trailing characters left in the value, it doesn't match
  300. if (i_val != val.length) { return null; }
  301. // Is date valid for month?
  302. if (month==2) {
  303. // Check for leap year
  304. if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
  305. if (date > 29){ return null; }
  306. }
  307. else { if (date > 28) { return null; } }
  308. }
  309. if ((month==4)||(month==6)||(month==9)||(month==11)) {
  310. if (date > 30) { return null; }
  311. }
  312. // Correct hours value
  313. if (hh !== null) {
  314. if (hh<12 && ampm=="PM") { hh=hh-0+12; }
  315. else if (hh>11 && ampm=="AM") { hh-=12; }
  316. }
  317. var newDate = new Date(year,month-1,date,hh,mm,ss);
  318. newDate.setFullYear(year);
  319. return newDate;
  320. }