2 * @brief time related functions.
4 * @copyright Copyright © 2001-2008 by Intra2net AG
6 * @contact info@intra2net.com
21 #include <sys/timeb.h>
23 #include <timefunc.hxx>
28 double prec_time(void)
35 ret=tb.time+(static_cast<float>(tb.millitm)/1000);
40 // converts ISO-DATE: 2003-06-13
41 int date_to_seconds(const std::string &date)
43 int rtn = -1, year = -1, month = -1, day = -1;
45 string::size_type pos = date.find("-");
46 if (pos == string::npos)
49 istringstream in(string(date,0,pos));
53 string dstr(date, pos+1);
54 if ((pos = dstr.find("-")) == string::npos)
58 in.str(string(dstr, 0, pos));
63 in.str(string(dstr, pos+1));
66 if (year < 0 || month == -1 || day == -1)
70 bzero (&tm_struct, sizeof(struct tm));
71 tm_struct.tm_year = year;
72 tm_struct.tm_mon = month;
73 tm_struct.tm_mday = day;
74 tm_struct.tm_isdst = -1;
76 rtn = mktime (&tm_struct);
80 string make_nice_time(int seconds)
84 int days=seconds/86400;
87 int hours=seconds/3600;
90 int minutes=seconds/60;
94 out << i18n("1 day") << ", ";
96 out << days << ' ' << i18n("days") << ", ";
99 out << setw(2) << hours << ':' << setw(2) << minutes << ':' << setw(2) << seconds;
104 string format_full_time(int seconds)
108 struct tm *ta = localtime ((time_t *)&seconds);
110 strftime (buf, 49, "%d.%m.%Y %H:%M", ta);
114 void seconds_to_hour_minute(int seconds, int *hour, int *minute)
118 while (seconds >= 3600) {
124 if (minute != NULL) {
126 while (seconds >= 60) {
133 std::string output_hour_minute(int hour, int minute, bool h_for_00)
137 if (hour >= 0 && hour < 10)
141 if (!h_for_00 || minute != 0)
144 if (minute >= 0 && minute < 10)
154 WEEK::WEEK(const std::string& daystring)
156 int len=daystring.length();
157 for (int p=0; p < len; p++)
164 if (!(c >> wnr) || wnr<0 || wnr >6)
165 throw range_error("illegal weekday >"+string(nr)+"< in "+daystring);
171 std::string WEEK::get_daystring() const
174 for (int i = 0; i < 7; i++)
181 std::string WEEK::get_displaystring() const
185 // From Monday to Saturday
187 for (int i = 1; i < 7; i++)
191 if (!weekdays_str.empty())
192 weekdays_str += ", ";
194 weekdays_str += get_day_display(static_cast<WEEKDAY>(i));
196 // check if we can group two or more days
198 while (days[j] && j < 7)
202 // Sunday end of week? j -> 7
203 if (j-i > 0 && j == 6 && days[0])
209 weekdays_str += "-" + get_day_display(SU);
211 weekdays_str += "-" + get_day_display(static_cast<WEEKDAY>(j));
219 if (days[0] && j != 7)
221 if (!weekdays_str.empty())
222 weekdays_str += ", ";
224 weekdays_str += get_day_display(SU);
230 std::string WEEK::get_netfilterstring() const
233 for (int i = 0; i < 7; i++)
238 out+=get_english_display(static_cast<WEEKDAY>(i));;
244 std::string WEEK::get_day_display(WEEKDAY day)
250 weekday_str = i18n("Mon");
253 weekday_str = i18n("Tue");
256 weekday_str = i18n("Wed");
259 weekday_str = i18n("Thu");
262 weekday_str = i18n("Fri");
265 weekday_str = i18n("Sat");
268 weekday_str = i18n("Sun");
277 std::string WEEK::get_english_display(WEEKDAY day)
310 string get_month_name(unsigned char month)
315 rtn = i18n("January");
318 rtn = i18n("February");
336 rtn = i18n("August");
339 rtn = i18n("September");
342 rtn = i18n("October");
345 rtn = i18n("November");
348 rtn = i18n("December");
353 out << i18n("Illegal month:") << " " << month;
363 ** implementaion of Interval
368 * @brief clears the interval (make it empty).
370 void Interval::clear()
372 m_lower_bound = m_upper_bound = 0;
373 } // eo Interval::clear()
377 * @brief tests if there is some overlapping with another interval
378 * @param other the other interval
379 * @return @a true if the two intervals have a non empty intersection.
381 bool Interval::intersects(const Interval& other) const
384 // // other start within this:
385 (other.m_lower_bound >= m_lower_bound and other.m_lower_bound < m_upper_bound )
386 // // other end within this:
387 or (other.m_upper_bound > m_lower_bound and other.m_upper_bound <= m_upper_bound )
388 // // other contains this
389 or (other.m_lower_bound <= m_lower_bound and other.m_upper_bound >= m_upper_bound )
391 } // eo Interval::intersects(const Interval&)
395 * @brief tests if the current interval (fully) contains another one.
396 * @param other the other interval.
397 * @return @a true if the current interval fully contains the other interval.
399 bool Interval::contains(const Interval& other) const
401 return (other.m_lower_bound >= m_lower_bound)
402 and (other.m_upper_bound <= m_upper_bound)
404 } // eo Interval::contains(const Interval& other) const
408 ** implementation of Intervals:
412 Intervals::Intervals()
414 } // eo Intervals::Intervals
417 void Intervals::clear()
420 } // eo Intervals::clear()
423 * @brief tests if one of the intervals of the list intersects with the given interval.
424 * @param other the interval to check for intersection.
425 * @return @a true if there is an intersection.
427 bool Intervals::intersects(const Interval& other) const
429 for(const_iterator it= begin();
433 if ( it->intersects(other) )
439 } // eo Intervals::intersects(const Interval&) const
443 * @brief tests if we have at least one intersection with another Intervals instance.
444 * @param other the other instance.
445 * @return @a true if there is an intersection.
447 bool Intervals::intersects(const Intervals& other) const
449 for(const_iterator it= begin();
453 if ( other.intersects( *it ) )
459 } // eo Intervals::intersects(const Intervals&) const
463 * @brief adds a new interval to the list.
464 * @param new_frame the new interval.
466 * Adds the interval to the list and joins overlapping intervals.
468 void Intervals::add(const Interval& new_frame)
470 if (not new_frame.is_valid() or new_frame.empty())
472 // well... we will not insert invalid or empty frames!
475 for (IntervalList::iterator it= m_intervals.begin();
476 it != m_intervals.end();
479 Interval& current_frame = *it;
480 if ( new_frame.m_lower_bound > current_frame.m_upper_bound )
482 // new_frame begins later than current end; go on:
485 // at this point: the begin of the new frame is less then the current end.
486 // now let's determine how we can insert the new frame:
488 if ( new_frame.m_upper_bound < current_frame.m_lower_bound )
490 // new disjoint frame; insert it before the current frame:
491 m_intervals.insert( it, new_frame );
495 // at this point: the end of the new frame is >= current begin.
496 if ( new_frame.m_upper_bound <= current_frame.m_upper_bound )
498 // the end of the new frame is within our current frame; we need to combine
499 if (new_frame.m_lower_bound < current_frame.m_lower_bound)
501 // the new interval starts earlier; we need to adjust our current frame:
502 current_frame.m_lower_bound = new_frame.m_lower_bound;
503 current_frame.m_changed = true;
505 // NOTE no "else" part needed since in that case our current frame already
506 // contains the new one!
511 // at this point: end of new frame > end of current frame
512 // so we need to extend the current frame; at least the end.
513 // But we need to deal with intersects of following frames... *sigh*
515 // first the simple part: let's see if we need to move the start:
516 if ( new_frame.m_lower_bound < current_frame.m_lower_bound)
518 // yes, we need to move the start:
519 current_frame.m_lower_bound = new_frame.m_lower_bound;
520 current_frame.m_changed= true;
523 // now let's extend the end:
524 current_frame.m_upper_bound = new_frame.m_upper_bound;
525 current_frame.m_changed = true;
527 // well... let's walk through the following frames; looking for more joins...:
528 IntervalList::iterator it2 = it;
529 while( ++(it2=it) != m_intervals.end()
530 and current_frame.m_upper_bound >= it2->m_lower_bound
533 Interval next_frame= *it2;
534 if ( current_frame.m_upper_bound < next_frame.m_upper_bound )
536 // in this case our end is within the next frame.
538 current_frame.m_upper_bound = next_frame.m_upper_bound;
540 // and remove the next frame since the current frame contains it (now):
541 m_intervals.erase(it2);
546 // at this point: new frame starts later than the last frame ends
547 // append the new frame:
548 m_intervals.push_back( new_frame );
549 } // eo Intervals::add(const Interval&)
553 * @brief subtracts a time interval from the list.
554 * @param del_frame the time interval to subtract.
556 * removes the time interval from the list; cut off parts from or remove existing
557 * intervals if they overlap.
559 void Intervals::sub(const Interval& del_frame)
561 if (not del_frame.is_valid() or del_frame.empty() )
565 for (IntervalList::iterator it= m_intervals.begin();
566 it != m_intervals.end();
569 Interval& current_frame = *it;
570 if ( del_frame.m_lower_bound >= current_frame.m_upper_bound )
572 // del_frame begins later than current end; go on:
576 // at this point: the begin of the del frame is less then the current end.
577 if ( del_frame.m_upper_bound < current_frame.m_lower_bound )
579 // end is before our start; nothing to do.
582 // at this point: the end of the del frame is >= current begin.
583 if ( del_frame.m_upper_bound < current_frame.m_upper_bound )
585 // del frame end point is within our interval.
586 if ( del_frame.m_lower_bound > current_frame.m_lower_bound)
588 // the del frame is within our interval... we need to split:
589 m_intervals.insert(it, Interval( current_frame.m_lower_bound, del_frame.m_lower_bound ) );
591 // adjust start of current frame:
592 if (current_frame.m_lower_bound < del_frame.m_upper_bound)
594 current_frame.m_lower_bound= del_frame.m_upper_bound;
595 current_frame.m_changed= true;
600 // at this point the end of the del frame is >= current end
601 if ( del_frame.m_lower_bound > current_frame.m_lower_bound )
603 // a part of the current interval needs to be preserved..
605 current_frame.m_upper_bound= del_frame.m_lower_bound;
606 current_frame.m_changed= true;
607 // and continue with the next interval:
611 // at this point; the whole frame needs to be deleted..
612 if ( it == m_intervals.begin())
614 m_intervals.erase(it);
615 it= m_intervals.begin();
619 IntervalList::iterator it2= it++;
620 m_intervals.erase(it2);
623 } // eo Intervals::sub(const Interval&)
627 * @brief returns if we contain an interval.
628 * @param other the interval to check.
629 * @return @a true if we cover the given interval, too.
631 bool Intervals::contains(const Interval& other) const
633 for(const_iterator it= begin();
637 if ( it->contains( other ))
643 } // eo Intervals::contains(const Interval&) const
647 * @brief returns if we contain another interval combination.
648 * @param other the intervals to check.
649 * @return @a true if we cover the given intervals, too.
651 * @internal we rely on the fact that the lists are sorted and contain
652 * disjoint intervals.
654 bool Intervals::contains(const Intervals& other) const
656 const_iterator my_it= begin();
657 const_iterator other_it= other.begin();
658 while( my_it != end() and other_it!= other.end() )
660 // seek the first interval which contains the lower bound of the current other interval
661 while (my_it != end()
662 and my_it->m_lower_bound > other_it->m_lower_bound
663 and other_it->m_lower_bound >= my_it->m_upper_bound
672 if (not my_it->contains( *other_it ))
674 // if we don't contain the current other; we're done:
677 //else check the next other interval:
680 return (other_it == other.end());
681 } // eo Intervals::comtains(const Intervals&) const
684 bool Intervals::operator==(const Intervals& other) const
686 // since we keep sorted lists: just compare the lists :-)
687 return m_intervals == other.m_intervals;
688 } // eo Intervals::operator==(const Intervals&)
691 Intervals& Intervals::operator+=(const Interval& other)
695 } // eo operator+=(const Interval&)
698 Intervals& Intervals::operator-=(const Interval& other)
702 } // eo operator-=(const Interval&)
705 Intervals& Intervals::operator+=(const Intervals& other)
707 for(const_iterator it= other.begin();
714 } // eo operator+=(const Intervals&)
717 Intervals& Intervals::operator-=(const Intervals& other)
725 for(const_iterator it= other.begin();
733 } // eo operator-=(const Intervals&)