00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kptduration.h"
00022 #include "kptdatetime.h"
00023
00024 #include <kglobal.h>
00025 #include <klocale.h>
00026 #include <kdebug.h>
00027 #include <QRegExp>
00028
00029 namespace KPlato
00030 {
00031
00032
00033 const Duration Duration::zeroDuration( 0, 0, 0 );
00034
00035 Duration::Duration() {
00036 m_ms = 0;
00037 }
00038
00039 Duration::Duration(const Duration &d) {
00040 m_ms = d.m_ms;
00041 }
00042
00043 Duration::Duration(unsigned d, unsigned h, unsigned m, unsigned s, unsigned ms) {
00044 m_ms = ms;
00045 m_ms += static_cast<qint64>(s) * 1000;
00046 m_ms += static_cast<qint64>(m) * 60 * 1000;
00047 m_ms += static_cast<qint64>(h) * 60 * 60 * 1000;
00048 m_ms += static_cast<qint64>(d) * 24 * 60 * 60 * 1000;
00049 }
00050
00051 Duration::Duration(qint64 seconds) {
00052 m_ms = seconds * 1000;
00053 }
00054
00055 Duration::~Duration() {
00056 }
00057
00058 void Duration::add(const Duration &delta) {
00059 m_ms += delta.m_ms;
00060 }
00061
00062 void Duration::add(qint64 delta) {
00063 qint64 tmp = m_ms + delta;
00064 if (tmp < 0) {
00065 kDebug()<<k_funcinfo<<"Underflow"<<(long int)delta<<" from "<<this->toString()<<endl;
00066 m_ms = 0;
00067 return;
00068 }
00069 m_ms = tmp;
00070 }
00071
00072 void Duration::subtract(const Duration &delta) {
00073 if (m_ms < delta.m_ms) {
00074 kDebug()<<k_funcinfo<<"Underflow"<<delta.toString()<<" from "<<this->toString()<<endl;
00075 m_ms = 0;
00076 return;
00077 }
00078 m_ms -= delta.m_ms;
00079 }
00080
00081 Duration Duration::operator*(int unit) const {
00082 Duration dur(*this);
00083 if (unit < 0) {
00084 kDebug()<<k_funcinfo<<"Underflow"<<unit<<" from "<<this->toString()<<endl;
00085 }
00086 else {
00087 dur.m_ms = m_ms * unit;
00088 }
00089 return dur;
00090 }
00091
00092 Duration Duration::operator/(int unit) const {
00093 Duration dur(*this);
00094 if (unit <= 0) {
00095 kDebug()<<k_funcinfo<<"Underflow"<<unit<<" from "<<this->toString()<<endl;
00096 }
00097 else {
00098 dur.m_ms = m_ms / unit;
00099 }
00100 return dur;
00101 }
00102
00103 Duration Duration::operator*(const double value) const {
00104 Duration dur(*this);
00105 dur.m_ms = QABS(m_ms * (qint64)value);
00106 return dur;
00107 }
00108
00109 double Duration::operator/(const Duration &d) const {
00110 if (d == zeroDuration) {
00111 kDebug()<<k_funcinfo<<"Devide by zero: "<<this->toString()<<endl;
00112 return 0.0;
00113 }
00114 return (double)(m_ms) / (double)(d.m_ms);
00115 }
00116
00117 QString Duration::toString(Format format) const {
00118 qint64 ms;
00119 double days;
00120 unsigned hours;
00121 unsigned minutes;
00122 unsigned seconds;
00123 double f;
00124 QString result;
00125
00126 switch (format) {
00127 case Format_Hour:
00128 ms = m_ms;
00129 hours = ms / (1000 * 60 * 60);
00130 ms -= (qint64)hours * (1000 * 60 * 60);
00131 minutes = ms / (1000 * 60);
00132 result = QString("%1h%2m").arg(hours).arg(minutes);
00133 break;
00134 case Format_Day:
00135 days = m_ms / (1000 * 60 * 60 * 24.0);
00136 result = QString("%1d").arg(QString::number(days, 'f', 4));
00137 break;
00138 case Format_DayTime:
00139 ms = m_ms;
00140 days = m_ms / (1000 * 60 * 60 * 24);
00141 ms -= (qint64)days * (1000 * 60 * 60 * 24);
00142 hours = ms / (1000 * 60 * 60);
00143 ms -= (qint64)hours * (1000 * 60 * 60);
00144 minutes = ms / (1000 * 60);
00145 ms -= minutes * (1000 * 60);
00146 seconds = ms / (1000);
00147 ms -= seconds * (1000);
00148 result.sprintf("%u %02u:%02u:%02u.%u", (unsigned)days, hours, minutes, seconds, (unsigned)ms);
00149 break;
00150 case Format_HourFraction:
00151 result = KGlobal::locale()->formatNumber(toDouble(Unit_h), 2);
00152 break;
00153
00154 case Format_i18nHour:
00155 ms = m_ms;
00156 hours = ms / (1000 * 60 * 60);
00157 ms -= (qint64)hours * (1000 * 60 * 60);
00158 minutes = ms / (1000 * 60);
00159 result = i18nc("<hours>h:<minutes>m", "%1h:%2m", hours, minutes);
00160 break;
00161 case Format_i18nDay:
00162 result = KGlobal::locale()->formatNumber(toDouble(Unit_d), 2);
00163 break;
00164 case Format_i18nDayTime:
00165 ms = m_ms;
00166 days = m_ms / (1000 * 60 * 60 * 24);
00167 ms -= (qint64)days * (1000 * 60 * 60 * 24);
00168 hours = ms / (1000 * 60 * 60);
00169 ms -= (qint64)hours * (1000 * 60 * 60);
00170 minutes = ms / (1000 * 60);
00171 ms -= minutes * (1000 * 60);
00172 seconds = ms / (1000);
00173 ms -= seconds * (1000);
00174 if (days == 0) {
00175 result = toString(Format_i18nHour);
00176 } else {
00177 result = i18nc("<days>d <hours>h:<minutes>m", "%1d %2h:%3m", days, hours, minutes);
00178 }
00179 break;
00180 case Format_i18nHourFraction:
00181 result = KGlobal::locale()->formatNumber(toDouble(Unit_h), 2);
00182 break;
00183 default:
00184 kFatal()<<k_funcinfo<<"Unknown format"<<endl;
00185 break;
00186 }
00187 return result;
00188 }
00189
00190 Duration::Duration Duration::fromString(const QString &s, Format format, bool *ok) {
00191 if (ok) *ok = false;
00192 QRegExp matcher;
00193 Duration tmp;
00194 switch (format) {
00195 case Format_Hour: {
00196 matcher.setPattern("^(\\d*)h(\\d*)m$" );
00197 int pos = matcher.search(s);
00198 if (pos > -1) {
00199 tmp.addHours(matcher.cap(1).toUInt());
00200 tmp.addMinutes(matcher.cap(2).toUInt());
00201 if (ok) *ok = true;
00202 }
00203 break;
00204 }
00205 case Format_DayTime: {
00206 matcher.setPattern("^(\\d*) (\\d*):(\\d*):(\\d*)\\.(\\d*)$" );
00207 int pos = matcher.search(s);
00208 if (pos > -1) {
00209 tmp.addDays(matcher.cap(1).toUInt());
00210 tmp.addHours(matcher.cap(2).toUInt());
00211 tmp.addMinutes(matcher.cap(3).toUInt());
00212 tmp.addSeconds(matcher.cap(4).toUInt());
00213 tmp.addMilliseconds(matcher.cap(5).toUInt());
00214 if (ok) *ok = true;
00215 }
00216 break;
00217 }
00218 case Format_HourFraction: {
00219
00220 bool res;
00221 double f = KGlobal::locale()->readNumber(s, &res);
00222 if (ok) *ok = res;
00223 if (res) {
00224 return Duration((qint64)(f*3600.0));
00225 }
00226 break;
00227 }
00228 default:
00229 kFatal()<<k_funcinfo<<"Unknown format"<<endl;
00230 break;
00231 }
00232 return tmp;
00233 }
00234
00235 void Duration::get(unsigned *days, unsigned *hours, unsigned *minutes, unsigned *seconds, unsigned *milliseconds) const {
00236 qint64 ms;
00237 qint64 tmp;
00238
00239 ms = m_ms;
00240 tmp = ms / (1000 * 60 * 60 * 24);
00241 *days = tmp;
00242 ms -= tmp * (1000 * 60 * 60 * 24);
00243 tmp = ms / (1000 * 60 * 60);
00244 *hours = tmp;
00245 ms -= tmp * (1000 * 60 * 60);
00246 tmp = ms / (1000 * 60);
00247 *minutes = tmp;
00248 ms -= tmp * (1000 * 60);
00249 tmp = ms / (1000);
00250 if (seconds)
00251 *seconds = tmp;
00252 ms -= tmp * (1000);
00253 if (milliseconds)
00254 *milliseconds = ms;
00255 }
00256
00257 }