1 <?php
2
3 /*
4 * This file is part of the sfDateTimePlugin package.
5 * (c) 2007 Stephen Riesenberg <sjohnr@gmail.com>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11 /**
12 *
13 * sfDate class.
14 *
15 * A class for representing a date/time value as an object.
16 *
17 * This class allows for chainable calculations using the sfTime utility class.
18 *
19 * @package sfDateTimePlugin
20 * @author Stephen Riesenberg <sjohnr@gmail.com>
21 * @version SVN: $Id$
22 */
23 class sfDate
24 {
25 /**
26 * The timestamp for this sfDate instance.
27 */
28 private $ts = null;
29
30 /**
31 * The original timestamp for this sfDate instance.
32 */
33 private $init = null;
34
35 /**
36 * Retrieves a new instance of this class.
37 *
38 * NOTE: This is not the singleton pattern. Instead, it is for chainability ease-of-use.
39 *
40 * <b>Example:</b>
41 * <code>
42 * echo sfDate::getInstance()->getFirstDayOfWeek()->addDay()->format('Y-m-d');
43 * </code>
44 *
45 * @param mixed timestamp, string, or sfDate object
46 * @return sfDate
47 */
48 public static function getInstance($value = null)
49 {
50 return new sfDate($value);
51 }
52
53 /**
54 * Construct an sfDate object.
55 *
56 * @param mixed timestamp, string, or sfDate object
57 */
58 public function __construct($value = null)
59 {
60 $this->set($value);
61 }
62
63 /**
64 * Format the date according to the <code>date</code> function.
65 *
66 * @return string
67 */
68 public function format($format)
69 {
70 return date($format, $this->ts);
71 }
72
73 /**
74 * Formats the date according to the <code>format_date</code> helper of the Date helper group.
75 *
76 * @return string
77 */
78 public function date($format = 'd')
79 {
80 return date('Y-m-d', $this->ts);
81 }
82
83 /**
84 * Formats the date according to the <code>format_datetime</code> helper of the Date helper group.
85 *
86 * @return string
87 */
88 public function datetime($format = 'F')
89 {
90 return date('Y-m-d H:i:s', $this->ts);
91 }
92
93 /**
94 * Format the date as a datetime value.
95 *
96 * @return string
97 */
98 public function dump()
99 {
100 return date('Y-m-d H:i:s', $this->ts);
101 }
102
103 /**
104 * Retrieves the given unit of time from the timestamp.
105 *
106 * @param int unit of time (accepts sfTime constants).
107 * @return int the unit of time
108 *
109 * @throws sfDateTimeException
110 */
111 public function retrieve($unit = sfTime::DAY)
112 {
113 switch ($unit)
114 {
115 case sfTime::SECOND:
116 return date('s', $this->ts);
117 case sfTime::MINUTE:
118 return date('i', $this->ts);
119 case sfTime::HOUR:
120 return date('H', $this->ts);
121 case sfTime::DAY:
122 return date('d', $this->ts);
123 case sfTime::WEEK:
124 return date('W', $this->ts);
125 case sfTime::MONTH:
126 return date('m', $this->ts);
127 case sfTime::QUARTER:
128 return ceil(date('m', $this->ts) / 3);
129 case sfTime::YEAR:
130 return date('Y', $this->ts);
131 case sfTime::DECADE:
132 return ceil((date('Y', $this->ts) % 100) / 10);
133 case sfTime::CENTURY:
134 return ceil(date('Y', $this->ts) / 100);
135 case sfTime::MILLENIUM:
136 return ceil(date('Y', $this->ts) / 1000);
137 default:
138 throw new sfDateTimeException(sprintf('The unit of time provided is not valid: %s', $unit));
139 }
140 }
141
142 /**
143 * Retrieve the timestamp value of this sfDate instance.
144 *
145 * @return timestamp
146 */
147 public function get()
148 {
149 return $this->ts;
150 }
151
152 /**
153 * Sets the timestamp value of this sfDate instance.
154 *
155 * This function accepts several froms of a date value:
156 * - timestamp
157 * - string, parsed with <code>strtotime</code>
158 * - sfDate object
159 *
160 * @return sfDate the modified object, for chainability
161 */
162 public function set($value = null)
163 {
164 $ts = sfDateTimeToolkit::getTS($value);
165
166 $this->ts = $ts;
167 if ($this->init === null)
168 {
169 $this->init = $ts;
170 }
171
172 return $this;
173 }
174
175 /**
176 * Resets the timestamp value of this sfDate instance to its original value.
177 *
178 * @return sfDate the reset object, for chainability
179 */
180 public function reset()
181 {
182 $this->ts = $this->init;
183
184 return $this;
185 }
186
187 /**
188 * Compares two date values.
189 *
190 * @param mixed timestamp, string, or sfDate object
191 * @return int -1, 0, or 1
192 */
193 public function cmp($value)
194 {
195 $ts = sfDateTimeToolkit::getTS($value);
196
197 if ($this->ts < $ts)
198 {
199 // less than
200 return -1;
201 }
202 else if ($this->ts > $ts)
203 {
204 // greater than
205 return 1;
206 }
207
208 // equal to
209 return 0;
210 }
211
212 /**
213 * Gets the difference of two date values in seconds.
214 *
215 * @param mixed timestamp, string, or sfDate object
216 * @param int the difference in seconds
217 */
218 public function diff($value)
219 {
220 $ts = sfDateTimeToolkit::getTS($value);
221
222 return $this->ts - $ts;
223 }
224
225 /**
226 * Call any function available in the sfTime library, but without the ts parameter.
227 *
228 * <b>Example:</b>
229 * <code>
230 * $ts = sfTime::firstDayOfMonth(sfTime::addMonth(time(), 5));
231 * // equivalent
232 * $dt = new sfDate();
233 * $ts = $dt->addMonth(5)->firstDayOfMonth()->get();
234 * </code>
235 *
236 * @return sfDate the modified object, for chainability
237 */
238 public function __call($method, $arguments)
239 {
240 $callable = array('sfTime', $method);
241
242 if (!is_callable($callable))
243 {
244 throw new sfDateTimeException(sprintf('Call to undefined function: %s::%s', 'sfDate', $method));
245 }
246
247 array_unshift($arguments, $this->ts);
248
249 $this->ts = call_user_func_array($callable, $arguments);
250
251 return $this;
252 }
253 }