summaryrefslogtreecommitdiffstats
path: root/kplato/kptduration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kplato/kptduration.cpp')
-rw-r--r--kplato/kptduration.cpp257
1 files changed, 257 insertions, 0 deletions
diff --git a/kplato/kptduration.cpp b/kplato/kptduration.cpp
new file mode 100644
index 00000000..87e0e54a
--- /dev/null
+++ b/kplato/kptduration.cpp
@@ -0,0 +1,257 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Thomas Zander zander@kde.org
+ Copyright (C) 2004, 2005 Dag Andersen <danders@get2net.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "kptduration.h"
+#include "kptdatetime.h"
+
+#include <tdeglobal.h>
+#include <tdelocale.h>
+#include <kdebug.h>
+#include <tqregexp.h>
+
+namespace KPlato
+{
+
+// Set the value of Duration::zeroDuration to zero.
+const Duration Duration::zeroDuration( 0, 0, 0 );
+
+Duration::Duration() {
+ m_ms = 0;
+}
+
+Duration::Duration(const Duration &d) {
+ m_ms = d.m_ms;
+}
+
+Duration::Duration(unsigned d, unsigned h, unsigned m, unsigned s, unsigned ms) {
+ m_ms = ms;
+ m_ms += static_cast<TQ_INT64>(s) * 1000; // cast to avoid potential overflow problem
+ m_ms += static_cast<TQ_INT64>(m) * 60 * 1000;
+ m_ms += static_cast<TQ_INT64>(h) * 60 * 60 * 1000;
+ m_ms += static_cast<TQ_INT64>(d) * 24 * 60 * 60 * 1000;
+}
+
+Duration::Duration(TQ_INT64 seconds) {
+ m_ms = seconds * 1000;
+}
+
+Duration::~Duration() {
+}
+
+void Duration::add(const Duration &delta) {
+ m_ms += delta.m_ms;
+}
+
+void Duration::add(TQ_INT64 delta) {
+ TQ_INT64 tmp = m_ms + delta;
+ if (tmp < 0) {
+ kdDebug()<<k_funcinfo<<"Underflow"<<(long int)delta<<" from "<<this->toString()<<endl;
+ m_ms = 0;
+ return;
+ }
+ m_ms = tmp;
+}
+
+void Duration::subtract(const Duration &delta) {
+ if (m_ms < delta.m_ms) {
+ kdDebug()<<k_funcinfo<<"Underflow"<<delta.toString()<<" from "<<this->toString()<<endl;
+ m_ms = 0;
+ return;
+ }
+ m_ms -= delta.m_ms;
+}
+
+Duration Duration::operator*(int unit) const {
+ Duration dur(*this);
+ if (unit < 0) {
+ kdDebug()<<k_funcinfo<<"Underflow"<<unit<<" from "<<this->toString()<<endl;
+ }
+ else {
+ dur.m_ms = m_ms * unit; //FIXME
+ }
+ return dur;
+}
+
+Duration Duration::operator/(int unit) const {
+ Duration dur(*this);
+ if (unit <= 0) {
+ kdDebug()<<k_funcinfo<<"Underflow"<<unit<<" from "<<this->toString()<<endl;
+ }
+ else {
+ dur.m_ms = m_ms / unit; //FIXME
+ }
+ return dur;
+}
+
+Duration Duration::operator*(const double value) const {
+ Duration dur(*this);
+ dur.m_ms = TQABS(m_ms * (TQ_INT64)value);
+ return dur;
+}
+
+double Duration::operator/(const Duration &d) const {
+ if (d == zeroDuration) {
+ kdDebug()<<k_funcinfo<<"Devide by zero: "<<this->toString()<<endl;
+ return 0.0;
+ }
+ return (double)(m_ms) / (double)(d.m_ms);
+}
+
+TQString Duration::toString(Format format) const {
+ TQ_INT64 ms;
+ double days;
+ unsigned hours;
+ unsigned minutes;
+ unsigned seconds;
+ double f;
+ TQString result;
+
+ switch (format) {
+ case Format_Hour:
+ ms = m_ms;
+ hours = ms / (1000 * 60 * 60);
+ ms -= (TQ_INT64)hours * (1000 * 60 * 60);
+ minutes = ms / (1000 * 60);
+ result = TQString("%1h%2m").arg(hours).arg(minutes);
+ break;
+ case Format_Day:
+ days = m_ms / (1000 * 60 * 60 * 24.0);
+ result = TQString("%1d").arg(TQString::number(days, 'f', 4));
+ break;
+ case Format_DayTime:
+ ms = m_ms;
+ days = m_ms / (1000 * 60 * 60 * 24);
+ ms -= (TQ_INT64)days * (1000 * 60 * 60 * 24);
+ hours = ms / (1000 * 60 * 60);
+ ms -= (TQ_INT64)hours * (1000 * 60 * 60);
+ minutes = ms / (1000 * 60);
+ ms -= minutes * (1000 * 60);
+ seconds = ms / (1000);
+ ms -= seconds * (1000);
+ result.sprintf("%u %02u:%02u:%02u.%u", (unsigned)days, hours, minutes, seconds, (unsigned)ms);
+ break;
+ case Format_HourFraction:
+ result = TDEGlobal::locale()->formatNumber(toDouble(Unit_h), 2);
+ break;
+ // i18n
+ case Format_i18nHour:
+ ms = m_ms;
+ hours = ms / (1000 * 60 * 60);
+ ms -= (TQ_INT64)hours * (1000 * 60 * 60);
+ minutes = ms / (1000 * 60);
+ result = i18n("<hours>h:<minutes>m", "%1h:%2m").arg(hours).arg(minutes);
+ break;
+ case Format_i18nDay:
+ result = TDEGlobal::locale()->formatNumber(toDouble(Unit_d), 2);
+ break;
+ case Format_i18nDayTime:
+ ms = m_ms;
+ days = m_ms / (1000 * 60 * 60 * 24);
+ ms -= (TQ_INT64)days * (1000 * 60 * 60 * 24);
+ hours = ms / (1000 * 60 * 60);
+ ms -= (TQ_INT64)hours * (1000 * 60 * 60);
+ minutes = ms / (1000 * 60);
+ ms -= minutes * (1000 * 60);
+ seconds = ms / (1000);
+ ms -= seconds * (1000);
+ if (days == 0) {
+ result = toString(Format_i18nHour);
+ } else {
+ result = i18n("<days>d <hours>h:<minutes>m", "%1d %2h:%3m").arg(days).arg(hours).arg(minutes);
+ }
+ break;
+ case Format_i18nHourFraction:
+ result = TDEGlobal::locale()->formatNumber(toDouble(Unit_h), 2);
+ break;
+ default:
+ kdFatal()<<k_funcinfo<<"Unknown format"<<endl;
+ break;
+ }
+ return result;
+}
+
+Duration Duration::fromString(const TQString &s, Format format, bool *ok) {
+ if (ok) *ok = false;
+ TQRegExp matcher;
+ Duration tmp;
+ switch (format) {
+ case Format_Hour: {
+ matcher.setPattern("^(\\d*)h(\\d*)m$" );
+ int pos = matcher.search(s);
+ if (pos > -1) {
+ tmp.addHours(matcher.cap(1).toUInt());
+ tmp.addMinutes(matcher.cap(2).toUInt());
+ if (ok) *ok = true;
+ }
+ break;
+ }
+ case Format_DayTime: {
+ matcher.setPattern("^(\\d*) (\\d*):(\\d*):(\\d*)\\.(\\d*)$" );
+ int pos = matcher.search(s);
+ if (pos > -1) {
+ tmp.addDays(matcher.cap(1).toUInt());
+ tmp.addHours(matcher.cap(2).toUInt());
+ tmp.addMinutes(matcher.cap(3).toUInt());
+ tmp.addSeconds(matcher.cap(4).toUInt());
+ tmp.addMilliseconds(matcher.cap(5).toUInt());
+ if (ok) *ok = true;
+ }
+ break;
+ }
+ case Format_HourFraction: {
+ // should be in double format
+ bool res;
+ double f = TDEGlobal::locale()->readNumber(s, &res);
+ if (ok) *ok = res;
+ if (res) {
+ return Duration((TQ_INT64)(f*3600.0));
+ }
+ break;
+ }
+ default:
+ kdFatal()<<k_funcinfo<<"Unknown format"<<endl;
+ break;
+ }
+ return tmp;
+}
+
+void Duration::get(unsigned *days, unsigned *hours, unsigned *minutes, unsigned *seconds, unsigned *milliseconds) const {
+ TQ_INT64 ms;
+ TQ_INT64 tmp;
+
+ ms = m_ms;
+ tmp = ms / (1000 * 60 * 60 * 24);
+ *days = tmp;
+ ms -= tmp * (1000 * 60 * 60 * 24);
+ tmp = ms / (1000 * 60 * 60);
+ *hours = tmp;
+ ms -= tmp * (1000 * 60 * 60);
+ tmp = ms / (1000 * 60);
+ *minutes = tmp;
+ ms -= tmp * (1000 * 60);
+ tmp = ms / (1000);
+ if (seconds)
+ *seconds = tmp;
+ ms -= tmp * (1000);
+ if (milliseconds)
+ *milliseconds = ms;
+}
+
+} //KPlato namespace