Completed
Push — master ( c7b167...faaa80 )
by Wanderson
02:08
created

Date   B

Complexity

Total Complexity 52

Size/Duplication

Total Lines 308
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
wmc 52
lcom 1
cbo 0
dl 0
loc 308
rs 7.9487
c 0
b 0
f 0

33 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 2
A getYear() 0 3 1
A getMonth() 0 3 1
A getDay() 0 3 1
A getHour() 0 3 1
A getMinute() 0 3 1
A getSecond() 0 3 1
A getZeroDate() 0 3 1
A setYear() 0 3 1
A setMonth() 0 3 1
A setDay() 0 3 1
A setHour() 0 3 1
A setMinute() 0 3 1
A setSecond() 0 3 1
A getMonthName() 0 3 1
A getMonthAbbre() 0 3 1
A initDateTime() 0 8 2
A initDate() 0 15 2
A initTime() 0 7 1
A toHtml() 0 3 1
A toSql() 0 7 2
A __toString() 0 3 1
B toHumanFormat() 0 15 5
A format() 0 9 4
A isValid() 0 6 4
A isValidBirthday() 0 9 3
A sumDays() 0 3 1
A sumMonths() 0 3 1
A sumYears() 0 3 1
A sumTime() 0 6 1
A secondsDiff() 0 7 1
A daysDiff() 0 4 1
A getHumanUnits() 0 13 4

How to fix   Complexity   

Complex Class

Complex classes like Date often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Date, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Win\Calendar;
4
5
/**
6
 * Data e Hora
7
 */
8
class Date {
9
10
	private $year = '00';
11
	private $month = '00';
12
	private $day = '00';
13
	private $hour = '00';
14
	private $minute = '00';
15
	private $second = '00';
16
	static $monthNames = array(0 => "00", "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro");
17
	static $zeroDate = '0000-00-00 00:00:00';
18
19
	const UNITS = array(
20
		31536000 => ['ano', 'anos'],
21
		2592000 => ['mês', 'mêses'],
22
		604800 => ['semana', 'semanas'],
23
		86400 => ['dia', 'dias'],
24
		3600 => ['hora', 'horas'],
25
		60 => ['minuto', 'minutos'],
26
		1 => ['segundo', 'segundos']
27
	);
28
29
	/**
30
	 * Inicia a data/hora de acordo com a string informada
31
	 * @param string
32
	 * @example new Data('01/01/1980 18:00');
33
	 */
34
	public function __construct($stringDate = null) {
35
		if ($stringDate != static::$zeroDate):
0 ignored issues
show
Bug introduced by
Since $zeroDate is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $zeroDate to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
36
			$this->initDateTime($stringDate);
37
		endif;
38
	}
39
40
	/* METODOS DE ACESSO */
41
42
	public function getYear() {
43
		return $this->year;
44
	}
45
46
	public function getMonth() {
47
		return $this->month;
48
	}
49
50
	public function getDay() {
51
		return $this->day;
52
	}
53
54
	public function getHour() {
55
		return $this->hour;
56
	}
57
58
	public function getMinute() {
59
		return $this->minute;
60
	}
61
62
	public function getSecond() {
63
		return $this->second;
64
	}
65
66
	public static function getZeroDate() {
67
		return self::$zeroDate;
68
	}
69
70
	public function setYear($year) {
71
		$this->year = $year;
72
	}
73
74
	public function setMonth($month) {
75
		$this->month = $month;
76
	}
77
78
	public function setDay($day) {
79
		$this->day = $day;
80
	}
81
82
	public function setHour($hour) {
83
		$this->hour = $hour;
84
	}
85
86
	public function setMinute($minute) {
87
		$this->minute = $minute;
88
	}
89
90
	public function setSecond($second) {
91
		$this->second = $second;
92
	}
93
94
	public function getMonthName() {
95
		return self::$monthNames[(int) $this->month];
96
	}
97
98
	public function getMonthAbbre() {
99
		return strtoupper(substr($this->getMonthName(), 0, 3));
100
	}
101
102
	/**
103
	 * Inicia o objeto de acordo com a data informada
104
	 * @param string $stringDate
105
	 */
106
	public function initDateTime($stringDate = null) {
107
		if (is_null($stringDate)):
108
			$stringDate = date("Y-m-d H:i:s");
109
		endif;
110
		$arrayDate = explode(' ', strEscape(strStrip($stringDate)) . ' ');
111
		$this->initDate($arrayDate[0]);
112
		$this->initTime($arrayDate[1]);
113
	}
114
115
	/**
116
	 * Inicia o Dia/Mes/Ano
117
	 * @param string $stringDateOnly
118
	 */
119
	private function initDate($stringDateOnly) {
120
		if (strpos($stringDateOnly, '/') > 0) {
121
			/* FORMATO: DD/MM/AAAA */
122
			$d1 = explode('/', $stringDateOnly . '///');
123
			$this->year = strLengthFormat((int) $d1[2], 4);
124
			$this->month = strLengthFormat((int) $d1[1], 2);
125
			$this->day = strLengthFormat((int) $d1[0], 2);
126
		} else {
127
			/* FORMATO: AAAA-MM-DD */
128
			$d1 = explode('-', $stringDateOnly . '---');
129
			$this->year = strLengthFormat((int) $d1[0], 4);
130
			$this->month = strLengthFormat((int) $d1[1], 2);
131
			$this->day = strLengthFormat((int) $d1[2], 2);
132
		}
133
	}
134
135
	/**
136
	 * Inicia a Hora:Minuto:Segundo
137
	 * @param string $stringTimeOnly
138
	 */
139
	private function initTime($stringTimeOnly) {
140
		/* FORMATO: HH:MM:SS */
141
		$d2 = explode(':', $stringTimeOnly . ':::');
142
		$this->hour = strLengthFormat((int) $d2[0], 2);
143
		$this->minute = strLengthFormat((int) $d2[1], 2);
144
		$this->second = strLengthFormat((int) $d2[2], 2);
145
	}
146
147
	/**
148
	 * Retorna a data no padrao HTML BRASILEIRO: "Dia/Mês/Ano Hora:Minuto:Segundo"
149
	 * @return string
150
	 */
151
	public function toHtml() {
152
		return $this->format('d/m/y h:i:s');
153
	}
154
155
	/**
156
	 * Retorna a data no padrao SQL DATETIME: "Ano-Mês-Dia Hora:Minuto:Segundo"
157
	 * @return string
158
	 */
159
	public function toSql() {
160
		if ($this->year == 0) {
161
			return static::$zeroDate;
0 ignored issues
show
Bug introduced by
Since $zeroDate is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $zeroDate to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
162
		} else {
163
			return $this->format('y-m-d h:i:s');
164
		}
165
	}
166
167
	/**
168
	 * Retorna a data com o formato padrão 'd/m/y'
169
	 * @return string 
170
	 */
171
	public function __toString() {
172
		return $this->format('d/m/y');
173
	}
174
175
	/**
176
	 * Retorna a data no formato humano
177
	 * @return string (ex: 4 horas atrás), (ex: daqui a 5 dias)
178
	 */
179
	public function toHumanFormat() {
180
		$time = time() - strtotime($this->format('d-m-y h:i:s'));
181
		if ($this->toSql() == static::$zeroDate) {
0 ignored issues
show
Bug introduced by
Since $zeroDate is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $zeroDate to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
182
			return 'indisponível';
183
		}
184
		if ($time == 0) {
185
			return 'agora mesmo';
186
		}
187
		if ($time > 0) {
188
			return $this->getHumanUnits($time) . ' atrás';
189
		}
190
		if ($time < 0) {
191
			return 'daqui a ' . $this->getHumanUnits($time * (-1));
192
		}
193
	}
194
195
	/**
196
	 * Retorna a data de acordo com o formato escolhido. Ex: [d/m/y h:i:s] , [y-m-d] , [y-m-d h:i:s] , etc
197
	 * @param string $format
198
	 * @return string Data no formato desejado
199
	 */
200
	public function format($format = 'd/m/y') {
201
		$date = '';
202
		if ($this->year != 0 and $this->month != 0 and $this->day != 0) {
203
			$a = array('d', 'm', 'y', 'h', 'i', 's');
204
			$b = array($this->day, $this->month, $this->year, $this->hour, $this->minute, $this->second);
205
			$date = str_replace($a, $b, strtolower($format));
206
		}
207
		return $date;
208
	}
209
210
	/**
211
	 * Valida a data
212
	 * @return boolean retorna True se data é valida
213
	 */
214
	public function isValid() {
215
		if ($this->second >= 60 or $this->minute >= 60 or $this->hour >= 24) {
216
			return false;
217
		}
218
		return checkdate($this->getMonth(), $this->getDay(), $this->getYear());
219
	}
220
221
	/**
222
	 * Retorna true se é uma data de nascimento válida
223
	 * @return boolean
224
	 */
225
	public function isValidBirthday() {
226
		$MIN_AGE = 0;
227
		$MAX_AGE = 200;
228
		$age = date('Y') - $this->getYear();
229
		if ($age < $MIN_AGE or $age > $MAX_AGE) {
230
			return false;
231
		}
232
		return $this->isValid();
233
	}
234
235
	/**
236
	 * Soma a quantidade de dias informada
237
	 * @param int $days
238
	 */
239
	public function sumDays($days) {
240
		$this->sumTime($days, 'days');
241
	}
242
243
	/**
244
	 * Soma a quantidade de meses informada
245
	 * @param int $months
246
	 */
247
	public function sumMonths($months) {
248
		$this->sumTime($months, 'months');
249
	}
250
251
	/**
252
	 * Soma a quantidade de anos informada
253
	 * @param int $years
254
	 */
255
	public function sumYears($years) {
256
		$this->sumTime($years, 'years');
257
	}
258
259
	/**
260
	 * Soma a quantidade de tempo informada
261
	 * @param int $time Unidade
262
	 * @param string $tipo [days,month,years]
263
	 */
264
	public function sumTime($time, $tipo = 'days') {
265
		$newTime = strtotime('+' . $time . ' ' . $tipo, strtotime($this->format('d-m-y')));
266
		$this->day = date('d', $newTime);
267
		$this->month = date('m', $newTime);
268
		$this->year = date('Y', $newTime);
269
	}
270
271
	/**
272
	 * Retorna a diferença em Segundos entre duas datas
273
	 * @param Data $date1
274
	 * @param Data $date2
275
	 * @return float Diferença em Segundos
276
	 */
277
	public static function secondsDiff(Data $date1, Data $date2) {
278
		$mkTime1 = mktime($date1->getHour(), $date1->getMinute(), $date1->getSecond(), $date1->getMonth(), $date1->getDay(), $date1->getYear());
279
		$mkTime2 = mktime($date2->getHour(), $date2->getMinute(), $date2->getSecond(), $date2->getMonth(), $date2->getDay(), $date2->getYear());
280
		$mkTimeDiff = $mkTime2 - $mkTime1;
281
282
		return $mkTimeDiff;
283
	}
284
285
	/**
286
	 * Retorna a diferença em Dias entre duas datas
287
	 * @param Data $date1
288
	 * @param Data $date2
289
	 * @return float Diferença em Dias
290
	 */
291
	public static function daysDiff(Data $date1, Data $date2) {
292
		$diffInDay = ((self::secondsDiff($date1, $date2)) / 86400);
293
		return $diffInDay;
294
	}
295
296
	/**
297
	 * Retorna a data em unidade de tempo Humana
298
	 * @param string $dateInSeconds
299
	 * @return string
300
	 */
301
	protected function getHumanUnits($dateInSeconds) {
302
		foreach (static::UNITS as $unit => $measure) {
303
			if ($dateInSeconds < $unit) {
304
				continue;
305
			}
306
			$total = floor($dateInSeconds / $unit);
307
			if ($total > 1) {
308
				return $total . ' ' . $measure[1];
309
			} else {
310
				return $total . ' ' . $measure[0];
311
			}
312
		}
313
	}
314
315
}
316