gantt_rails 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,584 @@
1
+ /**
2
+ * Copyright (c)2005-2009 Matt Kruse (javascripttoolbox.com)
3
+ *
4
+ * Dual licensed under the MIT and GPL licenses.
5
+ * This basically means you can use this code however you want for
6
+ * free, but don't claim to have written it yourself!
7
+ * Donations always accepted: http://www.JavascriptToolbox.com/donate/
8
+ *
9
+ * Please do not link to the .js files on javascripttoolbox.com from
10
+ * your site. Copy the files locally to your server instead.
11
+ *
12
+ */
13
+ /*
14
+ Date functions
15
+
16
+ These functions are used to parse, format, and manipulate Date objects.
17
+ See documentation and examples at http://www.JavascriptToolbox.com/lib/date/
18
+
19
+ */
20
+ Date.$VERSION = 1.02;
21
+
22
+ // Utility function to append a 0 to single-digit numbers
23
+ Date.LZ = function(x) {return(x<0||x>9?"":"0")+x};
24
+ // Full month names. Change this for local month names
25
+ Date.monthNames = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
26
+ // Month abbreviations. Change this for local month names
27
+ Date.monthAbbreviations = new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
28
+ // Full day names. Change this for local month names
29
+ Date.dayNames = new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
30
+ // Day abbreviations. Change this for local month names
31
+ Date.dayAbbreviations = new Array('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
32
+ // Used for parsing ambiguous dates like 1/2/2000 - default to preferring 'American' format meaning Jan 2.
33
+ // Set to false to prefer 'European' format meaning Feb 1
34
+ Date.preferAmericanFormat = true;
35
+
36
+ // Set to 0=SUn for American 1=Mon for european
37
+ Date.firstDayOfWeek = 0;
38
+
39
+ //default
40
+ Date.defaultFormat="MM/dd/yyyy";
41
+
42
+ // If the getFullYear() method is not defined, create it
43
+ if (!Date.prototype.getFullYear) {
44
+ Date.prototype.getFullYear = function() { var yy=this.getYear(); return (yy<1900?yy+1900:yy); } ;
45
+ }
46
+
47
+ // Parse a string and convert it to a Date object.
48
+ // If no format is passed, try a list of common formats.
49
+ // If string cannot be parsed, return null.
50
+ // Avoids regular expressions to be more portable.
51
+ Date.parseString = function(val, format) {
52
+ // If no format is specified, try a few common formats
53
+ if (typeof(format)=="undefined" || format==null || format=="") {
54
+ var generalFormats=new Array(Date.defaultFormat,'y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d','MMM-d','d-MMM');
55
+ var monthFirst=new Array('M/d/y','M-d-y','M.d.y','M/d','M-d');
56
+ var dateFirst =new Array('d/M/y','d-M-y','d.M.y','d/M','d-M');
57
+ var checkList=new Array(generalFormats,Date.preferAmericanFormat?monthFirst:dateFirst,Date.preferAmericanFormat?dateFirst:monthFirst);
58
+ for (var i=0; i<checkList.length; i++) {
59
+ var l=checkList[i];
60
+ for (var j=0; j<l.length; j++) {
61
+ var d=Date.parseString(val,l[j]);
62
+ if (d!=null) {
63
+ return d;
64
+ }
65
+ }
66
+ }
67
+ return null;
68
+ };
69
+
70
+ this.isInteger = function(val) {
71
+ for (var i=0; i < val.length; i++) {
72
+ if ("1234567890".indexOf(val.charAt(i))==-1) {
73
+ return false;
74
+ }
75
+ }
76
+ return true;
77
+ };
78
+ this.getInt = function(str,i,minlength,maxlength) {
79
+ for (var x=maxlength; x>=minlength; x--) {
80
+ var token=str.substring(i,i+x);
81
+ if (token.length < minlength) {
82
+ return null;
83
+ }
84
+ if (this.isInteger(token)) {
85
+ return token;
86
+ }
87
+ }
88
+ return null;
89
+ };
90
+
91
+
92
+ this.decodeShortcut=function(str){
93
+ var dateUpper = str.trim().toUpperCase();
94
+ var ret=new Date();
95
+ ret.clearTime();
96
+
97
+ if (["NOW","N"].indexOf(dateUpper)>=0) {
98
+ ret= new Date();
99
+
100
+ } else if (["TODAY","T"].indexOf(dateUpper)>=0) {
101
+ //do nothing
102
+
103
+ } else if (["YESTERDAY","Y"].indexOf(dateUpper)>=0) {
104
+ ret.setDate(ret.getDate()-1);
105
+
106
+ } else if (["TOMORROW","TO"].indexOf(dateUpper)>=0) {
107
+ ret.setDate(ret.getDate()+1);
108
+
109
+ } else if (["W", "TW", "WEEK", "THISWEEK", "WEEKSTART", "THISWEEKSTART"].indexOf(dateUpper)>=0) {
110
+ ret.setFirstDayOfThisWeek();
111
+
112
+ } else if (["LW", "LASTWEEK", "LASTWEEKSTART"].indexOf(dateUpper)>=0) {
113
+ ret.setFirstDayOfThisWeek();
114
+ ret.setDate(ret.getDate()-7);
115
+
116
+ } else if (["NW", "NEXTWEEK", "NEXTWEEKSTART"].indexOf(dateUpper)>=0) {
117
+ ret.setFirstDayOfThisWeek();
118
+ ret.setDate(ret.getDate()+7);
119
+
120
+ } else if (["M", "TM", "MONTH", "THISMONTH", "MONTHSTART", "THISMONTHSTART"].indexOf(dateUpper)>=0) {
121
+ ret.setDate(1);
122
+
123
+ } else if (["LM", "LASTMONTH", "LASTMONTHSTART"].indexOf(dateUpper)>=0) {
124
+ ret.setDate(1);
125
+ ret.setMonth(ret.getMonth()-1);
126
+
127
+ } else if (["NM", "NEXTMONTH", "NEXTMONTHSTART"].indexOf(dateUpper)>=0) {
128
+ ret.setDate(1);
129
+ ret.setMonth(ret.getMonth()+1);
130
+
131
+ } else if (["Q", "TQ", "QUARTER", "THISQUARTER", "QUARTERSTART", "THISQUARTERSTART"].indexOf(dateUpper)>=0) {
132
+ ret.setDate(1);
133
+ ret.setMonth(Math.floor((ret.getMonth()) / 3) * 3);
134
+
135
+ } else if (["LQ", "LASTQUARTER", "LASTQUARTERSTART"].indexOf(dateUpper)>=0) {
136
+ ret.setDate(1);
137
+ ret.setMonth(Math.floor((ret.getMonth()) / 3) * 3-3);
138
+
139
+ } else if (["NQ", "NEXTQUARTER", "NEXTQUARTERSTART"].indexOf(dateUpper)>=0) {
140
+ ret.setDate(1);
141
+ ret.setMonth(Math.floor((ret.getMonth()) / 3) * 3+3);
142
+
143
+
144
+ } else if (/^-?[0-9]+[DWMY]$/.test(dateUpper)) {
145
+ var lastOne = dateUpper.substr(dateUpper.length - 1);
146
+ var val = parseInt(dateUpper.substr(0, dateUpper.length - 1));
147
+ if (lastOne=="W")
148
+ ret.setDate(ret.getDate()+val*7 );
149
+ else if (lastOne=="M")
150
+ ret.setMonth(ret.getMonth()+val );
151
+ else if (lastOne=="Y")
152
+ ret.setYear(ret.getYear()+val );
153
+ } else {
154
+ ret=undefined;
155
+ }
156
+
157
+ return ret;
158
+ };
159
+
160
+ var ret=this.decodeShortcut(val);
161
+ if (ret)
162
+ return ret;
163
+
164
+ val=val+"";
165
+ format=format+"";
166
+ var i_val=0;
167
+ var i_format=0;
168
+ var c="";
169
+ var token="";
170
+ var token2="";
171
+ var x,y;
172
+ var year=new Date().getFullYear();
173
+ var month=1;
174
+ var date=1;
175
+ var hh=0;
176
+ var mm=0;
177
+ var ss=0;
178
+ var ampm="";
179
+ while (i_format < format.length) {
180
+ // Get next token from format string
181
+ c=format.charAt(i_format);
182
+ token="";
183
+ while ((format.charAt(i_format)==c) && (i_format < format.length)) {
184
+ token += format.charAt(i_format++);
185
+ }
186
+ // Extract contents of value based on format token
187
+ if (token=="yyyy" || token=="yy" || token=="y") {
188
+ if (token=="yyyy") {
189
+ x=4;y=4;
190
+ }
191
+ if (token=="yy") {
192
+ x=2;y=2;
193
+ }
194
+ if (token=="y") {
195
+ x=2;y=4;
196
+ }
197
+ year=this.getInt(val,i_val,x,y);
198
+ if (year==null) {
199
+ return null;
200
+ }
201
+ i_val += year.length;
202
+ if (year.length==2) {
203
+ if (year > 70) {
204
+ year=1900+(year-0);
205
+ }
206
+ else {
207
+ year=2000+(year-0);
208
+ }
209
+ }
210
+
211
+ // } else if (token=="MMM" || token=="NNN"){
212
+ } else if (token=="MMM" || token=="MMMM"){
213
+ month=0;
214
+ var names = (token=="MMMM"?(Date.monthNames.concat(Date.monthAbbreviations)):Date.monthAbbreviations);
215
+ for (var i=0; i<names.length; i++) {
216
+ var month_name=names[i];
217
+ if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
218
+ month=(i%12)+1;
219
+ i_val += month_name.length;
220
+ break;
221
+ }
222
+ }
223
+ if ((month < 1)||(month>12)){
224
+ return null;
225
+ }
226
+ }
227
+ else if (token=="E"||token=="EE"||token=="EEE"||token=="EEEE"){
228
+ var names = (token=="EEEE"?Date.dayNames:Date.dayAbbreviations);
229
+ for (var i=0; i<names.length; i++) {
230
+ var day_name=names[i];
231
+ if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
232
+ i_val += day_name.length;
233
+ break;
234
+ }
235
+ }
236
+ }
237
+ else if (token=="MM"||token=="M") {
238
+ month=this.getInt(val,i_val,token.length,2);
239
+ if(month==null||(month<1)||(month>12)){
240
+ return null;
241
+ }
242
+ i_val+=month.length;
243
+ }
244
+ else if (token=="dd"||token=="d") {
245
+ date=this.getInt(val,i_val,token.length,2);
246
+ if(date==null||(date<1)||(date>31)){
247
+ return null;
248
+ }
249
+ i_val+=date.length;
250
+ }
251
+ else if (token=="hh"||token=="h") {
252
+ hh=this.getInt(val,i_val,token.length,2);
253
+ if(hh==null||(hh<1)||(hh>12)){
254
+ return null;
255
+ }
256
+ i_val+=hh.length;
257
+ }
258
+ else if (token=="HH"||token=="H") {
259
+ hh=this.getInt(val,i_val,token.length,2);
260
+ if(hh==null||(hh<0)||(hh>23)){
261
+ return null;
262
+ }
263
+ i_val+=hh.length;
264
+ }
265
+ else if (token=="KK"||token=="K") {
266
+ hh=this.getInt(val,i_val,token.length,2);
267
+ if(hh==null||(hh<0)||(hh>11)){
268
+ return null;
269
+ }
270
+ i_val+=hh.length;
271
+ hh++;
272
+ }
273
+ else if (token=="kk"||token=="k") {
274
+ hh=this.getInt(val,i_val,token.length,2);
275
+ if(hh==null||(hh<1)||(hh>24)){
276
+ return null;
277
+ }
278
+ i_val+=hh.length;
279
+ hh--;
280
+ }
281
+ else if (token=="mm"||token=="m") {
282
+ mm=this.getInt(val,i_val,token.length,2);
283
+ if(mm==null||(mm<0)||(mm>59)){
284
+ return null;
285
+ }
286
+ i_val+=mm.length;
287
+ }
288
+ else if (token=="ss"||token=="s") {
289
+ ss=this.getInt(val,i_val,token.length,2);
290
+ if(ss==null||(ss<0)||(ss>59)){
291
+ return null;
292
+ }
293
+ i_val+=ss.length;
294
+ }
295
+ else if (token=="a") {
296
+ if (val.substring(i_val,i_val+2).toLowerCase()=="am") {
297
+ ampm="AM";
298
+ }
299
+ else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {
300
+ ampm="PM";
301
+ }
302
+ else {
303
+ return null;
304
+ }
305
+ i_val+=2;
306
+ }
307
+ else {
308
+ if (val.substring(i_val,i_val+token.length)!=token) {
309
+ return null;
310
+ }
311
+ else {
312
+ i_val+=token.length;
313
+ }
314
+ }
315
+ }
316
+ // If there are any trailing characters left in the value, it doesn't match
317
+ if (i_val != val.length) {
318
+ return null;
319
+ }
320
+ // Is date valid for month?
321
+ if (month==2) {
322
+ // Check for leap year
323
+ if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
324
+ if (date > 29){
325
+ return null;
326
+ }
327
+ }
328
+ else {
329
+ if (date > 28) {
330
+ return null;
331
+ }
332
+ }
333
+ }
334
+ if ((month==4)||(month==6)||(month==9)||(month==11)) {
335
+ if (date > 30) {
336
+ return null;
337
+ }
338
+ }
339
+ // Correct hours value
340
+ if (hh<12 && ampm=="PM") {
341
+ hh=hh-0+12;
342
+ }
343
+ else if (hh>11 && ampm=="AM") {
344
+ hh-=12;
345
+ }
346
+ return new Date(year,month-1,date,hh,mm,ss);
347
+ };
348
+
349
+ // Check if a date string is valid
350
+ Date.isValid = function(val,format) {
351
+ return (Date.parseString(val,format) != null);
352
+ };
353
+
354
+ // Check if a date object is before another date object
355
+ Date.prototype.isBefore = function(date2) {
356
+ if (date2==null) {
357
+ return false;
358
+ }
359
+ return (this.getTime()<date2.getTime());
360
+ };
361
+
362
+ // Check if a date object is after another date object
363
+ Date.prototype.isAfter = function(date2) {
364
+ if (date2==null) {
365
+ return false;
366
+ }
367
+ return (this.getTime()>date2.getTime());
368
+ };
369
+
370
+ // Check if two date objects have equal dates and times
371
+ Date.prototype.equals = function(date2) {
372
+ if (date2==null) {
373
+ return false;
374
+ }
375
+ return (this.getTime()==date2.getTime());
376
+ };
377
+
378
+ // Check if two date objects have equal dates, disregarding times
379
+ Date.prototype.equalsIgnoreTime = function(date2) {
380
+ if (date2==null) {
381
+ return false;
382
+ }
383
+ var d1 = new Date(this.getTime()).clearTime();
384
+ var d2 = new Date(date2.getTime()).clearTime();
385
+ return (d1.getTime()==d2.getTime());
386
+ };
387
+
388
+ // Format a date into a string using a given format string
389
+ Date.prototype.format = function(format) {
390
+ if (!format)
391
+ format=Date.defaultFormat;
392
+ format=format+"";
393
+ var result="";
394
+ var i_format=0;
395
+ var c="";
396
+ var token="";
397
+ var y=this.getFullYear()+"";
398
+ var M=this.getMonth()+1;
399
+ var d=this.getDate();
400
+ var E=this.getDay();
401
+ var H=this.getHours();
402
+ var m=this.getMinutes();
403
+ var s=this.getSeconds();
404
+ // Convert real date parts into formatted versions
405
+ var value=new Object();
406
+ if (y.length < 4) {
407
+ y=""+(+y+1900);
408
+ }
409
+ value["y"]=""+y;
410
+ value["yyyy"]=y;
411
+ value["yy"]=y.substring(2,4);
412
+ value["M"]=M;
413
+ value["MM"]=Date.LZ(M);
414
+ value["MMM"]=Date.monthAbbreviations[M-1];
415
+ value["MMMM"]=Date.monthNames[M-1];
416
+ value["d"]=d;
417
+ value["dd"]=Date.LZ(d);
418
+ value["E"]=Date.dayAbbreviations[E];
419
+ value["EE"]=Date.dayAbbreviations[E];
420
+ value["EEE"]=Date.dayAbbreviations[E];
421
+ value["EEEE"]=Date.dayNames[E];
422
+ value["H"]=H;
423
+ value["HH"]=Date.LZ(H);
424
+ if (H==0){
425
+ value["h"]=12;
426
+ }
427
+ else if (H>12){
428
+ value["h"]=H-12;
429
+ }
430
+ else {
431
+ value["h"]=H;
432
+ }
433
+ value["hh"]=Date.LZ(value["h"]);
434
+ value["K"]=value["h"]-1;
435
+ value["k"]=value["H"]+1;
436
+ value["KK"]=Date.LZ(value["K"]);
437
+ value["kk"]=Date.LZ(value["k"]);
438
+ if (H > 11) {
439
+ value["a"]="PM";
440
+ }
441
+ else {
442
+ value["a"]="AM";
443
+ }
444
+ value["m"]=m;
445
+ value["mm"]=Date.LZ(m);
446
+ value["s"]=s;
447
+ value["ss"]=Date.LZ(s);
448
+ while (i_format < format.length) {
449
+ c=format.charAt(i_format);
450
+ token="";
451
+ while ((format.charAt(i_format)==c) && (i_format < format.length)) {
452
+ token += format.charAt(i_format++);
453
+ }
454
+ if (typeof(value[token])!="undefined") {
455
+ result=result + value[token];
456
+ }
457
+ else {
458
+ result=result + token;
459
+ }
460
+ }
461
+ return result;
462
+ };
463
+
464
+ // Get the full name of the day for a date
465
+ Date.prototype.getDayName = function() {
466
+ return Date.dayNames[this.getDay()];
467
+ };
468
+
469
+ // Get the abbreviation of the day for a date
470
+ Date.prototype.getDayAbbreviation = function() {
471
+ return Date.dayAbbreviations[this.getDay()];
472
+ };
473
+
474
+ // Get the full name of the month for a date
475
+ Date.prototype.getMonthName = function() {
476
+ return Date.monthNames[this.getMonth()];
477
+ };
478
+
479
+ // Get the abbreviation of the month for a date
480
+ Date.prototype.getMonthAbbreviation = function() {
481
+ return Date.monthAbbreviations[this.getMonth()];
482
+ };
483
+
484
+ // Clear all time information in a date object
485
+ Date.prototype.clearTime = function() {
486
+ this.setHours(0);
487
+ this.setMinutes(0);
488
+ this.setSeconds(0);
489
+ this.setMilliseconds(0);
490
+ return this;
491
+ };
492
+
493
+ // Add an amount of time to a date. Negative numbers can be passed to subtract time.
494
+ Date.prototype.add = function(interval, number) {
495
+ if (typeof(interval)=="undefined" || interval==null || typeof(number)=="undefined" || number==null) {
496
+ return this;
497
+ }
498
+ number = +number;
499
+ if (interval=='y') { // year
500
+ this.setFullYear(this.getFullYear()+number);
501
+ }
502
+ else if (interval=='M') { // Month
503
+ this.setMonth(this.getMonth()+number);
504
+ }
505
+ else if (interval=='d') { // Day
506
+ this.setDate(this.getDate()+number);
507
+ }
508
+ else if (interval=='w') { // Weekday
509
+ var step = (number>0)?1:-1;
510
+ while (number!=0) {
511
+ this.add('d',step);
512
+ while(this.getDay()==0 || this.getDay()==6) {
513
+ this.add('d',step);
514
+ }
515
+ number -= step;
516
+ }
517
+ }
518
+ else if (interval=='h') { // Hour
519
+ this.setHours(this.getHours() + number);
520
+ }
521
+ else if (interval=='m') { // Minute
522
+ this.setMinutes(this.getMinutes() + number);
523
+ }
524
+ else if (interval=='s') { // Second
525
+ this.setSeconds(this.getSeconds() + number);
526
+ }
527
+ return this;
528
+
529
+ };
530
+
531
+ Date.prototype.toInt = function () {
532
+ return this.getFullYear()*10000+(this.getMonth()+1)*100+this.getDate();
533
+ };
534
+
535
+ Date.fromInt=function (dateInt){
536
+ var year = parseInt(dateInt/10000);
537
+ var month = parseInt((dateInt-year*10000)/100);
538
+ var day = parseInt(dateInt-year*10000-month*100);
539
+ return new Date(year,month-1,day,12,00,00);
540
+ };
541
+
542
+
543
+ Date.prototype.isHoliday=function(){
544
+ return isHoliday(this);
545
+ };
546
+
547
+ Date.prototype.isToday=function(){
548
+ return this.toInt()==new Date().toInt();
549
+ };
550
+
551
+
552
+ Date.prototype.incrementDateByWorkingDays=function (days) {
553
+ //console.debug("incrementDateByWorkingDays start ",d,days)
554
+ var q = Math.abs(days);
555
+ while (q > 0) {
556
+ this.setDate(this.getDate() + (days > 0 ? 1 : -1));
557
+ if (!this.isHoliday())
558
+ q--;
559
+ }
560
+ return this;
561
+ };
562
+
563
+
564
+ //todo questo può essere poco performante in caso di distanze grandi
565
+ Date.prototype.distanceInWorkingDays= function (toDate){
566
+ var pos = new Date(this.getTime());
567
+ pos.setHours(23, 59, 59, 999);
568
+ var days = 0;
569
+ var nd=new Date(toDate.getTime());
570
+ nd.setHours(23, 59, 59, 999);
571
+ var end=nd.getTime();
572
+ while (pos.getTime() <= end) {
573
+ days = days + (isHoliday(pos) ? 0 : 1);
574
+ pos.setDate(pos.getDate() + 1);
575
+ }
576
+ return days;
577
+ };
578
+
579
+
580
+ Date.prototype.setFirstDayOfThisWeek= function (firstDayOfWeek){
581
+ if (!firstDayOfWeek)
582
+ firstDayOfWeek=Date.firstDayOfWeek;
583
+ this.setDate(this.getDate() - this.getDay() +firstDayOfWeek - (this.getDay()==0 && firstDayOfWeek!=0 ?7:0));
584
+ }