summaryrefslogtreecommitdiff
path: root/framework/I18N/TDateFormat.php
blob: e7846be7563e1c07e72dce8e64e20b6ffc2dc8e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
<?php
/**
 * TDateFromat formatting component.
 *
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
 * @link http://www.pradosoft.com/
 * @copyright Copyright &copy; 2005-2014 PradoSoft
 * @license http://www.pradosoft.com/license/
 * @package System.I18N
 */

/**
 * Get the DateFormat class.
 */
Prado::using('System.I18N.core.DateFormat');

/**
 * Get the parent control class.
 */
Prado::using('System.I18N.TI18NControl');

/**
 * To format dates and/or time according to the current locale use
 * <code>
 * <com:TDateFormat Pattern="dd:MMM:yyyy" Value="01/01/2001" />
 *</code>
 * The date will be formatted according to the current locale (or culture)
 * using the format specified by 'Pattern' attribute.
 *
 * To format date and/or time for a locale (e.g. de_DE) include a Culture
 * attribute, for example:
 * <code>
 * <com:TDateFormat Culture="de_DE" Value="01/01/2001 12:00" />
 * </code>
 * The date will be formatted according to this format.
 *
 * If no Pattern was specified then the date will be formatted with the
 * default format (both date and time). If no value for the date is specified
 * then the current date will be used. E.g.: <code><com:TDateFormat /></code>
 * will result in the current date, formatted with default localized pattern.
 *
 * Namespace: System.I18N
 *
 * Properties
 * - <b>Value</b>, date,
 *   <br>Gets or sets the date to format. The tag content is used as Value
 *   if the Value property is not specified.
 * - <b>Pattern</b>, string,
 *   <br>Gets or sets the formatting pattern. The predefined patterns are
 *   'fulldate',           'longdate', 'mediumdate', 'shortdate', 'fulltime',
 * 'longtime', 'mediumtime', and 'shorttime'. Custom patterns can   specified
 * when the Pattern property does not match the predefined   patterns.
 * - <b>DefaultText</b>, string,
 * <br>Gets or sets the default text. If Value is not set, DefaultText will be
 * shown instead of todays date and time.
 *
 * @author Xiang Wei Zhuo <weizhuo[at]gmail[dot]com>
 * @version v1.0, last update on Sat Dec 11 15:25:11 EST 2004
 * @package System.I18N
 */
class TDateFormat extends TI18NControl implements IDataRenderer
{
	/**
	 * Default DateFormat, set to the application culture.
	 * @var DateFormat
	 */
	protected static $formatter;

	/**
	 * A set of pattern presets and their respective formatting shorthand.
	 * @var array
	 */
	static private $_patternPresets = array(
			'fulldate'=>'P','full'=>'P',
			'longdate'=>'D','long'=>'d',
			'mediumdate'=>'p','medium'=>'p',
			'shortdate'=>'d','short'=>'d',
			'fulltime'=>'Q', 'longtime'=>'T',
			'mediumtime'=>'q', 'shorttime'=>'t');

	/**
	 * Sets the date time formatting pattern.
	 * @param string format pattern.
	 */
	public function setPattern($value)
	{
		$this->setViewState('Pattern',$value,'');
	}

	/**
	 * Gets the date time format pattern.
	 * @return string format pattern.
	 */
	public function getPattern()
	{
		$string = $this->getViewState('Pattern','');

		$pattern = null;

		//try the subpattern of "date time" presets
		$subpatterns = explode(' ',$string,2);
		$datetime = array();
		if(count($subpatterns)==2)
		{
			$datetime[] = $this->getPreset($subpatterns[0]);
			$datetime[] = $this->getPreset($subpatterns[1]);
		}

		//we have a good subpattern
		if(count($datetime) == 2
			&& strlen($datetime[0]) == 1
			&& strlen($datetime[1]) == 1)
		{
			$pattern = $datetime;
		}
		else //no subpattern, try the presets
			$pattern = $this->getPreset($string);

		//no presets found, use the string as the pattern
		//and let the DateFormat handle it.
		if($pattern===null)
			$pattern = $string;
		if (!is_array($pattern) && strlen($pattern) == 0)
			$pattern = null;
		return $pattern;
	}

	/**
	 * For a given string, try and find a preset pattern.
	 * @param string the preset pattern name
	 * @return string a preset pattern if found, null otherwise.
	 */
	protected function getPreset($string)
	{
		$string = strtolower($string);
		foreach(self::$_patternPresets as $pattern => $preset)
		{
			if($string == $pattern)
				return $preset;
		}
	}

	/**
	 * Get the date-time value for this control.
	 * @return string date time value.
	 */
	public function getValue()
	{
		$value = $this->getViewState('Value','');
		if(empty($value))
		{
			$defaultText = $this->getDefaultText();
			if(empty($defaultText))
				return time();
		}
		return $value;
	}

	/**
	 * Set the date-time value for this control.
	 * @param string the date-time value.
	 */
	public function setValue($value)
	{
		$this->setViewState('Value',$value,'');
	}

	/**
	 * Get the default text value for this control.
	 * @return string default text value
	 */
	public function getDefaultText()
	{
		return $this->getViewState('DefaultText','');
	}

	/**
	 * Set the default text value for this control.
	 * @param string default text value
	 */
	public function setDefaultText($value)
	{
		$this->setViewState('DefaultText',$value,'');
	}

	/**
	 * Get the date-time value for this control.
	 * This method is required by {@link IDataRenderer}.
	 * It is the same as {@link getValue()}.
	 * @return string date time value.
	 * @see getValue
	 * @since 3.1.2
	 */
	public function getData()
	{
		return $this->getValue();
	}

	/**
	 * Set the date-time value for this control.
	 * This method is required by {@link IDataRenderer}.
	 * It is the same as {@link setValue()}.
	 * @param string the date-time value.
	 * @see setValue
	 * @since 3.1.2
	 */
	public function setData($value)
	{
		$this->setValue($value);
	}

	/**
	 * Renders the localized version of the date-time value.
	 * If the culture is not specified, the default application
	 * culture will be used.
	 * This method overrides parent's implementation.
	 */
	protected function getFormattedDate()
	{
		$value = $this->getValue();
		$defaultText = $this->getDefaultText();
		if(empty($value) && !empty($defaultText))
			return $this->getDefaultText();

		$app = $this->getApplication()->getGlobalization();

		//initialized the default class wide formatter
		if(self::$formatter===null)
			self::$formatter = new DateFormat($app->getCulture());

		$culture = $this->getCulture();

		//return the specific cultural formatted date time
		if(strlen($culture) && $app->getCulture() !== $culture)
		{
			$formatter = new DateFormat($culture);
			return $formatter->format($value,
									  $this->getPattern(),
									  $this->getCharset());
		}
		//return the application wide culture formatted date time.
		$result = self::$formatter->format($value,
										$this->getPattern(),
										$this->getCharset());
		return $result;
	}

	public function render($writer)
	{
		$writer->write($this->getFormattedDate());
	}

}