1: <?php
2: namespace NGS;
3:
4: require_once(__DIR__.'/Utils.php');
5: require_once(__DIR__.'/Timestamp.php');
6:
7: use NGS\Utils;
8:
9: 10: 11: 12: 13: 14:
15: class LocalDate
16: {
17: const DEFAULT_TIMEZONE = 'UTC';
18: const STRING_FORMAT = 'Y-m-d';
19: const FALLBACK_FORMAT = 'Y-m-d\\TH:i:s';
20:
21: 22: 23:
24: protected $datetime;
25:
26: 27: 28: 29: 30: 31: 32: 33:
34: private static function fromNumeric($utime, $timezone)
35: {
36: $strtime = sprintf('%.6f', $utime);
37:
38: $dt = \DateTime::createFromFormat('U.u', $strtime, new \DateTimeZone($timezone));
39: if($dt === false) {
40: throw new \InvalidArgumentException('Cannot initialize "NGS\\LocalDate". Input number was in invalid format: "'.$utime.'"');
41: }
42:
43: $dt->setTimezone(new \DateTimeZone($timezone));
44: return $dt;
45: }
46:
47: 48: 49: 50: 51: 52: 53: 54: 55:
56: private static function fromString($strtime, $timezone, $pattern)
57: {
58: try {
59: $dt = \DateTime::createFromFormat($pattern, $strtime, new \DateTimeZone($timezone));
60: if($dt === false) {
61: if($pattern===self::STRING_FORMAT) {
62: $dt = \DateTime::createFromFormat(self::FALLBACK_FORMAT, $strtime, new \DateTimeZone($timezone));
63: }
64: if($dt === false) {
65:
66: $dt = new \DateTime($strtime);
67: if(!$dt instanceof \DateTime) {
68: throw new \InvalidArgumentException('Cannot initialize "NGS\\LocalDate". Input string was in invalid format: "'.$strtime.'"');
69: }
70: }
71: }
72: }
73: catch(\Exception $ex) {
74:
75: if ($ex instanceof InvalidArgumentException) {
76: throw $ex;
77: }
78:
79:
80: throw new \InvalidArgumentException('Cannot initialize "NGS\\LocalDate". Input string was in invalid format: "'.$strtime.'"',
81: null,
82: $ex);
83: }
84: return $dt;
85: }
86:
87: 88: 89: 90: 91: 92: 93: 94:
95: public function __construct($value = 'now', $pattern = self::STRING_FORMAT, $timezone = self::DEFAULT_TIMEZONE)
96: {
97:
98: if($value === 'now') {
99: $value = microtime(true);
100: }
101:
102: if($pattern === null) {
103: $pattern = self::STRING_FORMAT;
104: }
105:
106: if($value instanceof \DateTime) {
107: $this->datetime = clone $value;
108: }
109: elseif($value instanceof \NGS\Timestamp) {
110: $this->datetime = $value->toDateTime();
111: }
112: elseif($value instanceof \NGS\LocalDate) {
113: $this->datetime = $value->toDateTime();
114: }
115: else if(is_int($value) || is_float($value)) {
116: $this->datetime = self::fromNumeric($value, $timezone);
117: }
118: elseif(is_string($value)) {
119: $this->datetime = self::fromString($value, $timezone, $pattern);
120: }
121: else {
122: throw new \InvalidArgumentException('LocalDate cannot be constructed from type "'.Utils::getType($value).'", valid types are \NGS\LocalDate, \DateTime, string, int, float or null (for current date/time).');
123: }
124:
125: if($this->datetime === null) {
126: throw new \InvalidArgumentException('LocalDate could not be constructed from type "'.Utils::getType($value).'" with value: "'.$value.'"');
127: }
128:
129:
130: $this->datetime->setTime(0, 0, 0);
131: }
132:
133: 134: 135: 136: 137: 138: 139:
140: public static function toArray(array $items, $allowNullValues=false)
141: {
142: $results = array();
143: try {
144: foreach ($items as $key => $val) {
145: if ($allowNullValues && $val===null) {
146: $results[] = null;
147: } elseif ($val === null) {
148: throw new \InvalidArgumentException('Null value found in provided array');
149: } elseif(!$val instanceof \NGS\LocalDate) {
150: $results[] = new \NGS\LocalDate($val);
151: } else {
152: $results[] = $val;
153: }
154: }
155: }
156: catch(\Exception $e) {
157: throw new \InvalidArgumentException('Element at index '.$key.' could not be converted to LocalDate!', 42, $e);
158: }
159: return $results;
160: }
161:
162: 163: 164: 165: 166:
167: public function __toString()
168: {
169: return $this->format(self::STRING_FORMAT);
170: }
171:
172: 173: 174: 175: 176:
177: public function format($pattern)
178: {
179: return $this->datetime->format($pattern);
180: }
181:
182: 183: 184: 185: 186:
187: public function equals(\NGS\LocalDate $other)
188: {
189: return $this->datetime == $other->toDateTime();
190: }
191:
192: 193: 194: 195: 196:
197: public function toInt()
198: {
199: return $this->datetime->getTimestamp();
200: }
201:
202: 203: 204: 205: 206:
207: public function toDateTime()
208: {
209: return clone $this->datetime;
210: }
211:
212: 213: 214: 215: 216:
217: public function toTimestamp()
218: {
219: return new \NGS\Timestamp($this->datetime);
220: }
221: }
222: