summaryrefslogtreecommitdiffstats
path: root/kplato/kptduration.h
blob: 116d0660da95906af85312bd882bbad160bf41c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* This file is part of the KDE project
   Copyright (C) 2001 Thomas Zander zander@kde.org
   Copyright (C) 2004 - 2006 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.
*/

#ifndef KPTDURATION_H
#define KPTDURATION_H

#include <qglobal.h>
#include <qstring.h>

namespace KPlato
{

/**
 * The duration class can be used to store a timespan in a convenient format.
 * The timespan can be in length in many many hours down to miliseconds.
 */
class Duration {
    public:
        /**
         * DayTime  = d hh:mm:ss.sss
         * Day      = d.ddd
         * Hour     = hh:mm
         * HourFraction = h.fraction of an hour
         */
        enum Format { Format_DayTime, Format_Day, Format_Hour, Format_HourFraction, Format_i18nDayTime, Format_i18nDay, Format_i18nHour, Format_i18nHourFraction };

        Duration();
        Duration(const Duration &d);
        Duration(unsigned d, unsigned h, unsigned m, unsigned s=0, unsigned ms=0);
        Duration(Q_INT64 seconds);
        ~Duration();

        /**
         * Adds @param delta to *this. If @param delta > *this, *this is set to zeroDuration.
         */
        void addMilliseconds(Q_INT64 delta)  { add(delta); }

        /**
         * Adds @param delta to *this. If @param delta > *this, *this is set to zeroDuration.
         */
        void addSeconds(Q_INT64 delta) { addMilliseconds(delta * 1000); }

        /**
         * Adds @param delta to *this. If @param delta > *this, *this is set to zeroDuration.
         */
        void addMinutes(Q_INT64 delta) { addSeconds(delta * 60); }

        /**
         * Adds @param delta to *this. If @param delta > *this, *this is set to zeroDuration.
         */
        void addHours(Q_INT64 delta) { addMinutes(delta * 60); }

        /**
         * Adds @param delta to *this. If @param delta > *this, *this is set to zeroDuration.
         */
        void addDays(Q_INT64 delta) { addHours(delta * 24); }

        //FIXME: overflow problem
        Q_INT64 milliseconds() const { return m_ms; }
        Q_INT64 seconds() const { return m_ms / 1000; }
        Q_INT64 minutes() const { return seconds() / 60; }
        unsigned hours() const { return minutes() / 60; }
        unsigned days() const { return hours() / 24; }
        void get(unsigned *days, unsigned *hours, unsigned *minutes, unsigned *seconds=0, unsigned *milliseconds=0) const;

        bool   operator==( const Duration &d ) const { return m_ms == d.m_ms; }
        bool   operator==( Q_INT64 d ) const { return m_ms == d; }
        bool   operator!=( const Duration &d ) const { return m_ms != d.m_ms; }
        bool   operator!=( Q_INT64 d ) const { return m_ms != d; }
        bool   operator<( const Duration &d ) const { return m_ms < d.m_ms; }
        bool   operator<( Q_INT64 d ) const { return m_ms < d; }
        bool   operator<=( const Duration &d ) const { return m_ms <= d.m_ms; }
        bool   operator<=( Q_INT64 d ) const { return m_ms <= d; }
        bool   operator>( const Duration &d ) const { return m_ms > d.m_ms; }
        bool   operator>( Q_INT64 d ) const { return m_ms > d; }
        bool   operator>=( const Duration &d ) const { return m_ms >= d.m_ms; }
        bool   operator>=( Q_INT64 d ) const { return m_ms >= d; }
        Duration &operator=(const Duration &d ) { m_ms = d.m_ms; return *this;}
        Duration operator*(int unit) const; 
        Duration operator*(const double value) const;
        Duration operator/(int unit) const;
        double operator/(const Duration &d) const;
        
        Duration operator+(const Duration &d) const
            {Duration dur(*this); dur.add(d); return dur; }
        Duration &operator+=(const Duration &d) {add(d); return *this; }
        
        Duration operator-(const Duration &d) const
            {Duration dur(*this); dur.subtract(d); return dur; }
        Duration &operator-=(const Duration &d) {subtract(d); return *this; }

        QString toString(Format format = Format_DayTime) const;
        static Duration fromString(const QString &s, Format format = Format_DayTime, bool *ok=0);
        
        //NOTE: These must match fieldnumbers in duration widget!
        enum Unit { Unit_d, Unit_h, Unit_m, Unit_s, Unit_ms };
        double toDouble(Unit u=Unit_ms) const { 
            if (u == Unit_ms) return (double)m_ms;
            else if (u == Unit_s) return (double)m_ms/1000.0;
            else if (u == Unit_m) return (double)m_ms/(1000.0*60.0);
            else if (u == Unit_h) return (double)m_ms/(1000.0*60.0*60.0);
            else if (u == Unit_d) return (double)m_ms/(1000.0*60.0*60.0*24.0);
            return (double)m_ms; 
        }

        /**
         * This is useful for occasions where we need a zero duration.
         */
        static const Duration zeroDuration;

    private:
	/**
	 * Duration in milliseconds. Signed to allow for simple calculations which
	 * might go negative for intermediate results.
	 */
        Q_INT64 m_ms;

        void add(Q_INT64 delta);
        void add(const Duration &delta);

        /**
         * Subtracts @param delta from *this. If @param delta > *this, *this is set to zeroDuration.
         */
        void subtract(const Duration &delta);
};

}  //KPlato namespace

#endif