Passed
Push — master ( 289f9d...bae7fb )
by Sebastian
04:42
created

ConvertHelper_DateInterval::toHours()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * File containing the {@see \AppUtils\ConvertHelper_DateInterval} class.
4
 * 
5
 * @package Application Utils
6
 * @subpackage ConvertHelper
7
 * @see \AppUtils\ConvertHelper_DateInterval
8
 */
9
10
declare(strict_types=1);
11
12
namespace AppUtils;
13
14
use DateInterval;
15
use DateTime;
16
use Exception;
17
18
/**
19
 * DateInterval wrapper, that makes it much easier to
20
 * work with intervals. The methods are typed, so no
21
 * conversions are necessary. A number of utility methods
22
 * also help.
23
 * 
24
 * Automatically fixes the issue of date interval properties
25
 * not being populated entirely when it is created using
26
 * a format string.
27
 * 
28
 * @see \AppUtils\parseInterval()
29
 *@subpackage ConvertHelper
30
 * @author Sebastian Mordziol <[email protected]>
31
 * @package Application Utils
32
 */
33
class ConvertHelper_DateInterval
34
{
35
    const ERROR_CANNOT_GET_DATE_DIFF = 43601;
36
    
37
    const TOKEN_SECONDS = 's';
38
    const TOKEN_MINUTES = 'i';
39
    const TOKEN_HOURS = 'h';
40
    const TOKEN_DAYS = 'd';
41
    const TOKEN_MONTHS = 'm';
42
    const TOKEN_YEARS = 'y';
43
    
44
   /**
45
    * @var DateInterval
46
    */
47
    protected $interval;
48
    
49
   /**
50
    * @var int
51
    */
52
    protected $seconds;
53
54
    /**
55
     * @param int $seconds
56
     *
57
     * @throws ConvertHelper_Exception
58
     * @throws Exception
59
     * @see ConvertHelper_DateInterval::ERROR_CANNOT_GET_DATE_DIFF
60
     */
61
    protected function __construct(int $seconds)
62
    {
63
        $this->seconds = $seconds;
64
        
65
        $d1 = new DateTime();
66
        $d2 = new DateTime();
67
        $d2->add(new DateInterval('PT'.$this->seconds.'S'));
68
        
69
        $interval = $d2->diff($d1);
70
        
71
        if(!$interval instanceof DateInterval)
0 ignored issues
show
introduced by
$interval is always a sub-type of DateInterval.
Loading history...
72
        {
73
            throw new ConvertHelper_Exception(
74
                'Cannot create interval',
75
                sprintf('Getting the date diff failed to retrieve the interval for [%s] seconds.', $this->seconds),
76
                self::ERROR_CANNOT_GET_DATE_DIFF
77
            );
78
        }
79
        
80
        $this->interval = $interval;
81
    }
82
83
    /**
84
     * Creates the interval from a specific amount of seconds.
85
     *
86
     * @param int $seconds
87
     * @return ConvertHelper_DateInterval
88
     * @throws ConvertHelper_Exception
89
     */
90
    public static function fromSeconds(int $seconds)
91
    {
92
        return new ConvertHelper_DateInterval($seconds);
93
    }
94
    
95
   /**
96
    * Creates the interval from an existing regular interval instance.
97
    * 
98
    * @param DateInterval $interval
99
    * @return ConvertHelper_DateInterval
100
    */
101
    public static function fromInterval(DateInterval $interval)
102
    {
103
        return self::fromSeconds(ConvertHelper::interval2seconds($interval));
104
    }
105
    
106
   /**
107
    * Retrieves the PHP native date interval.
108
    * 
109
    * @return DateInterval
110
    */
111
    public function getInterval() : DateInterval
112
    {
113
        return $this->interval;
114
    }
115
    
116
    public function getSeconds() : int
117
    {
118
        return $this->getToken(self::TOKEN_SECONDS);
119
    }
120
    
121
    public function getHours() : int
122
    {
123
        return $this->getToken(self::TOKEN_HOURS);
124
    }
125
    
126
    public function getMinutes() : int
127
    {
128
        return $this->getToken(self::TOKEN_MINUTES);
129
    }
130
    
131
    public function getDays() : int
132
    {
133
        return $this->getToken(self::TOKEN_DAYS);
134
    }
135
    
136
    public function getMonths() : int
137
    {
138
        return $this->getToken(self::TOKEN_MONTHS);
139
    }
140
    
141
    public function getYears() : int
142
    {
143
        return $this->getToken(self::TOKEN_YEARS);
144
    }
145
    
146
   /**
147
    * Retrieves a specific time token, e.g. "h" (for hours).
148
    * Using the constants to specifiy the tokens is recommended.
149
    * 
150
    * @param string $token
151
    * @return int
152
    * 
153
    * @see ConvertHelper_DateInterval::TOKEN_SECONDS
154
    * @see ConvertHelper_DateInterval::TOKEN_MINUTES
155
    * @see ConvertHelper_DateInterval::TOKEN_HOURS
156
    * @see ConvertHelper_DateInterval::TOKEN_DAYS
157
    * @see ConvertHelper_DateInterval::TOKEN_MONTHS
158
    * @see ConvertHelper_DateInterval::TOKEN_YEARS
159
    */
160
    public function getToken(string $token) : int
161
    {
162
        return (int)$this->interval->$token;
163
    }
164
    
165
   /**
166
    * The total amount of seconds in the interval (including
167
    * everything, from seconds to days, months, years...).
168
    * 
169
    * @return int
170
    */
171
    public function getTotalSeconds() : int
172
    {
173
        return $this->seconds;
174
    }
175
176
    /**
177
     * Calculates the total amount of days / hours / minutes or seconds
178
     * of a date interval object (depending on the specified units), and
179
     * returns the total amount.
180
     *
181
     * @param DateInterval $interval
182
     * @param string $unit What total value to calculate.
183
     * @return integer
184
     *
185
     * @see ConvertHelper::INTERVAL_SECONDS
186
     * @see ConvertHelper::INTERVAL_MINUTES
187
     * @see ConvertHelper::INTERVAL_HOURS
188
     * @see ConvertHelper::INTERVAL_DAYS
189
     */
190
    public static function toTotal(DateInterval $interval, string $unit=ConvertHelper::INTERVAL_SECONDS) : int
191
    {
192
        $total = (int)$interval->format('%a');
193
        if ($unit == ConvertHelper::INTERVAL_DAYS) {
194
            return $total;
195
        }
196
197
        $total = ($total * 24) + ((int)$interval->h );
198
        if ($unit == ConvertHelper::INTERVAL_HOURS) {
199
            return $total;
200
        }
201
202
        $total = ($total * 60) + ((int)$interval->i );
203
        if ($unit == ConvertHelper::INTERVAL_MINUTES) {
204
            return $total;
205
        }
206
207
        $total = ($total * 60) + ((int)$interval->s );
208
        if ($unit == ConvertHelper::INTERVAL_SECONDS) {
209
            return $total;
210
        }
211
212
        return 0;
213
    }
214
215
    /**
216
     * Converts an interval to its total amount of days.
217
     * @param DateInterval $interval
218
     * @return int
219
     */
220
    public static function toDays(DateInterval $interval) : int
221
    {
222
        return self::toTotal($interval, ConvertHelper::INTERVAL_DAYS);
223
    }
224
225
    /**
226
     * Converts an interval to its total amount of hours.
227
     * @param DateInterval $interval
228
     * @return int
229
     */
230
    public static function toHours(DateInterval $interval) : int
231
    {
232
        return self::toTotal($interval, ConvertHelper::INTERVAL_HOURS);
233
    }
234
235
    /**
236
     * Converts an interval to its total amount of minutes.
237
     * @param DateInterval $interval
238
     * @return int
239
     */
240
    public static function toMinutes(DateInterval $interval) : int
241
    {
242
        return self::toTotal($interval, ConvertHelper::INTERVAL_MINUTES);
243
    }
244
245
    /**
246
     * Converts an interval to its total amount of seconds.
247
     * @param DateInterval $interval
248
     * @return int
249
     */
250
    public static function toSeconds(DateInterval $interval) : int
251
    {
252
        return self::toTotal($interval, ConvertHelper::INTERVAL_SECONDS);
253
    }
254
}
255