00001 #include "duration.h"
00002
00003 #include <tools/invaliddataexception.h>
00004
00005 #include <limits.h>
00006 #include <QStringList>
00007 #include <QDateTime>
00008
00009 namespace domain
00010 {
00011
00017 enum
00018 {
00019 DAYS_PER_WEEK = 7,
00020 HOURS_PER_DAY = 24,
00021 MINUTES_PER_HOUR = 60,
00022 SECONDS_PER_MINUTE = 60,
00023 SECONDS_PER_HOUR = MINUTES_PER_HOUR * SECONDS_PER_MINUTE,
00024 SECONDS_PER_DAY = SECONDS_PER_HOUR * HOURS_PER_DAY,
00025 SECONDS_PER_WEEK = DAYS_PER_WEEK * SECONDS_PER_DAY
00026 };
00027
00028
00029 Duration::Duration(int seconds)
00030 {
00031 if (seconds > 0)
00032 {
00033 secs = seconds;
00034 }
00035 else
00036 {
00037 throw tools::InvalidDataException("Duration cannot be zero or negative.");
00038 }
00039 }
00040
00041 Duration::Duration(int weeks, int days, int hours, int minutes, int seconds)
00042 {
00043 QStringList errorList;
00044 if (!(weeks < INT_MAX / SECONDS_PER_WEEK))
00045 errorList << "weeks";
00046 if (!(days >= 0 && days < DAYS_PER_WEEK))
00047 errorList << "days";
00048 if (!(hours >= 0 && hours < HOURS_PER_DAY))
00049 errorList << "hours";
00050 if (!(minutes >= 0 && minutes < MINUTES_PER_HOUR))
00051 errorList << "minutes";
00052 if (!(seconds >= 0 && seconds < SECONDS_PER_MINUTE))
00053 errorList << "seconds";
00054
00055 if (errorList.isEmpty())
00056 {
00057 secs = seconds +
00058 minutes * SECONDS_PER_MINUTE +
00059 hours * SECONDS_PER_HOUR +
00060 days * SECONDS_PER_DAY +
00061 weeks * SECONDS_PER_WEEK;
00062
00063 if (secs <= 0)
00064 throw tools::InvalidDataException("Duration cannot be zero or negative.");
00065 }
00066 else
00067 {
00068 QString message = "The following values are invalid: ";
00069 throw tools::InvalidDataException(message + errorList.join(", ") + ".");
00070 }
00071 }
00072
00073 int Duration::weeks() const
00074 {
00075 return secs / SECONDS_PER_WEEK;
00076 }
00077
00078 int Duration::days() const
00079 {
00080 return (secs - weeks() * SECONDS_PER_WEEK) / SECONDS_PER_DAY;
00081 }
00082
00083 int Duration::hours() const
00084 {
00085 return (secs - weeks() * SECONDS_PER_WEEK - days() * SECONDS_PER_DAY) /
00086 SECONDS_PER_HOUR;
00087 }
00088
00089 int Duration::minutes() const
00090 {
00091 return (secs - weeks() * SECONDS_PER_WEEK - days() * SECONDS_PER_DAY -
00092 hours() * SECONDS_PER_HOUR) / SECONDS_PER_MINUTE;
00093 }
00094
00095 int Duration::seconds() const
00096 {
00097 return secs % SECONDS_PER_MINUTE;
00098 }
00099
00100 int Duration::totalSeconds() const
00101 {
00102 return secs;
00103 }
00104
00105 QString Duration::toString() const
00106 {
00107 QStringList list;
00108
00109 if (weeks() != 0)
00110 list << QString("%1 weeks").arg(weeks());
00111 if (this->days() != 0)
00112 list << QString("%1 days").arg(days());
00113 if (this->hours() != 0)
00114 list << QString("%1 hours").arg(hours());
00115 if (this->minutes() != 0)
00116 list << QString("%1 minutes").arg(minutes());
00117 if (list.isEmpty() || seconds() != 0)
00118 list << QString("%1 seconds").arg(seconds());
00119
00120 return list.join(", ");
00121 }
00122
00123 bool Duration::operator==(const Duration& other) const
00124 {
00125 return secs == other.secs;
00126 }
00127
00128 bool Duration::operator<(const Duration& other) const
00129 {
00130 return secs < other.secs;
00131 }
00132
00133 bool Duration::operator>(const Duration& other) const
00134 {
00135 return secs > other.secs;
00136 }
00137
00138 }
00139
00140 QDateTime operator+(const QDateTime& left, const domain::Duration& right)
00141 {
00142 return left.addSecs(right.totalSeconds());
00143 }