Completed
Push — master ( 84a728...c25be8 )
by Blizzz
18:08 queued 03:10
created

DateTimeFormatter::formatTimeSpan()   D

Complexity

Conditions 10
Paths 14

Size

Total Lines 32
Code Lines 23

Duplication

Lines 12
Ratio 37.5 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 23
c 1
b 0
f 0
nc 14
nop 3
dl 12
loc 32
rs 4.8196

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Joas Schilling <[email protected]>
6
 * @author Morris Jobke <[email protected]>
7
 * @author Thomas Müller <[email protected]>
8
 *
9
 * @license AGPL-3.0
10
 *
11
 * This code is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License, version 3,
13
 * as published by the Free Software Foundation.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License, version 3,
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
22
 *
23
 */
24
25
namespace OC;
26
27
class DateTimeFormatter implements \OCP\IDateTimeFormatter {
28
	/** @var \DateTimeZone */
29
	protected $defaultTimeZone;
30
31
	/** @var \OCP\IL10N */
32
	protected $defaultL10N;
33
34
	/**
35
	 * Constructor
36
	 *
37
	 * @param \DateTimeZone $defaultTimeZone Set the timezone for the format
38
	 * @param \OCP\IL10N $defaultL10N Set the language for the format
39
	 */
40
	public function __construct(\DateTimeZone $defaultTimeZone, \OCP\IL10N $defaultL10N) {
41
		$this->defaultTimeZone = $defaultTimeZone;
42
		$this->defaultL10N = $defaultL10N;
43
	}
44
45
	/**
46
	 * Get TimeZone to use
47
	 *
48
	 * @param \DateTimeZone $timeZone	The timezone to use
49
	 * @return \DateTimeZone		The timezone to use, falling back to the current user's timezone
50
	 */
51
	protected function getTimeZone($timeZone = null) {
52
		if ($timeZone === null) {
53
			$timeZone = $this->defaultTimeZone;
54
		}
55
56
		return $timeZone;
57
	}
58
59
	/**
60
	 * Get \OCP\IL10N to use
61
	 *
62
	 * @param \OCP\IL10N $l	The locale to use
63
	 * @return \OCP\IL10N		The locale to use, falling back to the current user's locale
64
	 */
65
	protected function getLocale($l = null) {
66
		if ($l === null) {
67
			$l = $this->defaultL10N;
68
		}
69
70
		return $l;
71
	}
72
73
	/**
74
	 * Generates a DateTime object with the given timestamp and TimeZone
75
	 *
76
	 * @param mixed $timestamp
77
	 * @param \DateTimeZone $timeZone	The timezone to use
78
	 * @return \DateTime
79
	 */
80
	protected function getDateTime($timestamp, \DateTimeZone $timeZone = null) {
81
		if ($timestamp === null) {
82
			return new \DateTime('now', $timeZone);
83
		} else if (!$timestamp instanceof \DateTime) {
84
			$dateTime = new \DateTime('now', $timeZone);
85
			$dateTime->setTimestamp($timestamp);
86
			return $dateTime;
87
		}
88
		if ($timeZone) {
89
			$timestamp->setTimezone($timeZone);
90
		}
91
		return $timestamp;
92
	}
93
94
	/**
95
	 * Formats the date of the given timestamp
96
	 *
97
	 * @param int|\DateTime	$timestamp	Either a Unix timestamp or DateTime object
98
	 * @param string	$format			Either 'full', 'long', 'medium' or 'short'
99
	 * 				full:	e.g. 'EEEE, MMMM d, y'	=> 'Wednesday, August 20, 2014'
100
	 * 				long:	e.g. 'MMMM d, y'		=> 'August 20, 2014'
101
	 * 				medium:	e.g. 'MMM d, y'			=> 'Aug 20, 2014'
102
	 * 				short:	e.g. 'M/d/yy'			=> '8/20/14'
103
	 * 				The exact format is dependent on the language
104
	 * @param \DateTimeZone	$timeZone	The timezone to use
105
	 * @param \OCP\IL10N	$l			The locale to use
106
	 * @return string Formatted date string
107
	 */
108
	public function formatDate($timestamp, $format = 'long', \DateTimeZone $timeZone = null, \OCP\IL10N $l = null) {
109
		return $this->format($timestamp, 'date', $format, $timeZone, $l);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->format($timestamp...format, $timeZone, $l); of type string|integer|false adds false to the return on line 109 which is incompatible with the return type declared by the interface OCP\IDateTimeFormatter::formatDate of type string. It seems like you forgot to handle an error condition.
Loading history...
110
	}
111
112
	/**
113
	 * Formats the date of the given timestamp
114
	 *
115
	 * @param int|\DateTime	$timestamp	Either a Unix timestamp or DateTime object
116
	 * @param string	$format			Either 'full', 'long', 'medium' or 'short'
117
	 * 				full:	e.g. 'EEEE, MMMM d, y'	=> 'Wednesday, August 20, 2014'
118
	 * 				long:	e.g. 'MMMM d, y'		=> 'August 20, 2014'
119
	 * 				medium:	e.g. 'MMM d, y'			=> 'Aug 20, 2014'
120
	 * 				short:	e.g. 'M/d/yy'			=> '8/20/14'
121
	 * 				The exact format is dependent on the language
122
	 * 					Uses 'Today', 'Yesterday' and 'Tomorrow' when applicable
123
	 * @param \DateTimeZone	$timeZone	The timezone to use
124
	 * @param \OCP\IL10N	$l			The locale to use
125
	 * @return string Formatted relative date string
126
	 */
127 View Code Duplication
	public function formatDateRelativeDay($timestamp, $format = 'long', \DateTimeZone $timeZone = null, \OCP\IL10N $l = null) {
128
		if (substr($format, -1) !== '*' && substr($format, -1) !== '*') {
129
			$format .= '^';
130
		}
131
132
		return $this->format($timestamp, 'date', $format, $timeZone, $l);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->format($timestamp...format, $timeZone, $l); of type string|integer|false adds false to the return on line 132 which is incompatible with the return type declared by the interface OCP\IDateTimeFormatter::formatDateRelativeDay of type string. It seems like you forgot to handle an error condition.
Loading history...
133
	}
134
135
	/**
136
	 * Gives the relative date of the timestamp
137
	 * Only works for past dates
138
	 *
139
	 * @param int|\DateTime	$timestamp	Either a Unix timestamp or DateTime object
140
	 * @param int|\DateTime	$baseTimestamp	Timestamp to compare $timestamp against, defaults to current time
141
	 * @return string	Dates returned are:
142
	 * 				<  1 month	=> Today, Yesterday, n days ago
143
	 * 				< 13 month	=> last month, n months ago
144
	 * 				>= 13 month	=> last year, n years ago
145
	 * @param \OCP\IL10N	$l			The locale to use
146
	 * @return string Formatted date span
147
	 */
148
	public function formatDateSpan($timestamp, $baseTimestamp = null, \OCP\IL10N $l = null) {
149
		$l = $this->getLocale($l);
150
		$timestamp = $this->getDateTime($timestamp);
151
		$timestamp->setTime(0, 0, 0);
152
153
		if ($baseTimestamp === null) {
154
			$baseTimestamp = time();
155
		}
156
		$baseTimestamp = $this->getDateTime($baseTimestamp);
157
		$baseTimestamp->setTime(0, 0, 0);
158
		$dateInterval = $timestamp->diff($baseTimestamp);
159
160
		if ($dateInterval->y == 0 && $dateInterval->m == 0 && $dateInterval->d == 0) {
161
			return $l->t('today');
162
		} else if ($dateInterval->y == 0 && $dateInterval->m == 0 && $dateInterval->d == 1) {
163
			if ($timestamp > $baseTimestamp) {
164
				return $l->t('tomorrow');
165
			} else {
166
				return $l->t('yesterday');
167
			}
168
		} else if ($dateInterval->y == 0 && $dateInterval->m == 0) {
169
			if ($timestamp > $baseTimestamp) {
170
				return $l->n('in %n day', 'in %n days', $dateInterval->d);
171
			} else {
172
				return $l->n('%n day ago', '%n days ago', $dateInterval->d);
173
			}
174
		} else if ($dateInterval->y == 0 && $dateInterval->m == 1) {
175
			if ($timestamp > $baseTimestamp) {
176
				return $l->t('next month');
177
			} else {
178
				return $l->t('last month');
179
			}
180
		} else if ($dateInterval->y == 0) {
181
			if ($timestamp > $baseTimestamp) {
182
				return $l->n('in %n month', 'in %n months', $dateInterval->m);
183
			} else {
184
				return $l->n('%n month ago', '%n months ago', $dateInterval->m);
185
			}
186 View Code Duplication
		} else if ($dateInterval->y == 1) {
187
			if ($timestamp > $baseTimestamp) {
188
				return $l->t('next year');
189
			} else {
190
				return $l->t('last year');
191
			}
192
		}
193 View Code Duplication
		if ($timestamp > $baseTimestamp) {
194
			return $l->n('in %n year', 'in %n years', $dateInterval->y);
195
		} else {
196
			return $l->n('%n year ago', '%n years ago', $dateInterval->y);
197
		}
198
	}
199
200
	/**
201
	 * Formats the time of the given timestamp
202
	 *
203
	 * @param int|\DateTime	$timestamp	Either a Unix timestamp or DateTime object
204
	 * @param string	$format			Either 'full', 'long', 'medium' or 'short'
205
	 * 				full:	e.g. 'h:mm:ss a zzzz'	=> '11:42:13 AM GMT+0:00'
206
	 * 				long:	e.g. 'h:mm:ss a z'		=> '11:42:13 AM GMT'
207
	 * 				medium:	e.g. 'h:mm:ss a'		=> '11:42:13 AM'
208
	 * 				short:	e.g. 'h:mm a'			=> '11:42 AM'
209
	 * 				The exact format is dependent on the language
210
	 * @param \DateTimeZone	$timeZone	The timezone to use
211
	 * @param \OCP\IL10N	$l			The locale to use
212
	 * @return string Formatted time string
213
	 */
214
	public function formatTime($timestamp, $format = 'medium', \DateTimeZone $timeZone = null, \OCP\IL10N $l = null) {
215
		return $this->format($timestamp, 'time', $format, $timeZone, $l);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->format($timestamp...format, $timeZone, $l); of type string|integer|false adds false to the return on line 215 which is incompatible with the return type declared by the interface OCP\IDateTimeFormatter::formatTime of type string. It seems like you forgot to handle an error condition.
Loading history...
216
	}
217
218
	/**
219
	 * Gives the relative past time of the timestamp
220
	 *
221
	 * @param int|\DateTime	$timestamp	Either a Unix timestamp or DateTime object
222
	 * @param int|\DateTime	$baseTimestamp	Timestamp to compare $timestamp against, defaults to current time
223
	 * @return string	Dates returned are:
224
	 * 				< 60 sec	=> seconds ago
225
	 * 				<  1 hour	=> n minutes ago
226
	 * 				<  1 day	=> n hours ago
227
	 * 				<  1 month	=> Yesterday, n days ago
228
	 * 				< 13 month	=> last month, n months ago
229
	 * 				>= 13 month	=> last year, n years ago
230
	 * @param \OCP\IL10N	$l			The locale to use
231
	 * @return string Formatted time span
232
	 */
233
	public function formatTimeSpan($timestamp, $baseTimestamp = null, \OCP\IL10N $l = null) {
234
		$l = $this->getLocale($l);
235
		$timestamp = $this->getDateTime($timestamp);
236
		if ($baseTimestamp === null) {
237
			$baseTimestamp = time();
238
		}
239
		$baseTimestamp = $this->getDateTime($baseTimestamp);
240
241
		$diff = $timestamp->diff($baseTimestamp);
242
		if ($diff->y > 0 || $diff->m > 0 || $diff->d > 0) {
243
			return $this->formatDateSpan($timestamp, $baseTimestamp, $l);
244
		}
245
246
		if ($diff->h > 0) {
247 View Code Duplication
			if ($timestamp > $baseTimestamp) {
248
				return $l->n('in %n hour', 'in %n hours', $diff->h);
249
			} else {
250
				return $l->n('%n hour ago', '%n hours ago', $diff->h);
251
			}
252 View Code Duplication
		} else if ($diff->i > 0) {
253
			if ($timestamp > $baseTimestamp) {
254
				return $l->n('in %n minute', 'in %n minutes', $diff->i);
255
			} else {
256
				return $l->n('%n minute ago', '%n minutes ago', $diff->i);
257
			}
258
		}
259
		if ($timestamp > $baseTimestamp) {
260
			return $l->t('in a few seconds');
261
		} else {
262
			return $l->t('seconds ago');
263
		}
264
	}
265
266
	/**
267
	 * Formats the date and time of the given timestamp
268
	 *
269
	 * @param int|\DateTime $timestamp	Either a Unix timestamp or DateTime object
270
	 * @param string		$formatDate		See formatDate() for description
271
	 * @param string		$formatTime		See formatTime() for description
272
	 * @param \DateTimeZone	$timeZone	The timezone to use
273
	 * @param \OCP\IL10N	$l			The locale to use
274
	 * @return string Formatted date and time string
275
	 */
276
	public function formatDateTime($timestamp, $formatDate = 'long', $formatTime = 'medium', \DateTimeZone $timeZone = null, \OCP\IL10N $l = null) {
277
		return $this->format($timestamp, 'datetime', $formatDate . '|' . $formatTime, $timeZone, $l);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->format($timestamp...atTime, $timeZone, $l); of type string|integer|false adds false to the return on line 277 which is incompatible with the return type declared by the interface OCP\IDateTimeFormatter::formatDateTime of type string. It seems like you forgot to handle an error condition.
Loading history...
278
	}
279
280
	/**
281
	 * Formats the date and time of the given timestamp
282
	 *
283
	 * @param int|\DateTime $timestamp	Either a Unix timestamp or DateTime object
284
	 * @param string	$formatDate		See formatDate() for description
285
	 * 					Uses 'Today', 'Yesterday' and 'Tomorrow' when applicable
286
	 * @param string	$formatTime		See formatTime() for description
287
	 * @param \DateTimeZone	$timeZone	The timezone to use
288
	 * @param \OCP\IL10N	$l			The locale to use
289
	 * @return string Formatted relative date and time string
290
	 */
291 View Code Duplication
	public function formatDateTimeRelativeDay($timestamp, $formatDate = 'long', $formatTime = 'medium', \DateTimeZone $timeZone = null, \OCP\IL10N $l = null) {
292
		if (substr($formatDate, -1) !== '^' && substr($formatDate, -1) !== '*') {
293
			$formatDate .= '^';
294
		}
295
296
		return $this->format($timestamp, 'datetime', $formatDate . '|' . $formatTime, $timeZone, $l);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->format($timestamp...atTime, $timeZone, $l); of type string|integer|false adds false to the return on line 296 which is incompatible with the return type declared by the interface OCP\IDateTimeFormatter::formatDateTimeRelativeDay of type string. It seems like you forgot to handle an error condition.
Loading history...
297
	}
298
299
	/**
300
	 * Formats the date and time of the given timestamp
301
	 *
302
	 * @param int|\DateTime $timestamp	Either a Unix timestamp or DateTime object
303
	 * @param string		$type		One of 'date', 'datetime' or 'time'
304
	 * @param string		$format		Format string
305
	 * @param \DateTimeZone	$timeZone	The timezone to use
306
	 * @param \OCP\IL10N	$l			The locale to use
307
	 * @return string Formatted date and time string
308
	 */
309
	protected function format($timestamp, $type, $format, \DateTimeZone $timeZone = null, \OCP\IL10N $l = null) {
310
		$l = $this->getLocale($l);
311
		$timeZone = $this->getTimeZone($timeZone);
312
		$timestamp = $this->getDateTime($timestamp, $timeZone);
313
314
		return $l->l($type, $timestamp, array(
315
			'width' => $format,
316
		));
317
	}
318
}
319