aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/js/RrdTime.js
diff options
context:
space:
mode:
authorPim van den Berg2013-05-10 21:36:54 +0200
committerPim van den Berg2013-05-10 21:36:54 +0200
commit0163faefef02207ad0ea3330af688103633293ff (patch)
treec407fca93a3418af59c4c7133327f5bc1630fba5 /js/RrdTime.js
parentMerge pull request #5 from mce35/nut (diff)
downloadapt-panopticon_cgp-0163faefef02207ad0ea3330af688103633293ff.zip
apt-panopticon_cgp-0163faefef02207ad0ea3330af688103633293ff.tar.gz
apt-panopticon_cgp-0163faefef02207ad0ea3330af688103633293ff.tar.bz2
apt-panopticon_cgp-0163faefef02207ad0ea3330af688103633293ff.tar.xz
import js directory from jsrrdgraph for client side graph rendering
Source: https://github.com/manuelluis/jsrrdgraph@276b880
Diffstat (limited to 'js/RrdTime.js')
-rw-r--r--js/RrdTime.js621
1 files changed, 621 insertions, 0 deletions
diff --git a/js/RrdTime.js b/js/RrdTime.js
new file mode 100644
index 0000000..95ea0ae
--- /dev/null
+++ b/js/RrdTime.js
@@ -0,0 +1,621 @@
1/**
2 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the Free
5 * Software Foundation; either version 2 of the License, or (at your option)
6 * any later version.
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
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
16
17 * RRDtool 1.4.5 Copyright by Tobi Oetiker, 1997-2010
18 *
19 * Convert to javascript: Manuel Sanmartin <manuel.luis at gmail.com>
20 **/
21
22"use strict";
23
24/**
25 * RrdTimeError
26 * @constructor
27 */
28var RrdTimeError = function (message)
29{
30 this.prototype = Error.prototype;
31 this.name = "RrdTimeError";
32 this.message = (message) ? message : "Error";
33};
34
35/**
36 * RrdTime
37 * @constructor
38 */
39var RrdTime = function(tspec) /* parser */
40{
41 var date = new Date();
42 var hr = 0;
43
44 this.tspec = tspec;
45
46 this.tokens = (tspec+'').match(/[0-9]+|[A-Za-z]+|[:.+-\/]/g);
47 this.toklen = this.tokens.length;
48 this.tokidx = 0;
49
50 this.token = null;
51 this.tokid = 0;
52
53 this.specials = RrdTime.VARIOUSWORDS;
54
55 /* establish the default time reference */
56 this.type = RrdTime.ABSOLUTE_TIME;
57 this.offset = 0;
58 this.tm_sec = date.getSeconds();
59 this.tm_min = date.getMinutes();
60 this.tm_hour = date.getHours();
61 this.tm_mday = date.getDate();
62 this.tm_mon = date.getMonth();
63 this.tm_year = date.getFullYear()-1900;
64 this.tm_wday = date.getDay();
65
66 this.gettok();
67 switch (this.tokid) {
68 case RrdTime.PLUS:
69 case RrdTime.MINUS:
70 break; /* jump to OFFSET-SPEC part */
71 case RrdTime.EPOCH:
72 this.type = RrdTime.RELATIVE_TO_EPOCH;
73 case RrdTime.START:
74 case RrdTime.END:
75 if (this.tokid === RrdTime.EPOCH)
76 this.type = RrdTime.RELATIVE_TO_START_TIME;
77 else
78 this.type = RrdTime.RELATIVE_TO_END_TIME;
79 this.tm_sec = 0;
80 this.tm_min = 0;
81 this.tm_hour = 0;
82 this.tm_mday = 0;
83 this.tm_mon = 0;
84 this.tm_year = 0;
85 case RrdTime.NOW:
86 var time_reference = this.tokid;
87 this.gettok();
88 if (this.tokid == RrdTime.PLUS || this.tokid == RrdTime.MINUS)
89 break;
90 if (time_reference != RrdTime.NOW) {
91 throw new RrdTimeError("'start' or 'end' MUST be followed by +|- offset");
92 } else if (this.tokid != RrdTime.EOF) {
93 throw new RrdTimeError("if 'now' is followed by a token it must be +|- offset");
94 }
95 break;
96 case RrdTime.NUMBER: /* Only absolute time specifications below */
97 var hour_sv = this.tm_hour;
98 var year_sv = this.tm_year;
99 this.tm_hour = 30;
100 this.tm_year = 30000;
101 this.tod();
102 this.day();
103 if (this.tm_hour == 30 && this.tm_year != 30000)
104 this.tod();
105 if (this.tm_hour == 30)
106 this.tm_hour = hour_sv;
107 if (this.tm_year == 30000)
108 this.tm_year = year_sv;
109 break;
110 case RrdTime.JAN:
111 case RrdTime.FEB:
112 case RrdTime.MAR:
113 case RrdTime.APR:
114 case RrdTime.MAY:
115 case RrdTime.JUN:
116 case RrdTime.JUL:
117 case RrdTime.AUG:
118 case RrdTime.SEP:
119 case RrdTime.OCT:
120 case RrdTime.NOV:
121 case RrdTime.DEC:
122 this.day();
123 if (this.tokid != RrdTime.NUMBER)
124 break;
125 this.tod();
126 break;
127 case RrdTime.TEATIME:
128 hr += 4;
129 case RrdTime.NOON:
130 hr += 12;
131 case RrdTime.MIDNIGHT:
132 this.tm_hour = hr;
133 this.tm_min = 0;
134 this.tm_sec = 0;
135 this.gettok();
136 this.day();
137 break;
138 default:
139 throw new RrdTimeError("unparsable time: "+this.token+" "+this.sct);
140 break;
141 } /* ugly case statement */
142
143 /*
144 * the OFFSET-SPEC part
145 * (NOTE, the sc_tokid was prefetched for us by the previous code)
146 */
147 if (this.tokid == RrdTime.PLUS || this.tokid == RrdTime.MINUS) {
148 this.specials = RrdTime.TIMEMULTIPLIERS; /* switch special words context */
149 while (this.tokid == RrdTime.PLUS || this.tokid == RrdTime.MINUS || this.tokid == RrdTime.NUMBER) {
150 if (this.tokid == RrdTime.NUMBER) {
151 this.plus_minus(-1);
152 } else {
153 this.plus_minus(this.tokid);
154 }
155 this.gettok(); /* We will get EOF eventually but that's OK, since token() will return us as many EOFs as needed */
156 }
157 }
158
159 /* now we should be at EOF */
160 if (this.tokid != RrdTime.EOF)
161 throw new RrdTimeError("unparsable trailing text: '..."+this.token+"'");
162// if (this.type == RrdTime.ABSOLUTE_TIME)
163// if (mktime(&ptv->tm) == -1) // FIXME ??
164// panic(e("the specified time is incorrect (out of range?)"));
165};
166
167RrdTime.EOF = -1;
168RrdTime.MIDNIGHT = 0;
169RrdTime.NOON = 1;
170RrdTime.TEATIME = 2;
171RrdTime.PM = 3;
172RrdTime.AM = 4;
173RrdTime.YESTERDAY = 5;
174RrdTime.TODAY = 6;
175RrdTime.TOMORROW = 7;
176RrdTime.NOW = 8;
177RrdTime.START = 9;
178RrdTime.END = 10;
179RrdTime.EPOCH = 11;
180RrdTime.SECONDS = 12;
181RrdTime.MINUTES = 13;
182RrdTime.HOURS = 14;
183RrdTime.DAYS = 15;
184RrdTime.WEEKS = 16;
185RrdTime.MONTHS = 17;
186RrdTime.YEARS = 18;
187RrdTime.MONTHS_MINUTES = 19;
188RrdTime.NUMBER = 20;
189RrdTime.PLUS = 21;
190RrdTime.MINUS = 22;
191RrdTime.DOT = 23;
192RrdTime.COLON = 24;
193RrdTime.SLASH = 25;
194RrdTime.ID = 26;
195RrdTime.JUNK = 27;
196RrdTime.JAN = 28;
197RrdTime.FEB = 29;
198RrdTime.MAR = 30;
199RrdTime.APR = 31;
200RrdTime.MAY = 32;
201RrdTime.JUN = 33;
202RrdTime.JUL = 34;
203RrdTime.AUG = 35;
204RrdTime.SEP = 36;
205RrdTime.OCT = 37;
206RrdTime.NOV = 38;
207RrdTime.DEC = 39;
208RrdTime.SUN = 40;
209RrdTime.MON = 41;
210RrdTime.TUE = 42;
211RrdTime.WED = 43;
212RrdTime.THU = 44;
213RrdTime.FRI = 45;
214RrdTime.SAT = 46;
215
216RrdTime.VARIOUSWORDS = {
217 "midnight": RrdTime.MIDNIGHT, /* 00:00:00 of today or tomorrow */
218 "noon": RrdTime.NOON, /* 12:00:00 of today or tomorrow */
219 "teatime": RrdTime.TEATIME, /* 16:00:00 of today or tomorrow */
220 "am": RrdTime.AM, /* morning times for 0-12 clock */
221 "pm": RrdTime.PM, /* evening times for 0-12 clock */
222 "tomorrow": RrdTime.TOMORROW,
223 "yesterday": RrdTime.YESTERDAY,
224 "today": RrdTime.TODAY,
225 "now": RrdTime.NOW,
226 "n": RrdTime.NOW,
227 "start": RrdTime.START,
228 "s": RrdTime.START,
229 "end": RrdTime.END,
230 "e": RrdTime.END,
231 "epoch": RrdTime.EPOCH,
232 "jan": RrdTime.JAN,
233 "feb": RrdTime.FEB,
234 "mar": RrdTime.MAR,
235 "apr": RrdTime.APR,
236 "may": RrdTime.MAY,
237 "jun": RrdTime.JUN,
238 "jul": RrdTime.JUL,
239 "aug": RrdTime.AUG,
240 "sep": RrdTime.SEP,
241 "oct": RrdTime.OCT,
242 "nov": RrdTime.NOV,
243 "dec": RrdTime.DEC,
244 "january": RrdTime.JAN,
245 "february": RrdTime.FEB,
246 "march": RrdTime.MAR,
247 "april": RrdTime.APR,
248// "may": RrdTime.MAY,
249 "june": RrdTime.JUN,
250 "july": RrdTime.JUL,
251 "august": RrdTime.AUG,
252 "september": RrdTime.SEP,
253 "october": RrdTime.OCT,
254 "november": RrdTime.NOV,
255 "december": RrdTime.DEC,
256 "sunday": RrdTime.SUN,
257 "sun": RrdTime.SUN,
258 "monday": RrdTime.MON,
259 "mon": RrdTime.MON,
260 "tuesday": RrdTime.TUE,
261 "tue": RrdTime.TUE,
262 "wednesday": RrdTime.WED,
263 "wed": RrdTime.WED,
264 "thursday": RrdTime.THU,
265 "thu": RrdTime.THU,
266 "friday": RrdTime.FRI,
267 "fri": RrdTime.FRI,
268 "saturday": RrdTime.SAT,
269 "sat": RrdTime.SAT
270};
271
272RrdTime.TIMEMULTIPLIERS = {
273 "second": RrdTime.SECONDS, /* seconds multiplier */
274 "seconds": RrdTime.SECONDS, /* (pluralized) */
275 "sec": RrdTime.SECONDS, /* (generic) */
276 "s": RrdTime.SECONDS, /* (short generic) */
277 "minute": RrdTime.MINUTES, /* minutes multiplier */
278 "minutes": RrdTime.MINUTES, /* (pluralized) */
279 "min": RrdTime.MINUTES, /* (generic) */
280 "m": RrdTime.MONTHS_MINUTES, /* (short generic) */
281 "hour": RrdTime.HOURS, /* hours ... */
282 "hours": RrdTime.HOURS, /* (pluralized) */
283 "hr": RrdTime.HOURS, /* (generic) */
284 "h": RrdTime.HOURS, /* (short generic) */
285 "day": RrdTime.DAYS, /* days ... */
286 "days": RrdTime.DAYS, /* (pluralized) */
287 "d": RrdTime.DAYS, /* (short generic) */
288 "week": RrdTime.WEEKS, /* week ... */
289 "weeks": RrdTime.WEEKS, /* (pluralized) */
290 "wk": RrdTime.WEEKS, /* (generic) */
291 "w": RrdTime.WEEKS, /* (short generic) */
292 "month": RrdTime.MONTHS, /* week ... */
293 "months": RrdTime.MONTHS, /* (pluralized) */
294 "mon": RrdTime.MONTHS, /* (generic) */
295 "year": RrdTime.YEARS, /* year ... */
296 "years": RrdTime.YEARS, /* (pluralized) */
297 "yr": RrdTime.YEARS, /* (generic) */
298 "y": RrdTime.YEARS /* (short generic) */
299};
300
301RrdTime.ABSOLUTE_TIME = 0;
302RrdTime.RELATIVE_TO_START_TIME = 1;
303RrdTime.RELATIVE_TO_END_TIME = 2;
304RrdTime.RELATIVE_TO_EPOCH = 3;
305
306RrdTime.prototype.gettok = function ()
307{
308 if (this.tokidx >= this.toklen) {
309 this.tokid = RrdTime.EOF;
310 } else {
311 this.token = this.tokens[this.tokidx];
312 this.tokidx++;
313 if (!isNaN(this.token)) {
314 this.tokid = RrdTime.NUMBER;
315 this.token = parseInt(this.token, 10);
316 } else if (this.token === ':') {
317 this.tokid = RrdTime.COLON;
318 } else if (this.token === '.') {
319 this.tokid = RrdTime.DOT;
320 } else if (this.token === '+') {
321 this.tokid = RrdTime.PLUS;
322 } else if (this.token === '/') {
323 this.tokid = RrdTime.SLASH;
324 } else if (this.token === '-') {
325 this.tokid = RrdTime.MINUS;
326 } else {
327 this.tokid = RrdTime.ID;
328 if (this.token in this.specials)
329 this.tokid = this.specials[this.token];
330 }
331 }
332 return this.tokid;
333};
334
335RrdTime.prototype.plus_minus = function (doop)
336{
337 var op = RrdTime.PLUS;
338 var prev_multiplier = -1;
339 var delta;
340
341 if (doop >= 0) {
342 op = doop;
343 if (this.gettok() != RrdTime.NUMBER)
344 throw new RrdTimeError("There should be number after '"+(op == RrdTime.PLUS ? '+' : '-')+"'");
345 prev_multiplier = -1; /* reset months-minutes guessing mechanics */
346 }
347 /* if doop is < 0 then we repeat the previous op with the prefetched number */
348 delta = this.token;
349 if (this.gettok() == RrdTime.MONTHS_MINUTES) {
350 /* hard job to guess what does that -5m means: -5mon or -5min? */
351 switch (prev_multiplier) {
352 case RrdTime.DAYS:
353 case RrdTime.WEEKS:
354 case RrdTime.MONTHS:
355 case RrdTime.YEARS:
356 this.tokid = RrdTime.MONTHS;
357 break;
358 case RrdTime.SECONDS:
359 case RrdTime.MINUTES:
360 case RrdTime.HOURS:
361 this.tokid = RrdTime.MINUTES;
362 break;
363 default:
364 if (delta < 6) /* it may be some other value but in the context of RRD who needs less than 6 min deltas? */
365 this.tokid = RrdTime.MONTHS;
366 else
367 this.tokid = RrdTime.MINUTES;
368 }
369 }
370 prev_multiplier = this.tokid;
371 switch (this.tokid) {
372 case RrdTime.YEARS:
373 this.tm_year += ( op == RrdTime.PLUS) ? delta : -delta;
374 return;
375 case RrdTime.MONTHS:
376 this.tm_mon += ( op == RrdTime.PLUS) ? delta : -delta;
377 return;
378 case RrdTime.WEEKS:
379 delta *= 7;
380 case RrdTime.DAYS:
381 this.tm_mday += ( op == RrdTime.PLUS) ? delta : -delta;
382 return;
383 case RrdTime.HOURS:
384 this.offset += (op == RrdTime.PLUS) ? delta * 60 * 60 : -delta * 60 * 60;
385 return;
386 case RrdTime.MINUTES:
387 this.offset += (op == RrdTime.PLUS) ? delta * 60 : -delta * 60;
388 return;
389 case RrdTime.SECONDS:
390 this.offset += (op == RrdTime.PLUS) ? delta : -delta;
391 return;
392 default: /*default unit is seconds */
393 this.offset += (op == RrdTime.PLUS) ? delta : -delta;
394 return;
395 }
396 throw new RrdTimeError("well-known time unit expected after "+delta);
397};
398
399RrdTime.prototype.tod = function() /* tod() computes the time of day (TIME-OF-DAY-SPEC) */
400{
401 var hour, minute = 0;
402 var tlen;
403 /* save token status in case we must abort */
404 var tokid_sv = this.tokid;
405
406 tlen = (this.token+"").length;
407 /* first pick out the time of day - we assume a HH (COLON|DOT) MM time */
408 if (tlen > 2)
409 return;
410 hour = this.token;
411 this.gettok();
412 if (this.tokid == RrdTime.SLASH || this.tokid == RrdTime.DOT) {
413 /* guess we are looking at a date */
414 this.tokid = tokid_sv;
415 this.token = hour;
416 return;
417 }
418 if (this.tokid == RrdTime.COLON) {
419 if (this.gettok() != RrdTime.NUMBER)
420 throw new RrdTimeError("Parsing HH:MM syntax, expecting MM as number, got none");
421 minute = this.token;
422 if (minute > 59)
423 throw new RrdTimeError("parsing HH:MM syntax, got MM = "+minute+" (>59!)");
424 this.gettok();
425 }
426 /* check if an AM or PM specifier was given */
427 if (this.tokid == RrdTime.AM || this.tokid == RrdTime.PM) {
428 if (hour > 12) {
429 throw new RrdTimeError("there cannot be more than 12 AM or PM hours");
430 }
431 if (this.tokid == RrdTime.PM) {
432 if (hour != 12) /* 12:xx PM is 12:xx, not 24:xx */
433 hour += 12;
434 } else {
435 if (hour == 12) /* 12:xx AM is 00:xx, not 12:xx */
436 hour = 0;
437 }
438 this.gettok();
439 } else if (hour > 23) {
440 /* guess it was not a time then ... */
441 this.tokid = tokid_sv;
442 this.token = hour;
443 return;
444 }
445 this.tm_hour = hour;
446 this.tm_min = minute;
447 this.tm_sec = 0;
448 if (this.tm_hour == 24) {
449 this.tm_hour = 0;
450 this.tm_mday++;
451 }
452};
453
454RrdTime.prototype.assign_date = function(mday, mon, year)
455{
456 if (year > 138) {
457 if (year > 1970) {
458 year -= 1900;
459 } else {
460 throw new RrdTimeError("invalid year "+year+" (should be either 00-99 or >1900)");
461 }
462 } else if (year >= 0 && year < 38) {
463 year += 100; /* Allow year 2000-2037 to be specified as */
464 }
465 /* 00-37 until the problem of 2038 year will */
466 /* arise for unices with 32-bit time_t :) */
467 if (year < 70)
468 throw new RrdTimeError("won't handle dates before epoch (01/01/1970), sorry");
469
470 this.tm_mday = mday;
471 this.tm_mon = mon;
472 this.tm_year = year;
473};
474
475RrdTime.prototype.day = function ()
476{
477 var mday = 0, wday, mon, year = this.tm_year;
478 var tlen;
479
480 switch (this.tokid) {
481 case RrdTime.YESTERDAY:
482 this.tm_mday--;
483 case RrdTime.TODAY:
484 this.gettok();
485 break;
486 case RrdTime.TOMORROW:
487 this.tm_mday++;
488 this.gettok();
489 break;
490 case RrdTime.JAN:
491 case RrdTime.FEB:
492 case RrdTime.MAR:
493 case RrdTime.APR:
494 case RrdTime.MAY:
495 case RrdTime.JUN:
496 case RrdTime.JUL:
497 case RrdTime.AUG:
498 case RrdTime.SEP:
499 case RrdTime.OCT:
500 case RrdTime.NOV:
501 case RrdTime.DEC:
502 mon = (this.tokid - RrdTime.JAN);
503 if (this.gettok() != RrdTime.NUMBER)
504 throw new RrdTimeError("the day of the month should follow month name");
505 mday = this.token;
506 if (this.gettok() == RrdTime.NUMBER) {
507 year = this.token;
508 this.gettok();
509 } else {
510 year = this.tm_year;
511 }
512 this.assign_date(mday, mon, year);
513 break;
514 case RrdTime.SUN:
515 case RrdTime.MON:
516 case RrdTime.TUE:
517 case RrdTime.WED:
518 case RrdTime.THU:
519 case RrdTime.FRI:
520 case RrdTime.SAT:
521 wday = (this.tokid - RrdTime.SUN);
522 this.tm_mday += (wday - this.tm_wday);
523 this.gettok();
524 break;
525 case RrdTime.NUMBER:
526 mon = this.token;
527 if (mon > 10 * 365 * 24 * 60 * 60) {
528 this.localtime(mon);
529 this.gettok();
530 break;
531 }
532 if (mon > 19700101 && mon < 24000101) { /*works between 1900 and 2400 */
533 var str = this.token + '';
534 year = parseInt(str.substr(0,4),10);
535 mon = parseInt(str.substr(4,2),10);
536 mday = parseInt(str.substr(6,2),10);
537 this.gettok();
538 } else {
539 this.gettok();
540 if (mon <= 31 && (this.tokid == RrdTime.SLASH || this.tokid == RrdTime.DOT)) {
541 var sep = this.tokid;
542 if (this.gettok() != RrdTime.NUMBER)
543 throw new RrdTimeError("there should be "+(RrdTime.DOT ? "month" : "day")+" number after '"+(RrdTime.DOT ? '.' : '/')+"'");
544 mday = this.token;
545 if (this.gettok() == sep) {
546 if (this.gettok() != RrdTime.NUMBER)
547 throw new RrdTimeError("there should be year number after '"+(sep == RrdTime.DOT ? '.' : '/')+"'");
548 year = this.token;
549 this.gettok();
550 }
551 if (sep == RrdTime.DOT) {
552 var x = mday;
553 mday = mon;
554 mon = x;
555 }
556 }
557 }
558 mon--;
559 if (mon < 0 || mon > 11)
560 throw new RrdTimeError("did you really mean month "+(mon+1)+"?");
561 if (mday < 1 || mday > 31)
562 throw new RrdTimeError("I'm afraid that "+mday+" is not a valid day of the month");
563 this.assign_date(mday, mon, year);
564 break;
565 }
566};
567
568RrdTime.prototype.localtime = function (tm)
569{
570 var date = new Date(tm*1000);
571 this.tm_sec = date.getSeconds();
572 this.tm_min = date.getMinutes();
573 this.tm_hour = date.getHours();
574 this.tm_mday = date.getDate();
575 this.tm_mon = date.getMonth();
576 this.tm_year = date.getFullYear()-1900;
577 this.tm_wday = date.getDay();
578};
579
580RrdTime.prototype.mktime = function()
581{
582 var date = new Date(this.tm_year+1900, this.tm_mon, this.tm_mday, this.tm_hour, this.tm_min, this.tm_sec);
583 return Math.round(date.getTime()/1000.0);
584};
585
586RrdTime.proc_start_end = function(start_t, end_t)
587{
588 var start, end;
589
590 if (start_t.type == RrdTime.RELATIVE_TO_END_TIME && end_t.type == RrdTime.RELATIVE_TO_START_TIME)
591 throw new RrdTimeError("the start and end times cannot be specified relative to each other");
592 if (start_t.type == RrdTime.RELATIVE_TO_START_TIME)
593 throw new RrdTimeError("the start time cannot be specified relative to itself");
594 if (end_t.type == RrdTime.RELATIVE_TO_END_TIME)
595 throw new RrdTimeError("the end time cannot be specified relative to itself");
596
597 if (start_t.type == RrdTime.RELATIVE_TO_END_TIME) {
598 end = end_t.mktime() + end_t.offset;
599 var tmtmp = new Date(end*1000);
600 tmtmp.setDate(tmtmp.getDate()+start_t.tm_mday);
601 tmtmp.setMonth(tmtmp.getMonth()+start_t.tm_mon);
602 tmtmp.setFullYear(tmtmp.getFullYear()+start_t.tm_year);
603 start = Math.round(tmtmp.getTime()/1000.0) + start_t.offset;
604 } else {
605 start = start_t.mktime() + start_t.offset;
606 }
607
608 if (end_t.type == RrdTime.RELATIVE_TO_START_TIME) {
609 start = start_t.mktime() + start_t.offset;
610 var tmtmp = new Date(start*1000);
611 tmtmp.setDate(tmtmp.getDate()+end_t.tm_mday);
612 tmtmp.setMonth(tmtmp.getMonth()+end_t.tm_mon);
613 tmtmp.setFullYear(tmtmp.getFullYear()+end_t.tm_year);
614 end = Math.round(tmtmp.getTime()/1000.0) + end_t.offset;
615 } else {
616 end = end_t.mktime() + end_t.offset;
617 }
618
619 return [start, end];
620};
621