Completed
Push — master ( 080ba5...2a2655 )
by Fabio
13:17 queued 07:29
created

TDateFormat   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 229
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 229
rs 10
c 0
b 0
f 0
wmc 30
lcom 2
cbo 1

12 Methods

Rating   Name   Duplication   Size   Complexity  
A setPattern() 0 5 1
A getPattern() 0 4 1
A getPreset() 0 10 3
A getValue() 0 11 3
A setValue() 0 4 1
A getDefaultText() 0 4 1
A setDefaultText() 0 4 1
A getData() 0 4 1
A setData() 0 4 1
A getFormatter() 0 11 4
C getFormattedDate() 0 64 12
A render() 0 4 1
1
<?php
2
/**
3
 * TDateFromat formatting component.
4
 *
5
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
6
 * @link https://github.com/pradosoft/prado
7
 * @copyright Copyright &copy; 2005-2016 The PRADO Group
8
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
9
 * @package Prado\I18N
10
 */
11
12
namespace Prado\I18N;
13
14
use Prado\Prado;
15
use Prado\Util\TUtf8Converter;
16
17
/**
18
 * To format dates and/or time according to the current locale use
19
 * <code>
20
 * <com:TDateFormat Pattern="dd:MMM:yyyy" Value="01/01/2001" />
21
 *</code>
22
 * The date will be formatted according to the current locale (or culture)
23
 * using the format specified by 'Pattern' attribute.
24
 * The 'Pattern' attribute can also contain two of the predefined presets,
25
 * the first one for the date part and the second for the time part:
26
 * 'full', 'long', 'medium', 'short', 'none'.
27
 * If only one preset is present, it will be used for both the date and the
28
 * time parts.
29
 * <code>
30
 * <com:TDateFormat Pattern="medium long" Value="01/01/2001 15:30:45" />
31
 * <com:TDateFormat Pattern="full" Value="01/01/2001 15:30:45" />
32
 *</code>
33
 *
34
 * To format date and/or time for a locale (e.g. de_DE) include a Culture
35
 * attribute, for example:
36
 * <code>
37
 * <com:TDateFormat Culture="de_DE" Value="01/01/2001 12:00" />
38
 * </code>
39
 * The date will be formatted according to this format.
40
 *
41
 * If no Pattern was specified then the date will be formatted with the
42
 * default format (both date and time). If no value for the date is specified
43
 * then the current date will be used. E.g.: <code><com:TDateFormat /></code>
44
 * will result in the current date, formatted with default localized pattern.
45
 *
46
 * @author Xiang Wei Zhuo <weizhuo[at]gmail[dot]com>
47
 * @author Fabio Bas <ctrlaltca[at]gmail[dot]com>
48
 * @package Prado\I18N
49
 */
50
class TDateFormat extends TI18NControl implements \Prado\IDataRenderer
51
{
52
	/**
53
	 * Cached IntlDateFormatter set to the application culture.
54
	 * @var IntlDateFormatter
55
	 */
56
	protected static $formatters;
57
58
	/**
59
	 * A set of pattern presets and their respective formatting shorthand.
60
	 * @var array
61
	 */
62
	private static $_patternPresets = [
63
		'fulldate' => \IntlDateFormatter::FULL,
64
		'full' => \IntlDateFormatter::FULL,
65
		'fulltime' => \IntlDateFormatter::FULL,
66
		'longdate' => \IntlDateFormatter::LONG,
67
		'long' => \IntlDateFormatter::LONG,
68
		'longtime' => \IntlDateFormatter::LONG,
69
		'mediumdate' => \IntlDateFormatter::MEDIUM,
70
		'medium' => \IntlDateFormatter::MEDIUM,
71
		'mediumtime' => \IntlDateFormatter::MEDIUM,
72
		'shortdate' => \IntlDateFormatter::SHORT,
73
		'short' => \IntlDateFormatter::SHORT,
74
		'shorttime' => \IntlDateFormatter::SHORT,
75
		'none' => \IntlDateFormatter::NONE,
76
	];
77
78
	/**
79
	 * Sets the date time formatting pattern.
80
	 * @param string $value format pattern.
81
	 */
82
	public function setPattern($value)
83
	{
84
85
		$this->setViewState('Pattern', $value, '');
86
	}
87
88
	/**
89
	 * Gets the date time format pattern.
90
	 * @return string format pattern.
91
	 */
92
	public function getPattern()
93
	{
94
		return $this->getViewState('Pattern', '');
95
	}
96
97
	/**
98
	 * For a given string, try and find a preset pattern.
99
	 * @param string $string the preset pattern name
100
	 * @return string a preset pattern if found, null otherwise.
101
	 */
102
	protected function getPreset($string)
103
	{
104
		$string = strtolower($string);
105
		foreach (self::$_patternPresets as $pattern => $preset) {
106
			if ($string == $pattern) {
107
				return $preset;
108
			}
109
		}
110
		return null;
111
	}
112
113
	/**
114
	 * Get the date-time value for this control.
115
	 * @return string date time value.
116
	 */
117
	public function getValue()
118
	{
119
		$value = $this->getViewState('Value', '');
120
		if (empty($value)) {
121
			$defaultText = $this->getDefaultText();
122
			if (empty($defaultText)) {
123
				return time();
124
			}
125
		}
126
		return $value;
127
	}
128
129
	/**
130
	 * Set the date-time value for this control.
131
	 * @param string $value the date-time value.
132
	 */
133
	public function setValue($value)
134
	{
135
		$this->setViewState('Value', $value, '');
136
	}
137
138
	/**
139
	 * Get the default text value for this control.
140
	 * @return string default text value
141
	 */
142
	public function getDefaultText()
143
	{
144
		return $this->getViewState('DefaultText', '');
145
	}
146
147
	/**
148
	 * Set the default text value for this control.
149
	 * @param string $value default text value
150
	 */
151
	public function setDefaultText($value)
152
	{
153
		$this->setViewState('DefaultText', $value, '');
154
	}
155
156
	/**
157
	 * Get the date-time value for this control.
158
	 * This method is required by {@link \Prado\IDataRenderer}.
159
	 * It is the same as {@link getValue()}.
160
	 * @return string date time value.
161
	 * @see getValue
162
	 * @since 3.1.2
163
	 */
164
	public function getData()
165
	{
166
		return $this->getValue();
167
	}
168
169
	/**
170
	 * Set the date-time value for this control.
171
	 * This method is required by {@link \Prado\IDataRenderer}.
172
	 * It is the same as {@link setValue()}.
173
	 * @param string $value the date-time value.
174
	 * @see setValue
175
	 * @since 3.1.2
176
	 */
177
	public function setData($value)
178
	{
179
		$this->setValue($value);
180
	}
181
182
	/**
183
	 * Formats the localized number, be it currency or decimal, or percentage.
184
	 * If the culture is not specified, the default application
185
	 * culture will be used.
186
	 * @param string $culture
187
	 * @param mixed $datetype
188
	 * @param mixed $timetype
189
	 * @return NumberFormatter
190
	 */
191
	protected function getFormatter($culture, $datetype, $timetype)
192
	{
193
		if(!isset(self::$formatters[$culture]))
194
			self::$formatters[$culture] = [];
195
		if(!isset(self::$formatters[$culture][$datetype]))
196
			self::$formatters[$culture][$datetype] = [];
197
		if(!isset(self::$formatters[$culture][$datetype][$timetype]))
198
			self::$formatters[$culture][$datetype][$timetype] = new \IntlDateFormatter($culture, $datetype, $timetype);
199
200
		return self::$formatters[$culture][$datetype][$timetype];
201
	}
202
203
	/**
204
	 * Renders the localized version of the date-time value.
205
	 * If the culture is not specified, the default application
206
	 * culture will be used.
207
	 * This method overrides parent's implementation.
208
	 */
209
	protected function getFormattedDate()
210
	{
211
		$value = $this->getValue();
212
		$defaultText = $this->getDefaultText();
213
		if (empty($value) && !empty($defaultText)) {
214
			return $this->getDefaultText();
215
		}
216
217
		// get a date object from textual value
218
		if (is_numeric($value)) { //assumes unix epoch
219
			$value = (float) $value;
220
		} elseif (is_string($value)) {
221
			$value = @strtotime($value);
222
		}
223
224
		$date = new \DateTime;
225
		$date->setTimestamp($value);
226
227
		$culture = $this->getCulture();
228
		$pattern = $this->getPattern();
229
		$datetype = \IntlDateFormatter::LONG;
230
		$timetype = \IntlDateFormatter::LONG;
231
232
		// try the "date time" pattern format
233
		if(!empty($pattern))
234
		{
235
			$subs = explode(' ', $pattern, 2);
236
			if (count($subs) == 2) {
237
				$sub0 = $this->getPreset($subs[0]);
238
				$sub1 = $this->getPreset($subs[1]);
239
240
				if($sub0 !== null && $sub1 !== null)
241
				{
242
					$datetype = $sub0;
243
					$timetype = $sub1;
244
					$pattern = null;
245
				}
246
			}
247
		}
248
249
		// try the "date" pattern format
250
		if(!empty($pattern))
251
		{
252
			$sub = $this->getPreset($pattern);
253
			if($sub !== null)
254
			{
255
				$datetype = $sub;
256
				$timetype = $sub;
257
				$pattern = null;
258
			}
259
		}
260
261
		if(empty($pattern))
262
		{
263
			$formatter = $this->getFormatter($culture, $datetype, $timetype);
264
		} else {
265
			$formatter = new \IntlDateFormatter($culture, $datetype, $timetype);
266
			$formatter->setPattern($pattern);
267
		}
268
269
		$result = $formatter->format($date);
270
271
		return TUtf8Converter::fromUTF8($result, $this->getCharset());
272
	}
273
274
	public function render($writer)
275
	{
276
		$writer->write($this->getFormattedDate());
277
	}
278
}
279