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 * @internal complexity O(n).
470 void Intervals::add(const Interval& new_frame)
472 if (not new_frame.is_valid() or new_frame.empty())
474 // well... we will not insert invalid or empty frames!
477 for (IntervalList::iterator it= m_intervals.begin();
478 it != m_intervals.end();
481 Interval& current_frame = *it;
482 if ( new_frame.m_lower_bound > current_frame.m_upper_bound )
484 // new_frame begins later than current end; go on:
487 // at this point: the begin of the new frame is less then the current end.
488 // now let's determine how we can insert the new frame:
490 if ( new_frame.m_upper_bound < current_frame.m_lower_bound )
492 // new disjoint frame; insert it before the current frame:
493 m_intervals.insert( it, new_frame );
497 // at this point: the end of the new frame is >= current begin.
498 if ( new_frame.m_upper_bound <= current_frame.m_upper_bound )
500 // the end of the new frame is within our current frame; we need to combine
501 if (new_frame.m_lower_bound < current_frame.m_lower_bound)
503 // the new interval starts earlier; we need to adjust our current frame:
504 current_frame.m_lower_bound = new_frame.m_lower_bound;
505 current_frame.m_changed = true;
507 // NOTE no "else" part needed since in that case our current frame already
508 // contains the new one!
513 // at this point: end of new frame > end of current frame
514 // so we need to extend the current frame; at least the end.
515 // But we need to deal with intersects of following frames... *sigh*
517 // first the simple part: let's see if we need to move the start:
518 if ( new_frame.m_lower_bound < current_frame.m_lower_bound)
520 // yes, we need to move the start:
521 current_frame.m_lower_bound = new_frame.m_lower_bound;
522 current_frame.m_changed= true;
525 // now let's extend the end:
526 current_frame.m_upper_bound = new_frame.m_upper_bound;
527 current_frame.m_changed = true;
529 // well... let's walk through the following frames; looking for more joins...:
530 IntervalList::iterator it2 = it;
531 while( ++(it2=it) != m_intervals.end()
532 and current_frame.m_upper_bound >= it2->m_lower_bound
535 Interval next_frame= *it2;
536 if ( current_frame.m_upper_bound < next_frame.m_upper_bound )
538 // in this case our end is within the next frame.
540 current_frame.m_upper_bound = next_frame.m_upper_bound;
542 // and remove the next frame since the current frame contains it (now):
543 m_intervals.erase(it2);
548 // at this point: new frame starts later than the last frame ends
549 // append the new frame:
550 m_intervals.push_back( new_frame );
551 } // eo Intervals::add(const Interval&)
555 * @brief subtracts a time interval from the list.
556 * @param del_frame the time interval to subtract.
558 * removes the time interval from the list; cut off parts from or remove existing
559 * intervals if they overlap.
561 * @internal complexity O(n).
563 void Intervals::sub(const Interval& del_frame)
565 if (not del_frame.is_valid() or del_frame.empty() )
569 for (IntervalList::iterator it= m_intervals.begin();
570 it != m_intervals.end();
573 Interval& current_frame = *it;
574 if ( del_frame.m_lower_bound >= current_frame.m_upper_bound )
576 // del_frame begins later than current end; go on:
580 // at this point: the begin of the del frame is less then the current end.
581 if ( del_frame.m_upper_bound < current_frame.m_lower_bound )
583 // end is before our start; nothing to do.
586 // at this point: the end of the del frame is >= current begin.
587 if ( del_frame.m_upper_bound < current_frame.m_upper_bound )
589 // del frame end point is within our interval.
590 if ( del_frame.m_lower_bound > current_frame.m_lower_bound)
592 // the del frame is within our interval... we need to split:
593 m_intervals.insert(it, Interval( current_frame.m_lower_bound, del_frame.m_lower_bound ) );
595 // adjust start of current frame:
596 if (current_frame.m_lower_bound < del_frame.m_upper_bound)
598 current_frame.m_lower_bound= del_frame.m_upper_bound;
599 current_frame.m_changed= true;
604 // at this point the end of the del frame is >= current end
605 if ( del_frame.m_lower_bound > current_frame.m_lower_bound )
607 // a part of the current interval needs to be preserved..
609 current_frame.m_upper_bound= del_frame.m_lower_bound;
610 current_frame.m_changed= true;
611 // and continue with the next interval:
615 // at this point; the whole frame needs to be deleted..
616 if ( it == m_intervals.begin())
618 m_intervals.erase(it);
619 it= m_intervals.begin();
623 IntervalList::iterator it2= it++;
624 m_intervals.erase(it2);
627 } // eo Intervals::sub(const Interval&)
631 * @brief returns if we contain an interval.
632 * @param other the interval to check.
633 * @return @a true if we cover the given interval, too.
635 bool Intervals::contains(const Interval& other) const
637 for(const_iterator it= begin();
641 if ( it->contains( other ))
647 } // eo Intervals::contains(const Interval&) const
651 * @brief returns if we contain an exact interval.
652 * @param other the interval to check.
653 * @return @a true if we axactly contains the given interval.
655 * @note thsi differs from contain in the way, that we return only @a true
656 * iff we have the given interval in our list; not only cover it.
658 bool Intervals::contains_exact(const Interval& other) const
660 for(const_iterator it= begin();
670 } // eo Intervals::contains_exact(const Interval&)const
674 * @brief returns if we contain another interval combination.
675 * @param other the intervals to check.
676 * @return @a true if we cover the given intervals, too.
678 * @internal we rely on the fact that the lists are sorted and contain
679 * disjoint intervals.
681 * So this method has a complexity of O(n).
683 bool Intervals::contains(const Intervals& other) const
685 const_iterator my_it= begin();
686 const_iterator other_it= other.begin();
687 while( my_it != end() and other_it!= other.end() )
689 // seek the first interval which contains the lower bound of the current other interval
690 while (my_it != end()
691 and my_it->m_lower_bound > other_it->m_lower_bound
692 and other_it->m_lower_bound >= my_it->m_upper_bound
701 if (not my_it->contains( *other_it ))
703 // if we don't contain the current other; we're done:
706 //else check the next other interval:
709 return (other_it == other.end());
710 } // eo Intervals::contains(const Intervals&) const
714 * @brief combines to interval combinates for equality
715 * @param other the other instance.
716 * @return @a true if the other is equal to the current.
718 * @internal since the lists are sorted, we compare the interval lists.
719 * Thus we have a complexity of O(n).
721 bool Intervals::operator==(const Intervals& other) const
723 // since we keep sorted lists: just compare the lists :-)
724 return m_intervals == other.m_intervals;
725 } // eo Intervals::operator==(const Intervals&)
728 Intervals& Intervals::operator+=(const Interval& other)
732 } // eo operator+=(const Interval&)
735 Intervals& Intervals::operator-=(const Interval& other)
739 } // eo operator-=(const Interval&)
743 * @brief adds the intervals of a second instance to us.
744 * @param other the other instance.
745 * @return self reference (allow chaining).
747 * @internal since we do simple loops over the other and our intervals
748 * we have a complexity of O(n^2).
750 * @todo optimize if complexity becomes a problem.
752 Intervals& Intervals::operator+=(const Intervals& other)
754 for(const_iterator it= other.begin();
761 } // eo operator+=(const Intervals&)
765 * @brief subtracts the intervals of a second instance from us.
766 * @param other the other instance.
767 * @return self reference (allow chaining).
769 * @internal since we do simple loops over the other and our intervals
770 * we have a complexity of O(n^2).
772 * @todo optimize if complexity becomes a problem.
774 Intervals& Intervals::operator-=(const Intervals& other)
782 for(const_iterator it= other.begin();
790 } // eo operator-=(const Intervals&)