Passed
Push — master ( f1ca2b...4512a5 )
by Sebastian
04:21
created

ConvertHelper_TimeConverter   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 11
eloc 55
c 1
b 0
f 0
dl 0
loc 127
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A toString() 0 23 4
A initUnits() 0 37 2
A resolveTokens() 0 31 4
1
<?php
2
/**
3
 * File containing the {@see AppUtils\ConvertHelper_TimeConverter} class.
4
 *
5
 * @package Application Utils
6
 * @subpackage ConvertHelper
7
 * @see AppUtils\ConvertHelper_TimeConverter
8
 */
9
10
declare(strict_types=1);
11
12
namespace AppUtils;
13
14
/**
15
 * Converts seconds to a human readable duration string,
16
 * like "5 minutes and 20 seconds".
17
 *
18
 * @package Application Utils
19
 * @subpackage ConvertHelper
20
 * @author Sebastian Mordziol <[email protected]>
21
 *
22
 * @see ConvertHelper::time2string()
23
 */
24
class ConvertHelper_TimeConverter
25
{
26
   /**
27
    * @var float
28
    */
29
    private $seconds;
30
31
   /**
32
    * @var array<int,array<string,string|int>>
33
    */
34
    private static $units;
35
    
36
   /**
37
    * @param float $seconds
38
    */
39
    public function __construct($seconds)
40
    {
41
        $this->seconds = $seconds;   
42
        
43
        $this->initUnits();
44
    }
45
    
46
   /**
47
    * Creates the list of units once per request as needed.
48
    */
49
    private function initUnits() : void
50
    {
51
        if(isset(self::$units))
52
        {
53
            return;
54
        }
55
        
56
        self::$units = array(
57
            array(
58
                'value' => 31 * 7 * 24 * 3600,
59
                'singular' => t('month'),
60
                'plural' => t('months')
61
            ),
62
            array(
63
                'value' => 7 * 24 * 3600,
64
                'singular' => t('week'),
65
                'plural' => t('weeks')
66
            ),
67
            array(
68
                'value' => 24 * 3600,
69
                'singular' => t('day'),
70
                'plural' => t('days')
71
            ),
72
            array(
73
                'value' => 3600,
74
                'singular' => t('hour'),
75
                'plural' => t('hours')
76
            ),
77
            array(
78
                'value' => 60,
79
                'singular' => t('minute'),
80
                'plural' => t('minutes')
81
            ),
82
            array(
83
                'value' => 1,
84
                'singular' => t('second'),
85
                'plural' => t('seconds')
86
            )
87
        );
88
    }
89
    
90
    public function toString() : string
91
    {
92
        // specifically handle zero
93
        if($this->seconds <= 0) 
94
        {
95
            return '0 ' . t('seconds');
96
        }
97
        
98
        if($this->seconds < 1) 
99
        {
100
            return t('less than a second');
101
        }
102
        
103
        $tokens = $this->resolveTokens();
104
105
        $last = array_pop($tokens);
106
        
107
        if(empty($tokens)) 
108
        {
109
            return $last;
110
        }
111
        
112
        return implode(', ', $tokens) . ' ' . t('and') . ' ' . $last;
113
    }
114
    
115
   /**
116
    * Resolves the list of converted units.
117
    * 
118
    * @return string[]
119
    */
120
    private function resolveTokens() : array
121
    {
122
        $seconds = $this->seconds;
123
        $tokens = array();
124
        
125
        foreach(self::$units as $def)
126
        {
127
            $unitValue = intval($seconds / $def['value']);
128
            
129
            if($unitValue <= 0)
130
            {
131
                continue;
132
            }
133
            
134
            $item = strval($unitValue) . ' ';
135
            
136
            if(abs($unitValue) > 1)
137
            {
138
                $item .= $def['plural'];
139
            }
140
            else
141
            {
142
                $item .= $def['singular'];
143
            }
144
            
145
            $tokens[] = $item;
146
            
147
            $seconds -= $unitValue * $def['value'];
148
        }
149
        
150
        return $tokens;
151
    }
152
}
153