├── .travis.yml ├── LICENSE ├── README.md ├── composer.json ├── phpunit.xml ├── src ├── ExpressiveDate.php └── ExpressiveDateServiceProvider.php └── tests └── ExpressiveDateTest.php /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | branches: 4 | only: 5 | - master 6 | 7 | php: 8 | - 5.3 9 | - 5.4 10 | 11 | before_script: 12 | - curl -s http://getcomposer.org/installer | php 13 | - php composer.phar install --dev 14 | 15 | script: phpunit -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Jason Lewis 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Expressive Date 2 | 3 | A fluent extension to PHPs DateTime class. 4 | 5 | [![Build Status](https://travis-ci.org/jasonlewis/expressive-date.png?branch=master)](https://travis-ci.org/jasonlewis/expressive-date) 6 | 7 | ## Table of Contents 8 | 9 | - Installation 10 | - Composer 11 | - Manually 12 | - Laravel 4 13 | - Usage 14 | - Getting Instances 15 | - Quick Helpers 16 | - Cloning 17 | - Manipulating Dates 18 | - Differences Between Dates 19 | - Comparing Dates 20 | - Interacting With Dates 21 | - Formatting Dates 22 | - Working With Timezones 23 | - Changelog 24 | - License 25 | 26 | ## Installation 27 | 28 | ### Composer 29 | 30 | Add Expressive Date to your `composer.json` file. 31 | 32 | "jasonlewis/expressive-date": "1.0.*" 33 | 34 | Run `composer install` to get the latest version of the package. 35 | 36 | ### Manually 37 | 38 | It's recommended that you use Composer, however you can download and install from this repository. 39 | 40 | ### Laravel 4 41 | 42 | Expressive Date comes with a service provider for Laravel 4. You'll need to add it to your `composer.json` as mentioned in the above steps, then register the service provider with your application. 43 | 44 | Open `app/config/app.php` and find the `providers` key. Add `ExpressiveDateServiceProvider` to the array. 45 | 46 | You can get an instance of Expressive Date through the applications container. 47 | 48 | ```php 49 | $date = App::make('date'); 50 | 51 | // Or if you have access to an instance of the application. 52 | $date = $app['date']; 53 | ``` 54 | 55 | You can also use the other instantiation methods described below. 56 | 57 | ## Usage 58 | 59 | Expressive Date is an extension to PHPs [DateTime](http://www.php.net/manual/en/class.datetime.php) class. This means that if you can't do something with Expressive Date you still have the flexibility of `DateTime` at your disposal. 60 | 61 | ### Getting Instances 62 | 63 | Before you can begin working with dates you'll need to get an instance of `ExpressiveDate`. You have a number of options available to you. 64 | 65 | ```php 66 | // Instantiate a new instance of Expressive Date. 67 | // This will create an instance and use the current date and time 68 | $date = new ExpressiveDate; 69 | 70 | // Use the static make method to get an instance of Expressive Date. 71 | $date = ExpressiveDate::make(); 72 | ``` 73 | 74 | Both of these methods accepts two parameters, a time string and a timezone. This is identical to the `DateTime` constructor except the second parameters timezone does not need to be an intance of `DateTimeZone`. 75 | 76 | ```php 77 | // Pass a valid timezone as the second parameter. 78 | $date = new ExpressiveDate(null, 'Australia/Melbourne'); 79 | 80 | // Or you can still use a DateTimeZone instance. 81 | $timezone = new DateTimeZone('Australia/Melbourne'); 82 | 83 | $date = new ExpressiveDate(null, $timezone); 84 | ``` 85 | 86 | Alternatively, you can make a date from existing dates or times. 87 | 88 | ```php 89 | // You can use existing dates to get an instance of Expressive Date. 90 | $date = ExpressiveDate::makeFromDate(2012, 1, 31); 91 | 92 | // If you have the time, you can use that instead. 93 | $date = ExpressiveDate::makeFromTime(14, 30, 0); 94 | ``` 95 | 96 | If you use `null` as any of the parameters then Expressive Date will use the current respective value. The only exception to this is if you supply an hour to `ExpressiveDate::makeFromTime()` but no minute or second, instead of defaulting to the current minute or second it will set them to 0. This mimicks the existing functionality when interacting with dates using PHP. 97 | 98 | ### Quick Helpers 99 | 100 | There are a couple of quick helper methods available to you when using Expressive Date. 101 | 102 | ```php 103 | $date = new ExpressiveDate; // Creates an instance that uses current date and time 104 | 105 | $date->today(); // Sets to todays date, e.g., 1991-01-31 00:00:00 106 | 107 | $date->tomorrow(); // Sets to tomorrows date, e.g., 1991-02-01 00:00:00 108 | 109 | $date->yesterday(); // Sets to yesterdays date, e.g., 1991-01-30 00:00:00 110 | ``` 111 | 112 | These helpers also set the time to midnight. 113 | 114 | ### Cloning 115 | 116 | You can clone an instance of `ExpressiveDate` with the `clone()` method. 117 | 118 | ```php 119 | $date = new ExpressiveDate; 120 | 121 | $clone = $date->clone(); 122 | ``` 123 | 124 | A clone is identical to the original instance and is useful when you need to compare or manipulate a date without affecting the original instance. 125 | 126 | ### Manipulating Dates 127 | 128 | When working with dates you'll often want to manipulate it in a number of ways. Expressive Date eases this process with a simple and intuitive syntax. 129 | 130 | ```php 131 | $date = new ExpressiveDate('December 1, 2012 12:00:00 PM'); 132 | 133 | $date->addOneDay(); // December 2, 2012 12:00:00 PM 134 | $date->addDays(10); // December 12, 2012 12:00:00 PM 135 | $date->minusOneDay(); // December 11, 2012 12:00:00 PM 136 | $date->minusDays(10); // December 1, 2012 12:00:00 PM 137 | 138 | $date->addOneWeek(); // December 8, 2012 12:00:00 PM 139 | $date->addWeeks(10); // February 16, 2013, at 12:00:00 PM 140 | $date->minusOneWeek(); // February 9, 2013 12:00:00 PM 141 | $date->minusWeeks(10); // December 1, 2012 12:00:00 PM 142 | 143 | $date->addOneMonth(); // January 1, 2013 12:00:00 PM 144 | $date->addMonths(10); // November 1, 2013 12:00:00 PM 145 | $date->minusOneMonth(); // October 1, 2013 12:00:00 PM 146 | $date->minusMonths(10); // December 1, 2012 12:00:00 PM 147 | 148 | $date->addOneYear(); // December 1, 2013 12:00:00 PM 149 | $date->addYears(10); // December 1, 2023 12:00:00 PM 150 | $date->minusOneYear(); // December 1, 2022 12:00:00 PM 151 | $date->minusYears(10); // December 1, 2012 12:00:00 PM 152 | 153 | $date->addOneHour(); // December 1, 2012 1:00:00 PM 154 | $date->addHours(10); // December 1, 2012 11:00:00 PM 155 | $date->minusOneHour(); // December 1, 2012 10:00:00 PM 156 | $date->minusHours(10); // December 1, 2012 12:00:00 PM 157 | 158 | $date->addOneMinute(); // December 1, 2012 12:01:00 PM 159 | $date->addMinutes(10); // December 1, 2012 12:11:00 PM 160 | $date->minusOneMinute(); // December 1, 2012 12:10:00 PM 161 | $date->minusMinutes(10); // December 1, 2012 12:00:00 PM 162 | 163 | $date->addOneSecond(); // December 1, 2012 12:00:01 PM 164 | $date->addSeconds(10); // December 1, 2012 12:00:11 PM 165 | $date->minusOneSecond(); // December 1, 2012 12:00:10 PM 166 | $date->minusSeconds(10); // December 1, 2012 12:00:00 PM 167 | ``` 168 | 169 | You can also set the unit manually using one of the setters. 170 | 171 | ```php 172 | $date = new ExpressiveDate('December 1, 2012 12:00:00 PM'); 173 | 174 | $date->setDay(31); // December 31, 2012 12:00:00 PM 175 | $date->setMonth(1); // January 31, 2012 12:00:00 PM 176 | $date->setYear(1991); // January 31, 1991 12:00:00 PM 177 | $date->setHour(6); // January 31, 1991 6:00:00 AM 178 | $date->setMinute(30); // January 31, 1991 6:30:00 AM 179 | $date->setSecond(53); // January 31, 1991 6:30:53 AM 180 | ``` 181 | 182 | There are also several methods to quick jump to the start or end of a day, month, or week. 183 | 184 | ```php 185 | $date = new ExpressiveDate('December 1, 2012 12:00:00 PM'); 186 | 187 | $date->startOfDay(); // December 1, 2012 12:00:00 AM 188 | $date->endOfDay(); // December 1, 2012 11:59:59 PM 189 | 190 | $date->startOfWeek(); // 25th November, 2012 at 12:00 AM 191 | $date->endOfWeek(); // 1st December, 2012 at 11:59 PM 192 | 193 | $date->startOfMonth(); // December 1, 2012 12:00:00 AM 194 | $date->endOfMonth(); // December 31, 2012 11:59:59 PM 195 | ``` 196 | 197 | The start and end of the week are influenced by what day you configure to be the start of the week. In America, the start of the week is Sunday and for most other places it's Monday. By default the start of the week is Sunday. 198 | 199 | ```php 200 | $date = new ExpressiveDate('December 1, 2012 12:00:00 PM'); 201 | 202 | // Set the week start day to Monday, to set it to Sunday you'd use 0. 203 | $date->setWeekStartDay(1); 204 | 205 | // You can also use the actual name of the day so it makes more sense. 206 | $date->setWeekStartDay('monday'); 207 | 208 | $date->startOfWeek(); // 26th November, 2012 at 12:00 AM 209 | ``` 210 | 211 | Lastly you can set the timestamp directly or set it from a string. 212 | 213 | ```php 214 | $date = new ExpressiveDate; 215 | 216 | $date->setTimestamp(time()); // Set the timestamp to the current time. 217 | $date->setTimestampFromString('31 January 1991'); // Set timestamp from a string. 218 | ``` 219 | 220 | ### Differences Between Dates 221 | 222 | Getting the difference between two dates is very easy with Expressive Date. Let's see how long it's been since my birthday, which was on the 31st January, 1991. 223 | 224 | ```php 225 | $date = new ExpressiveDate('January 31, 1991'); 226 | $now = new ExpressiveDate('December 1, 2012'); 227 | 228 | $date->getDifferenceInYears($now); // 21 229 | $date->getDifferenceInMonths($now); // 262 230 | $date->getDifferenceInDays($now); // 7975 231 | $date->getDifferenceInHours($now); // 191400 232 | $date->getDifferenceInMinutes($now); // 11484000 233 | $date->getDifferenceInSeconds($now); // 689040000 234 | ``` 235 | 236 | Wow, I'm over 689040000 seconds old! 237 | 238 | In the above example I'm explicitly passing in another instance to compare against. You don't have to, by default it'll use the current date and time. 239 | 240 | ```php 241 | $date = new ExpressiveDate('January 31, 1991'); 242 | 243 | $date->getDifferenceInYears(); // Will use the current date and time to get the difference. 244 | ``` 245 | 246 | ### Comparing Dates 247 | 248 | Being able to compare two dates is important in many applications. Expressive Date allows you to compare two `ExpressiveDate` instances against one another in a variety of ways. 249 | 250 | ```php 251 | $date = new ExpressiveDate; 252 | 253 | $date->equalTo($date->clone()); // true 254 | $date->sameAs($date->clone()->minusOneDay()); // false 255 | $date->notEqualTo($date->clone()); // false 256 | $date->greaterThan($date->clone()->minusOneDay()); // true 257 | $date->lessThan($date->clone()->addOneDay()); // true 258 | $date->greaterOrEqualTo($date->clone()); // true 259 | $date->lessOrEqualTo($date->clone()->minusOneDay()); // false 260 | ``` 261 | 262 | The methods themselves should be self explanatory. The `sameAs()` method is an alias of `equalTo()`. 263 | 264 | ### Interacting With Dates 265 | 266 | Expressive Date provides a number of helpful methods for interacting with your dates and times. 267 | 268 | ```php 269 | $date = new ExpressiveDate('December 1, 2012 2:30:50 PM'); 270 | 271 | $date->getDay(); // 1 272 | $date->getMonth(); // 12 273 | $date->getYear(); // 2012 274 | $date->getHour(); // 14 275 | $date->getMinute(); // 30 276 | $date->getSecond(); // 50 277 | $date->getDayOfWeek(); // Saturday 278 | $date->getDayOfWeekAsNumeric(); // 6 279 | $date->getDaysInMonth(); // 31 280 | $date->getDayOfYear(); // 335 281 | $date->getDaySuffix(); // st 282 | $date->getGmtDifference(); // +1100 283 | $date->getSecondsSinceEpoch(); // 1354320000 284 | $date->isLeapYear(); // true 285 | $date->isAmOrPm(); // PM 286 | $date->isDaylightSavings(); // true 287 | $date->isWeekday(); // false 288 | $date->isWeekend(); // true 289 | ``` 290 | 291 | ### Formatting Dates 292 | 293 | It's now time to display your date and time to everyone. Expressive Date comes with a couple of predefined formatting methods for your convenience. 294 | 295 | ```php 296 | $date = new ExpressiveDate('December 1, 2012 2:30:50 PM'); 297 | 298 | $date->getDate(); // 2012-12-01 299 | $date->getDateTime(); // 2012-12-01 14:30:50 300 | $date->getShortDate(); // Dec 1, 2012 301 | $date->getLongDate(); // December 1st, 2012 at 2:30pm 302 | $date->getTime(); // 14:30:50 303 | 304 | // You can still define your own formats. 305 | $date->format('jS F, Y'); // 31st January, 2012 306 | ``` 307 | 308 | You can set a default date format on each instance of Expressive Date which will then be used when you cast the object to a string. 309 | 310 | ```php 311 | $date = new ExpressiveDate('December 1, 2012 2:30:50 PM'); 312 | 313 | echo $date; // 1st December, 2012 at 2:30pm 314 | 315 | $date->setDefaultDateFormat('d M y'); 316 | 317 | echo $date; // 1 Dec 12 318 | ``` 319 | 320 | Expressive Date also comes with a human readable or relative date method. 321 | 322 | ```php 323 | $date = new ExpressiveDate('December 1, 2012 2:30:50 PM'); 324 | 325 | $date->getRelativeDate(); // Would show something similar to: 4 days ago 326 | ``` 327 | 328 | You can also pass in an instance of Expressive Date to compare against, and it's date can also be in the future. 329 | 330 | ```php 331 | $now = new ExpressiveDate('December 1, 2012 2:30:50 PM'); 332 | $future = new ExpressiveDate('December 9, 2012 7:45:32 AM'); 333 | 334 | $now->getRelativeDate($future); // 1 week from now 335 | ``` 336 | 337 | ### Working with Timezones 338 | 339 | It's always important to factor in timezones when working with dates and times. Because Expressive Date uses PHPs `DateTime` class it'll default to using the date defined with `date_default_timezone_set()`. 340 | 341 | If you need to you can manipulate the timezone on the fly. 342 | 343 | ```php 344 | $date = new ExpressiveDate; 345 | 346 | $date->setTimezone('Australia/Darwin'); 347 | 348 | // Or use an instance of DateTimeZone. 349 | $timezone = new DateTimeZone('Australia/Darwin'); 350 | 351 | $date->setTimezone($timezone); 352 | ``` 353 | 354 | You can also get an instance of PHPs `DateTimeZone` if you need it for other manipulations. 355 | 356 | ```php 357 | $date = new ExpressiveDate; 358 | 359 | $timezone = $date->getTimezone(); 360 | ``` 361 | 362 | Or you can just get the name of the timezone. 363 | 364 | ```php 365 | $date = new ExpressiveDate; 366 | 367 | $timezone = $date->getTimezoneName(); // Australia/Melbourne 368 | ``` 369 | 370 | ## Changelog 371 | 372 | ### 1.0.2 373 | 374 | - Added `copy` method. 375 | - Added docblock for magic method hints. 376 | - Added `startOfWeek`, `endOfWeek`, `setWeekStartDay`, and `getWeekStartDay` methods. 377 | - Allowed `setWeekStartDay` to accept the name of the day as a parameter, e.g., Monday. 378 | - Fixed exceptions being thrown when using floats for manipulation, e.g., `ExpressiveDate::addDays(0.5)`. 379 | - Added `makeFromDate`, `makeFromTime`, and `makeFromDateTime` methods. 380 | - Fixed bug with the week start day being inclusive resulting in 8 day weeks. 381 | - Added `equalTo`, `sameAs`, `greaterThan`, `lessThan`, `greaterOrEqualTo`, and `lessOrEqualTo` methods. 382 | 383 | ### 1.0.1 384 | 385 | - Added the `setDefaultDate` method. 386 | - Added `__toString` method which uses the default date. 387 | - Removed the `String` suffix from date formatting methods. 388 | 389 | ### 1.0.0 390 | 391 | - Initial release. 392 | 393 | ## License 394 | 395 | Expressive Date is licensed under the 2-clause BSD, see the `LICENSE` file for more details. 396 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jasonlewis/expressive-date", 3 | "description": "A fluent extension to PHPs DateTime class.", 4 | "keywords": ["date", "time"], 5 | "license": "BSD-2-Clause", 6 | "authors": [ 7 | { 8 | "name": "Jason Lewis", 9 | "email": "jason.lewis1991@gmail.com", 10 | "homepage": "http://jasonlewis.me" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=5.2.0" 15 | }, 16 | "autoload": { 17 | "classmap": ["src"] 18 | }, 19 | "minimum-stability": "stable" 20 | } 21 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/ 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/ExpressiveDate.php: -------------------------------------------------------------------------------- 1 | parseSuppliedTimezone($timezone); 55 | 56 | parent::__construct($time, $timezone); 57 | } 58 | 59 | /** 60 | * Make and return new ExpressiveDate instance. 61 | * 62 | * @param string $time 63 | * @param string|DateTimeZone $timezone 64 | * @return ExpressiveDate 65 | */ 66 | public static function make($time = null, $timezone = null) 67 | { 68 | return new static($time, $timezone); 69 | } 70 | 71 | /** 72 | * Make and return a new ExpressiveDate instance with defined year, month, and day. 73 | * 74 | * @param int $year 75 | * @param int $month 76 | * @param int $day 77 | * @param string|DateTimeZone $timezone 78 | * @return ExpressiveDate 79 | */ 80 | public static function makeFromDate($year = null, $month = null, $day = null, $timezone = null) 81 | { 82 | return static::makeFromDateTime($year, $month, $day, null, null, null, $timezone); 83 | } 84 | 85 | /** 86 | * Make and return a new ExpressiveDate instance with defined hour, minute, and second. 87 | * 88 | * @param int $hour 89 | * @param int $minute 90 | * @param int $second 91 | * @param string|DateTimeZone $timezone 92 | * @return ExpressiveDate 93 | */ 94 | public static function makeFromTime($hour = null, $minute = null, $second = null, $timezone = null) 95 | { 96 | return static::makeFromDateTime(null, null, null, $hour, $minute, $second, $timezone); 97 | } 98 | 99 | /** 100 | * Make and return a new ExpressiveDate instance with defined year, month, day, hour, minute, and second. 101 | * 102 | * @param int $year 103 | * @param int $month 104 | * @param int $day 105 | * @param int $hour 106 | * @param int $minute 107 | * @param int $second 108 | * @param string|DateTimeZone $timezone 109 | * @return ExpressiveDate 110 | */ 111 | public static function makeFromDateTime($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $timezone = null) 112 | { 113 | $date = new static(null, $timezone); 114 | 115 | $date->setDate($year ?: $date->getYear(), $month ?: $date->getMonth(), $day ?: $date->getDay()); 116 | 117 | // If no hour was given then we'll default the minute and second to the current 118 | // minute and second. If a date was given and minute or second are null then 119 | // we'll set them to 0, mimicking PHPs behaviour. 120 | if (is_null($hour)) 121 | { 122 | $minute = $minute ?: $date->getMinute(); 123 | $second = $second ?: $date->getSecond(); 124 | } 125 | else 126 | { 127 | $minute = $minute ?: 0; 128 | $second = $second ?: 0; 129 | } 130 | 131 | $date->setTime($hour ?: $date->getHour(), $minute, $second); 132 | 133 | return $date; 134 | 135 | } 136 | 137 | /** 138 | * Parse a supplied timezone. 139 | * 140 | * @param string|DateTimeZone $timezone 141 | * @return DateTimeZone 142 | */ 143 | protected function parseSuppliedTimezone($timezone) 144 | { 145 | if ($timezone instanceof DateTimeZone or is_null($timezone)) 146 | { 147 | return $timezone; 148 | } 149 | 150 | try 151 | { 152 | $timezone = new DateTimeZone($timezone); 153 | } 154 | catch (Exception $error) 155 | { 156 | throw new InvalidArgumentException('The supplied timezone ['.$timezone.'] is not supported.'); 157 | } 158 | 159 | return $timezone; 160 | } 161 | 162 | /** 163 | * Use the current date and time. 164 | * 165 | * @return ExpressiveDate 166 | */ 167 | public function now() 168 | { 169 | $this->setTimestamp(time()); 170 | 171 | return $this; 172 | } 173 | 174 | /** 175 | * Use today's date and time at midnight. 176 | * 177 | * @return ExpressiveDate 178 | */ 179 | public function today() 180 | { 181 | $this->now()->setHour(0)->setMinute(0)->setSecond(0); 182 | 183 | return $this; 184 | } 185 | 186 | /** 187 | * Use tomorrow's date and time at midnight. 188 | * 189 | * @return ExpressiveDate 190 | */ 191 | public function tomorrow() 192 | { 193 | $this->now()->addOneDay()->startOfDay(); 194 | 195 | return $this; 196 | } 197 | 198 | /** 199 | * Use yesterday's date and time at midnight. 200 | * 201 | * @return ExpressiveDate 202 | */ 203 | public function yesterday() 204 | { 205 | $this->now()->minusOneDay()->startOfDay(); 206 | 207 | return $this; 208 | } 209 | 210 | /** 211 | * Use the start of the day. 212 | * 213 | * @return ExpressiveDate 214 | */ 215 | public function startOfDay() 216 | { 217 | $this->setHour(0)->setMinute(0)->setSecond(0); 218 | 219 | return $this; 220 | } 221 | 222 | /** 223 | * Use the end of the day. 224 | * 225 | * @return ExpressiveDate 226 | */ 227 | public function endOfDay() 228 | { 229 | $this->setHour(23)->setMinute(59)->setSecond(59); 230 | 231 | return $this; 232 | } 233 | 234 | /** 235 | * Use the start of the week. 236 | * 237 | * @return ExpressiveDate 238 | */ 239 | public function startOfWeek() 240 | { 241 | $this->minusDays($this->getDayOfWeekAsNumeric())->startOfDay(); 242 | 243 | return $this; 244 | } 245 | 246 | /** 247 | * Use the end of the week. 248 | * 249 | * @return ExpressiveDate 250 | */ 251 | public function endOfWeek() 252 | { 253 | $this->addDays(6 - $this->getDayOfWeekAsNumeric())->endOfDay(); 254 | 255 | return $this; 256 | } 257 | 258 | /** 259 | * Use the start of the month. 260 | * 261 | * @return ExpressiveDate 262 | */ 263 | public function startOfMonth() 264 | { 265 | $this->setDay(1)->startOfDay(); 266 | 267 | return $this; 268 | } 269 | 270 | /** 271 | * Use the end of the month. 272 | * 273 | * @return ExpressiveDate 274 | */ 275 | public function endOfMonth() 276 | { 277 | $this->setDay($this->getDaysInMonth())->endOfDay(); 278 | 279 | return $this; 280 | } 281 | 282 | /** 283 | * Add one day. 284 | * 285 | * @param int $amount 286 | * @return ExpressiveDate 287 | */ 288 | public function addOneDay() 289 | { 290 | return $this->modifyDays(1); 291 | } 292 | 293 | /** 294 | * Add a given amount of days. 295 | * 296 | * @param int $amount 297 | * @return ExpressiveDate 298 | */ 299 | public function addDays($amount) 300 | { 301 | return $this->modifyDays($amount); 302 | } 303 | 304 | /** 305 | * Minus one day. 306 | * 307 | * @return ExpressiveDate 308 | */ 309 | public function minusOneDay() 310 | { 311 | return $this->modifyDays(1, true); 312 | } 313 | 314 | /** 315 | * Minus a given amount of days. 316 | * 317 | * @param int $amount 318 | * @return ExpressiveDate 319 | */ 320 | public function minusDays($amount) 321 | { 322 | return $this->modifyDays($amount, true); 323 | } 324 | 325 | /** 326 | * Modify by an amount of days. 327 | * 328 | * @param int $amount 329 | * @param bool $invert 330 | * @return ExpressiveDate 331 | */ 332 | protected function modifyDays($amount, $invert = false) 333 | { 334 | if ($this->isFloat($amount)) 335 | { 336 | return $this->modifyHours($amount * 24, $invert); 337 | } 338 | 339 | $interval = new DateInterval("P{$amount}D"); 340 | 341 | $this->modifyFromInterval($interval, $invert); 342 | 343 | return $this; 344 | } 345 | 346 | /** 347 | * Add one month. 348 | * 349 | * @param int $amount 350 | * @return ExpressiveDate 351 | */ 352 | public function addOneMonth() 353 | { 354 | return $this->modifyMonths(1); 355 | } 356 | 357 | /** 358 | * Add a given amount of months. 359 | * 360 | * @param int $amount 361 | * @return ExpressiveDate 362 | */ 363 | public function addMonths($amount) 364 | { 365 | return $this->modifyMonths($amount); 366 | } 367 | 368 | /** 369 | * Minus one month. 370 | * 371 | * @return ExpressiveDate 372 | */ 373 | public function minusOneMonth() 374 | { 375 | return $this->modifyMonths(1, true); 376 | } 377 | 378 | /** 379 | * Minus a given amount of months. 380 | * 381 | * @param int $amount 382 | * @return ExpressiveDate 383 | */ 384 | public function minusMonths($amount) 385 | { 386 | return $this->modifyMonths($amount, true); 387 | } 388 | 389 | /** 390 | * Modify by an amount of months. 391 | * 392 | * @param int $amount 393 | * @param bool $invert 394 | * @return ExpressiveDate 395 | */ 396 | protected function modifyMonths($amount, $invert = false) 397 | { 398 | if ($this->isFloat($amount)) 399 | { 400 | return $this->modifyWeeks($amount * 4, $invert); 401 | } 402 | 403 | $interval = new DateInterval("P{$amount}M"); 404 | 405 | $this->modifyFromInterval($interval, $invert); 406 | 407 | return $this; 408 | } 409 | 410 | /** 411 | * Add one year. 412 | * 413 | * @param int $amount 414 | * @return ExpressiveDate 415 | */ 416 | public function addOneYear() 417 | { 418 | return $this->modifyYears(1); 419 | } 420 | 421 | /** 422 | * Add a given amount of years. 423 | * 424 | * @param int $amount 425 | * @return ExpressiveDate 426 | */ 427 | public function addYears($amount) 428 | { 429 | return $this->modifyYears($amount); 430 | } 431 | 432 | /** 433 | * Minus one year. 434 | * 435 | * @return ExpressiveDate 436 | */ 437 | public function minusOneYear() 438 | { 439 | return $this->modifyYears(1, true); 440 | } 441 | 442 | /** 443 | * Minus a given amount of years. 444 | * 445 | * @param int $amount 446 | * @return ExpressiveDate 447 | */ 448 | public function minusYears($amount) 449 | { 450 | return $this->modifyYears($amount, true); 451 | } 452 | 453 | /** 454 | * Modify by an amount of Years. 455 | * 456 | * @param int $amount 457 | * @param bool $invert 458 | * @return ExpressiveDate 459 | */ 460 | protected function modifyYears($amount, $invert = false) 461 | { 462 | if ($this->isFloat($amount)) 463 | { 464 | return $this->modifyMonths($amount * 12, $invert); 465 | } 466 | 467 | $interval = new DateInterval("P{$amount}Y"); 468 | 469 | $this->modifyFromInterval($interval, $invert); 470 | 471 | return $this; 472 | } 473 | 474 | /** 475 | * Add one hour. 476 | * 477 | * @param int $amount 478 | * @return ExpressiveDate 479 | */ 480 | public function addOneHour() 481 | { 482 | return $this->modifyHours(1); 483 | } 484 | 485 | /** 486 | * Add a given amount of hours. 487 | * 488 | * @param int $amount 489 | * @return ExpressiveDate 490 | */ 491 | public function addHours($amount) 492 | { 493 | return $this->modifyHours($amount); 494 | } 495 | 496 | /** 497 | * Minus one hour. 498 | * 499 | * @return ExpressiveDate 500 | */ 501 | public function minusOneHour() 502 | { 503 | return $this->modifyHours(1, true); 504 | } 505 | 506 | /** 507 | * Minus a given amount of hours. 508 | * 509 | * @param int $amount 510 | * @return ExpressiveDate 511 | */ 512 | public function minusHours($amount) 513 | { 514 | return $this->modifyHours($amount, true); 515 | } 516 | 517 | /** 518 | * Modify by an amount of hours. 519 | * 520 | * @param int $amount 521 | * @param bool $invert 522 | * @return ExpressiveDate 523 | */ 524 | protected function modifyHours($amount, $invert = false) 525 | { 526 | if ($this->isFloat($amount)) 527 | { 528 | return $this->modifyMinutes($amount * 60, $invert); 529 | } 530 | 531 | $interval = new DateInterval("PT{$amount}H"); 532 | 533 | $this->modifyFromInterval($interval, $invert); 534 | 535 | return $this; 536 | } 537 | 538 | /** 539 | * Add one minute. 540 | * 541 | * @param int $amount 542 | * @return ExpressiveDate 543 | */ 544 | public function addOneMinute() 545 | { 546 | return $this->modifyMinutes(1); 547 | } 548 | 549 | /** 550 | * Add a given amount of minutes. 551 | * 552 | * @param int $amount 553 | * @return ExpressiveDate 554 | */ 555 | public function addMinutes($amount) 556 | { 557 | return $this->modifyMinutes($amount); 558 | } 559 | 560 | /** 561 | * Minus one minute. 562 | * 563 | * @return ExpressiveDate 564 | */ 565 | public function minusOneMinute() 566 | { 567 | return $this->modifyMinutes(1, true); 568 | } 569 | 570 | /** 571 | * Minus a given amount of minutes. 572 | * 573 | * @param int $amount 574 | * @return ExpressiveDate 575 | */ 576 | public function minusMinutes($amount) 577 | { 578 | return $this->modifyMinutes($amount, true); 579 | } 580 | 581 | /** 582 | * Modify by an amount of minutes. 583 | * 584 | * @param int $amount 585 | * @param bool $invert 586 | * @return ExpressiveDate 587 | */ 588 | protected function modifyMinutes($amount, $invert = false) 589 | { 590 | if ($this->isFloat($amount)) 591 | { 592 | return $this->modifySeconds($amount * 60, $invert); 593 | } 594 | 595 | $interval = new DateInterval("PT{$amount}M"); 596 | 597 | $this->modifyFromInterval($interval, $invert); 598 | 599 | return $this; 600 | } 601 | 602 | /** 603 | * Add one second. 604 | * 605 | * @param int $amount 606 | * @return ExpressiveDate 607 | */ 608 | public function addOneSecond() 609 | { 610 | return $this->modifySeconds(1); 611 | } 612 | 613 | /** 614 | * Add a given amount of seconds. 615 | * 616 | * @param int $amount 617 | * @return ExpressiveDate 618 | */ 619 | public function addSeconds($amount) 620 | { 621 | return $this->modifySeconds($amount); 622 | } 623 | 624 | /** 625 | * Minus one second. 626 | * 627 | * @return ExpressiveDate 628 | */ 629 | public function minusOneSecond() 630 | { 631 | return $this->modifySeconds(1, true); 632 | } 633 | 634 | /** 635 | * Minus a given amount of seconds. 636 | * 637 | * @param int $amount 638 | * @return ExpressiveDate 639 | */ 640 | public function minusSeconds($amount) 641 | { 642 | return $this->modifySeconds($amount, true); 643 | } 644 | 645 | /** 646 | * Modify by an amount of seconds. 647 | * 648 | * @param int $amount 649 | * @param bool $invert 650 | * @return ExpressiveDate 651 | */ 652 | protected function modifySeconds($amount, $invert = false) 653 | { 654 | $interval = new DateInterval("PT{$amount}S"); 655 | 656 | $this->modifyFromInterval($interval, $invert); 657 | 658 | return $this; 659 | } 660 | 661 | /** 662 | * Add one week. 663 | * 664 | * @param int $amount 665 | * @return ExpressiveDate 666 | */ 667 | public function addOneWeek() 668 | { 669 | return $this->modifyWeeks(1); 670 | } 671 | 672 | /** 673 | * Add a given amount of weeks. 674 | * 675 | * @param int $amount 676 | * @return ExpressiveDate 677 | */ 678 | public function addWeeks($amount) 679 | { 680 | return $this->modifyWeeks($amount); 681 | } 682 | 683 | /** 684 | * Minus one week. 685 | * 686 | * @return ExpressiveDate 687 | */ 688 | public function minusOneWeek() 689 | { 690 | return $this->modifyWeeks(1, true); 691 | } 692 | 693 | /** 694 | * Minus a given amount of weeks. 695 | * 696 | * @param int $amount 697 | * @return ExpressiveDate 698 | */ 699 | public function minusWeeks($amount) 700 | { 701 | return $this->modifyWeeks($amount, true); 702 | } 703 | 704 | /** 705 | * Modify by an amount of weeks. 706 | * 707 | * @param int $amount 708 | * @param bool $invert 709 | * @return ExpressiveDate 710 | */ 711 | protected function modifyWeeks($amount, $invert = false) 712 | { 713 | if ($this->isFloat($amount)) 714 | { 715 | return $this->modifyDays($amount * 7, $invert); 716 | } 717 | 718 | $interval = new DateInterval("P{$amount}W"); 719 | 720 | $this->modifyFromInterval($interval, $invert); 721 | 722 | return $this; 723 | } 724 | 725 | /** 726 | * Modify from a DateInterval object. 727 | * 728 | * @param DateInterval $interval 729 | * @param bool $invert 730 | * @return ExpressiveDate 731 | */ 732 | protected function modifyFromInterval($interval, $invert = false) 733 | { 734 | if ($invert) 735 | { 736 | $this->sub($interval); 737 | } 738 | else 739 | { 740 | $this->add($interval); 741 | } 742 | 743 | return $this; 744 | } 745 | 746 | /** 747 | * Set the timezone. 748 | * 749 | * @param string|DateTimeZone $timezone 750 | * @return ExpressiveDate 751 | */ 752 | public function setTimezone($timezone) 753 | { 754 | $timezone = $this->parseSuppliedTimezone($timezone); 755 | 756 | parent::setTimezone($timezone); 757 | 758 | return $this; 759 | } 760 | 761 | /** 762 | * Sets the timestamp from a human readable string. 763 | * 764 | * @param string $string 765 | * @return ExpressiveDate 766 | */ 767 | public function setTimestampFromString($string) 768 | { 769 | $this->setTimestamp(strtotime($string)); 770 | 771 | return $this; 772 | } 773 | 774 | /** 775 | * Determine if day is a weekday. 776 | * 777 | * @return bool 778 | */ 779 | public function isWeekday() 780 | { 781 | $day = $this->getDayOfWeek(); 782 | 783 | return ! in_array($day, array('Saturday', 'Sunday')); 784 | } 785 | 786 | /** 787 | * Determine if day is a weekend. 788 | * 789 | * @return bool 790 | */ 791 | public function isWeekend() 792 | { 793 | return ! $this->isWeekday(); 794 | } 795 | 796 | /** 797 | * Get the difference in years. 798 | * 799 | * @param ExpressiveDate $compare 800 | * @return string 801 | */ 802 | public function getDifferenceInYears($compare = null) 803 | { 804 | if ( ! $compare) 805 | { 806 | $compare = new ExpressiveDate(null, $this->getTimezone()); 807 | } 808 | 809 | return $this->diff($compare)->format('%r%y'); 810 | } 811 | 812 | /** 813 | * Get the difference in months. 814 | * 815 | * @param ExpressiveDate $compare 816 | * @return string 817 | */ 818 | public function getDifferenceInMonths($compare = null) 819 | { 820 | if ( ! $compare) 821 | { 822 | $compare = new ExpressiveDate(null, $this->getTimezone()); 823 | } 824 | 825 | $difference = $this->diff($compare); 826 | 827 | list($years, $months) = explode(':', $difference->format('%y:%m')); 828 | 829 | return (($years * 12) + $months) * $difference->format('%r1'); 830 | } 831 | 832 | /** 833 | * Get the difference in days. 834 | * 835 | * @param ExpressiveDate $compare 836 | * @return string 837 | */ 838 | public function getDifferenceInDays($compare = null) 839 | { 840 | if ( ! $compare) 841 | { 842 | $compare = new ExpressiveDate(null, $this->getTimezone()); 843 | } 844 | 845 | return $this->diff($compare)->format('%r%a'); 846 | } 847 | 848 | /** 849 | * Get the difference in hours. 850 | * 851 | * @param ExpressiveDate $compare 852 | * @return string 853 | */ 854 | public function getDifferenceInHours($compare = null) 855 | { 856 | return $this->getDifferenceInMinutes($compare) / 60; 857 | } 858 | 859 | /** 860 | * Get the difference in minutes. 861 | * 862 | * @param ExpressiveDate $compare 863 | * @return string 864 | */ 865 | public function getDifferenceInMinutes($compare = null) 866 | { 867 | return $this->getDifferenceInSeconds($compare) / 60; 868 | } 869 | 870 | /** 871 | * Get the difference in seconds. 872 | * 873 | * @param ExpressiveDate $compare 874 | * @return string 875 | */ 876 | public function getDifferenceInSeconds($compare = null) 877 | { 878 | if ( ! $compare) 879 | { 880 | $compare = new ExpressiveDate(null, $this->getTimezone()); 881 | } 882 | 883 | $difference = $this->diff($compare); 884 | 885 | list($days, $hours, $minutes, $seconds) = explode(':', $difference->format('%a:%h:%i:%s')); 886 | 887 | // Add the total amount of seconds in all the days. 888 | $seconds += ($days * 24 * 60 * 60); 889 | 890 | // Add the total amount of seconds in all the hours. 891 | $seconds += ($hours * 60 * 60); 892 | 893 | // Add the total amount of seconds in all the minutes. 894 | $seconds += ($minutes * 60); 895 | 896 | return $seconds * $difference->format('%r1'); 897 | } 898 | 899 | /** 900 | * Get a relative date string, e.g., 3 days ago. 901 | * 902 | * @param ExpressiveDate $compare 903 | * @return string 904 | */ 905 | public function getRelativeDate($compare = null) 906 | { 907 | if ( ! $compare) 908 | { 909 | $compare = new ExpressiveDate(null, $this->getTimezone()); 910 | } 911 | 912 | $units = array('second', 'minute', 'hour', 'day', 'week', 'month', 'year'); 913 | $values = array(60, 60, 24, 7, 4.35, 12); 914 | 915 | // Get the difference between the two timestamps. We'll use this to cacluate the 916 | // actual time remaining. 917 | $difference = abs($compare->getTimestamp() - $this->getTimestamp()); 918 | 919 | for ($i = 0; $i < count($values) and $difference >= $values[$i]; $i++) 920 | { 921 | $difference = $difference / $values[$i]; 922 | } 923 | 924 | // Round the difference to the nearest whole number. 925 | $difference = round($difference); 926 | 927 | if ($compare->getTimestamp() < $this->getTimestamp()) 928 | { 929 | $suffix = 'from now'; 930 | } 931 | else 932 | { 933 | $suffix = 'ago'; 934 | } 935 | 936 | // Get the unit of time we are measuring. We'll then check the difference, if it is not equal 937 | // to exactly 1 then it's a multiple of the given unit so we'll append an 's'. 938 | $unit = $units[$i]; 939 | 940 | if ($difference != 1) 941 | { 942 | $unit .= 's'; 943 | } 944 | 945 | return $difference.' '.$unit.' '.$suffix; 946 | } 947 | 948 | /** 949 | * Get a date string in the format of 2012-12-04. 950 | * 951 | * @return string 952 | */ 953 | public function getDate() 954 | { 955 | return $this->format('Y-m-d'); 956 | } 957 | 958 | /** 959 | * Get a date and time string in the format of 2012-12-04 23:43:27. 960 | * 961 | * @return string 962 | */ 963 | public function getDateTime() 964 | { 965 | return $this->format('Y-m-d H:i:s'); 966 | } 967 | 968 | /** 969 | * Get a date string in the format of Jan 31, 1991. 970 | * 971 | * @return string 972 | */ 973 | public function getShortDate() 974 | { 975 | return $this->format('M j, Y'); 976 | } 977 | 978 | /** 979 | * Get a date string in the format of January 31st, 1991 at 7:45am. 980 | * 981 | * @return string 982 | */ 983 | public function getLongDate() 984 | { 985 | return $this->format('F jS, Y \a\\t g:ia'); 986 | } 987 | 988 | /** 989 | * Get a date string in the format of 07:42:32. 990 | * 991 | * @return string 992 | */ 993 | public function getTime() 994 | { 995 | return $this->format('H:i:s'); 996 | } 997 | 998 | /** 999 | * Get a date string in the default format. 1000 | * 1001 | * @return string 1002 | */ 1003 | public function getDefaultDate() 1004 | { 1005 | return $this->format($this->defaultDateFormat); 1006 | } 1007 | 1008 | /** 1009 | * Set the default date format. 1010 | * 1011 | * @param string $format 1012 | * @return ExpressiveDate 1013 | */ 1014 | public function setDefaultDateFormat($format) 1015 | { 1016 | $this->defaultDateFormat = $format; 1017 | 1018 | return $this; 1019 | } 1020 | 1021 | /** 1022 | * Set the starting day of the week, where 0 is Sunday and 1 is Monday. 1023 | * 1024 | * @param int|string $weekStartDay 1025 | * @return void 1026 | */ 1027 | public function setWeekStartDay($weekStartDay) 1028 | { 1029 | if (is_numeric($weekStartDay)) 1030 | { 1031 | $this->weekStartDay = $weekStartDay; 1032 | } 1033 | else 1034 | { 1035 | $this->weekStartDay = array_search(strtolower($weekStartDay), array('sunday', 'monday')); 1036 | } 1037 | 1038 | return $this; 1039 | } 1040 | 1041 | /** 1042 | * Get the starting day of the week, where 0 is Sunday and 1 is Monday 1043 | * 1044 | * @return int 1045 | */ 1046 | public function getWeekStartDay() 1047 | { 1048 | return $this->weekStartDay; 1049 | } 1050 | 1051 | /** 1052 | * Get a date attribute. 1053 | * 1054 | * @param string $attribute 1055 | * @return mixed 1056 | */ 1057 | protected function getDateAttribute($attribute) 1058 | { 1059 | switch ($attribute) 1060 | { 1061 | case 'Day': 1062 | return $this->format('d'); 1063 | break; 1064 | case 'Month': 1065 | return $this->format('m'); 1066 | break; 1067 | case 'Year': 1068 | return $this->format('Y'); 1069 | break; 1070 | case 'Hour': 1071 | return $this->format('G'); 1072 | break; 1073 | case 'Minute': 1074 | return $this->format('i'); 1075 | break; 1076 | case 'Second': 1077 | return $this->format('s'); 1078 | break; 1079 | case 'DayOfWeek': 1080 | return $this->format('l'); 1081 | break; 1082 | case 'DayOfWeekAsNumeric': 1083 | return (7 + $this->format('w') - $this->getWeekStartDay()) % 7; 1084 | break; 1085 | case 'DaysInMonth': 1086 | return $this->format('t'); 1087 | break; 1088 | case 'DayOfYear': 1089 | return $this->format('z'); 1090 | break; 1091 | case 'DaySuffix': 1092 | return $this->format('S'); 1093 | break; 1094 | case 'GmtDifference': 1095 | return $this->format('O'); 1096 | break; 1097 | case 'SecondsSinceEpoch': 1098 | return $this->format('U'); 1099 | break; 1100 | case 'TimezoneName': 1101 | return $this->getTimezone()->getName(); 1102 | break; 1103 | } 1104 | 1105 | throw new InvalidArgumentException('The date attribute ['.$attribute.'] could not be found.'); 1106 | } 1107 | 1108 | /** 1109 | * Syntactical sugar for determining if date object "is" a condition. 1110 | * 1111 | * @param string $attribute 1112 | * @return mixed 1113 | */ 1114 | protected function isDateAttribute($attribute) 1115 | { 1116 | switch ($attribute) 1117 | { 1118 | case 'LeapYear': 1119 | return (bool) $this->format('L'); 1120 | break; 1121 | case 'AmOrPm': 1122 | return $this->format('A'); 1123 | break; 1124 | case 'DaylightSavings': 1125 | return (bool) $this->format('I'); 1126 | break; 1127 | } 1128 | 1129 | throw new InvalidArgumentException('The date attribute ['.$attribute.'] could not be found.'); 1130 | } 1131 | 1132 | /** 1133 | * Set a date attribute. 1134 | * 1135 | * @param string $attribute 1136 | * @return mixed 1137 | */ 1138 | protected function setDateAttribute($attribute, $value) 1139 | { 1140 | switch ($attribute) 1141 | { 1142 | case 'Day': 1143 | return $this->setDate($this->getYear(), $this->getMonth(), $value); 1144 | break; 1145 | case 'Month': 1146 | return $this->setDate($this->getYear(), $value, $this->getDay()); 1147 | break; 1148 | case 'Year': 1149 | return $this->setDate($value, $this->getMonth(), $this->getDay()); 1150 | break; 1151 | case 'Hour': 1152 | return $this->setTime($value, $this->getMinute(), $this->getSecond()); 1153 | break; 1154 | case 'Minute': 1155 | return $this->setTime($this->getHour(), $value, $this->getSecond()); 1156 | break; 1157 | case 'Second': 1158 | return $this->setTime($this->getHour(), $this->getMinute(), $value); 1159 | break; 1160 | } 1161 | 1162 | throw new InvalidArgumentException('The date attribute ['.$attribute.'] could not be set.'); 1163 | } 1164 | 1165 | /** 1166 | * Alias for ExpressiveDate::equalTo() 1167 | * 1168 | * @param ExpressiveDate $date 1169 | * @return bool 1170 | */ 1171 | public function sameAs(ExpressiveDate $date) 1172 | { 1173 | return $this->equalTo($date); 1174 | } 1175 | 1176 | /** 1177 | * Determine if date is equal to another Expressive Date instance. 1178 | * 1179 | * @param ExpressiveDate $date 1180 | * @return bool 1181 | */ 1182 | public function equalTo(ExpressiveDate $date) 1183 | { 1184 | return $this == $date; 1185 | } 1186 | 1187 | /** 1188 | * Determine if date is not equal to another Expressive Date instance. 1189 | * 1190 | * @param ExpressiveDate $date 1191 | * @return bool 1192 | */ 1193 | public function notEqualTo(ExpressiveDate $date) 1194 | { 1195 | return ! $this->equalTo($date); 1196 | } 1197 | 1198 | /** 1199 | * Determine if date is greater than another Expressive Date instance. 1200 | * 1201 | * @param ExpressiveDate $date 1202 | * @return bool 1203 | */ 1204 | public function greaterThan(ExpressiveDate $date) 1205 | { 1206 | return $this > $date; 1207 | } 1208 | 1209 | /** 1210 | * Determine if date is less than another Expressive Date instance. 1211 | * 1212 | * @param ExpressiveDate $date 1213 | * @return bool 1214 | */ 1215 | public function lessThan(ExpressiveDate $date) 1216 | { 1217 | return $this < $date; 1218 | } 1219 | 1220 | /** 1221 | * Determine if date is greater than or equal to another Expressive Date instance. 1222 | * 1223 | * @param ExpressiveDate $date 1224 | * @return bool 1225 | */ 1226 | public function greaterOrEqualTo(ExpressiveDate $date) 1227 | { 1228 | return $this >= $date; 1229 | } 1230 | 1231 | /** 1232 | * Determine if date is less than or equal to another Expressive Date instance. 1233 | * 1234 | * @param ExpressiveDate $date 1235 | * @return bool 1236 | */ 1237 | public function lessOrEqualTo(ExpressiveDate $date) 1238 | { 1239 | return $this <= $date; 1240 | } 1241 | 1242 | /** 1243 | * Dynamically handle calls for date attributes and testers. 1244 | * 1245 | * @param string $method 1246 | * @param array $parameters 1247 | * @return mixed 1248 | */ 1249 | public function __call($method, $parameters) 1250 | { 1251 | if (substr($method, 0, 3) == 'get' or substr($method, 0, 3) == 'set') 1252 | { 1253 | $attribute = substr($method, 3); 1254 | } 1255 | elseif (substr($method, 0, 2) == 'is') 1256 | { 1257 | $attribute = substr($method, 2); 1258 | 1259 | return $this->isDateAttribute($attribute); 1260 | } 1261 | 1262 | if ( ! isset($attribute)) 1263 | { 1264 | throw new InvalidArgumentException('Could not dynamically handle method call ['.$method.']'); 1265 | } 1266 | 1267 | if (substr($method, 0, 3) == 'set') 1268 | { 1269 | return $this->setDateAttribute($attribute, $parameters[0]); 1270 | } 1271 | 1272 | // If not setting an attribute then we'll default to getting an attribute. 1273 | return $this->getDateAttribute($attribute); 1274 | } 1275 | 1276 | /** 1277 | * Return the default date format when casting to string. 1278 | * 1279 | * @return string 1280 | */ 1281 | public function __toString() 1282 | { 1283 | return $this->getDefaultDate(); 1284 | } 1285 | 1286 | /** 1287 | * Determine if a given amount is a floating point number. 1288 | * 1289 | * @param int|float $amount 1290 | * @return bool 1291 | */ 1292 | protected function isFloat($amount) 1293 | { 1294 | return is_float($amount) and intval($amount) != $amount; 1295 | } 1296 | 1297 | /** 1298 | * Return copy of expressive date object 1299 | * 1300 | * @return ExpressiveDate 1301 | */ 1302 | public function copy() 1303 | { 1304 | return clone $this; 1305 | } 1306 | 1307 | } -------------------------------------------------------------------------------- /src/ExpressiveDateServiceProvider.php: -------------------------------------------------------------------------------- 1 | app['date'] = function($app) 15 | { 16 | return new ExpressiveDate; 17 | }; 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /tests/ExpressiveDateTest.php: -------------------------------------------------------------------------------- 1 | date = null; 12 | } 13 | 14 | 15 | public function setUp() 16 | { 17 | date_default_timezone_set('Australia/Melbourne'); 18 | 19 | $this->date = new ExpressiveDate; 20 | } 21 | 22 | 23 | public function testDateIsCreatedFromNow() 24 | { 25 | $this->assertEquals(time(), $this->date->getTimestamp()); 26 | } 27 | 28 | 29 | public function testDateIsCreatedFromStaticMethod() 30 | { 31 | $date = ExpressiveDate::make(); 32 | $this->assertEquals(time(), $date->getTimestamp()); 33 | } 34 | 35 | 36 | public function testDateIsCreatedFromDate() 37 | { 38 | $date = ExpressiveDate::makeFromDate(2013, 1, 31); 39 | $this->assertEquals('2013-01-31', $date->getDate()); 40 | } 41 | 42 | 43 | public function testDateIsCreatedFromTime() 44 | { 45 | $date = ExpressiveDate::makeFromTime(20, null, null); 46 | $this->assertEquals('20:00:00', $date->getTime()); 47 | 48 | $date = ExpressiveDate::makeFromTime(-12, null, 120); 49 | $this->assertEquals('12:02:00', $date->getTime()); 50 | 51 | $date = ExpressiveDate::makeFromTime(12, 30, 125); 52 | $this->assertEquals('12:32:05', $date->getTime()); 53 | } 54 | 55 | 56 | public function testDateIsCreatedFromDateTime() 57 | { 58 | $date = ExpressiveDate::makeFromDateTime(2013, 1, 31, 8, null, null); 59 | $this->assertEquals('2013-01-31 08:00:00', $date->getDateTime()); 60 | 61 | $date = ExpressiveDate::makeFromDateTime(2013, 1, 31, -12, null, null); 62 | $this->assertEquals('2013-01-30 12:00:00', $date->getDateTime()); 63 | } 64 | 65 | 66 | public function testDateIsCreatedWithDifferentTimezone() 67 | { 68 | $date = new ExpressiveDate(null, 'Europe/Paris'); 69 | date_default_timezone_set('Europe/Paris'); 70 | $this->assertEquals(time(), $date->getTimestamp()); 71 | 72 | date_default_timezone_set('Australia/Melbourne'); 73 | 74 | $date = new ExpressiveDate(null, new DateTimeZone('Europe/Paris')); 75 | date_default_timezone_set('Europe/Paris'); 76 | $this->assertEquals(time(), $date->getTimestamp()); 77 | } 78 | 79 | 80 | public function testDateIsCreatedWithCustomTimeString() 81 | { 82 | $date = new ExpressiveDate('31 January 1991'); 83 | $this->assertEquals('31/01/1991', $date->format('d/m/Y')); 84 | 85 | $date = new ExpressiveDate('+1 day'); 86 | $this->assertEquals(time() + 86400, $date->getTimestamp()); 87 | 88 | $date = new ExpressiveDate('-1 day'); 89 | $this->assertEquals(time() - 86400, $date->getTimestamp()); 90 | } 91 | 92 | 93 | /** 94 | * @expectedException InvalidArgumentException 95 | */ 96 | public function testCannotCreateDateWithInvalidTimezone() 97 | { 98 | $date = new ExpressiveDate(null, 'Australia/JasonsPlace'); 99 | } 100 | 101 | 102 | public function testUseTomorrowsDateAndTime() 103 | { 104 | $this->assertEquals(strtotime('tomorrow'), $this->date->tomorrow()->getTimestamp()); 105 | } 106 | 107 | 108 | public function testUseYesterdaysDateAndTime() 109 | { 110 | $this->assertEquals(strtotime('yesterday'), $this->date->yesterday()->getTimestamp()); 111 | } 112 | 113 | 114 | public function testStartOfDay() 115 | { 116 | $this->assertEquals(strtotime('today'), $this->date->startOfDay()->getTimestamp()); 117 | } 118 | 119 | 120 | public function testEndOfDay() 121 | { 122 | $this->assertEquals(strtotime('tomorrow -1 second'), $this->date->endOfDay()->getTimestamp()); 123 | } 124 | 125 | 126 | public function testStartOfMonth() 127 | { 128 | $this->assertEquals(strtotime('January 1'), $this->date->setDay(31)->setMonth(1)->startOfMonth()->getTimestamp()); 129 | } 130 | 131 | 132 | public function testEndOfMonth() 133 | { 134 | $this->assertEquals(strtotime('February 1 -1 second'), $this->date->setMonth(1)->setDay(1)->endOfMonth()->getTimestamp()); 135 | } 136 | 137 | 138 | public function testDayOfWeekAsNumber() 139 | { 140 | $date = new ExpressiveDate('17 March 2013'); 141 | $this->assertEquals(0, $date->setWeekStartDay(0)->getDayOfWeekAsNumeric()); 142 | $this->assertEquals(6, $date->setWeekStartDay(1)->getDayOfWeekAsNumeric()); 143 | 144 | $this->assertEquals(1, $date->setDay(18)->setWeekStartDay(0)->getDayOfWeekAsNumeric()); 145 | $this->assertEquals(0, $date->setDay(18)->setWeekStartDay(1)->getDayOfWeekAsNumeric()); 146 | 147 | $this->assertEquals(6, $date->setDay(23)->setWeekStartDay(0)->getDayOfWeekAsNumeric()); 148 | $this->assertEquals(5, $date->setDay(23)->setWeekStartDay(1)->getDayOfWeekAsNumeric()); 149 | } 150 | 151 | 152 | public function testSetDayOfWeekFromString() 153 | { 154 | $date = new ExpressiveDate('17 March 2013'); 155 | $this->assertEquals(0, $date->setWeekStartDay('sunday')->getDayOfWeekAsNumeric()); 156 | $this->assertEquals(6, $date->setWeekStartDay('monday')->getDayOfWeekAsNumeric()); 157 | } 158 | 159 | 160 | public function testStartOfWeek() 161 | { 162 | $date = new ExpressiveDate('17 March 2013'); 163 | $date->setWeekStartDay(0); 164 | 165 | $this->assertEquals('2013/03/17', $date->copy()->startOfWeek()->format('Y/m/d')); 166 | $this->assertEquals('2013/03/17', $date->copy()->setDay(19)->startOfWeek()->format('Y/m/d')); 167 | $this->assertEquals('2013/03/17', $date->copy()->setDay(23)->startOfWeek()->format('Y/m/d')); 168 | $this->assertEquals('2013/03/24', $date->copy()->setDay(24)->startOfWeek()->format('Y/m/d')); 169 | 170 | $date = new ExpressiveDate('18 March 2013'); 171 | $date->setWeekStartDay(1); 172 | 173 | $this->assertEquals('2013/02/25', $date->copy()->setDay(1)->startOfWeek()->format('Y/m/d')); 174 | $this->assertEquals('2013/03/18', $date->copy()->setDay(18)->startOfWeek()->format('Y/m/d')); 175 | $this->assertEquals('2013/03/18', $date->copy()->setDay(19)->startOfWeek()->format('Y/m/d')); 176 | $this->assertEquals('2013/03/18', $date->copy()->setDay(23)->startOfWeek()->format('Y/m/d')); 177 | $this->assertEquals('2013/03/18', $date->copy()->setDay(24)->startOfWeek()->format('Y/m/d')); 178 | $this->assertEquals('2013/03/25', $date->copy()->setDay(25)->startOfWeek()->format('Y/m/d')); 179 | } 180 | 181 | 182 | public function testEndOfWeek() 183 | { 184 | $date = new ExpressiveDate('17 March 2013'); 185 | $date->setWeekStartDay(0); 186 | 187 | $this->assertEquals('2013/03/23', $date->copy()->endOfWeek()->format('Y/m/d')); 188 | $this->assertEquals('2013/03/23', $date->copy()->setDay(19)->endOfWeek()->format('Y/m/d')); 189 | $this->assertEquals('2013/03/23', $date->copy()->setDay(23)->endOfWeek()->format('Y/m/d')); 190 | $this->assertEquals('2013/03/30', $date->copy()->setDay(24)->endOfWeek()->format('Y/m/d')); 191 | 192 | $date = new ExpressiveDate('18 March 2013'); 193 | $date->setWeekStartDay(1); 194 | 195 | $this->assertEquals('2013/03/24', $date->copy()->setDay(18)->endOfWeek()->format('Y/m/d')); 196 | $this->assertEquals('2013/03/24', $date->copy()->setDay(24)->endOfWeek()->format('Y/m/d')); 197 | $this->assertEquals('2013/03/31', $date->copy()->setDay(25)->endOfWeek()->format('Y/m/d')); 198 | } 199 | 200 | 201 | public function testAddingDays() 202 | { 203 | $this->assertEquals(strtotime('+1 day'), $this->date->copy()->addOneDay()->getTimestamp()); 204 | $this->assertEquals(strtotime('+4 days'), $this->date->copy()->addDays(4)->getTimestamp()); 205 | } 206 | 207 | 208 | public function testSubtractingDays() 209 | { 210 | $this->assertEquals(strtotime('-1 day'), $this->date->copy()->minusOneDay()->getTimestamp()); 211 | $this->assertEquals(strtotime('-4 days'), $this->date->copy()->minusDays(4)->getTimestamp()); 212 | } 213 | 214 | 215 | public function testAddingMonths() 216 | { 217 | $this->assertEquals(strtotime('+1 month'), $this->date->copy()->addOneMonth()->getTimestamp()); 218 | $this->assertEquals(strtotime('+4 months'), $this->date->copy()->addMonths(4)->getTimestamp()); 219 | } 220 | 221 | 222 | public function testSubtractingMonths() 223 | { 224 | $this->assertEquals(strtotime('-1 month'), $this->date->copy()->minusOneMonth()->getTimestamp()); 225 | $this->assertEquals(strtotime('-4 months'), $this->date->copy()->minusMonths(4)->getTimestamp()); 226 | } 227 | 228 | 229 | public function testAddingYears() 230 | { 231 | $this->assertEquals(strtotime('+1 year'), $this->date->copy()->addOneYear()->getTimestamp()); 232 | $this->assertEquals(strtotime('+4 years'), $this->date->copy()->addYears(4)->getTimestamp()); 233 | } 234 | 235 | 236 | public function testSubtractingYears() 237 | { 238 | $this->assertEquals(strtotime('-1 year'), $this->date->copy()->minusOneYear()->getTimestamp()); 239 | $this->assertEquals(strtotime('-4 years'), $this->date->copy()->minusYears(4)->getTimestamp()); 240 | } 241 | 242 | 243 | public function testAddingHours() 244 | { 245 | $this->assertEquals(strtotime('+1 hour'), $this->date->copy()->addOneHour()->getTimestamp()); 246 | $this->assertEquals(strtotime('+4 hours'), $this->date->copy()->addHours(4)->getTimestamp()); 247 | } 248 | 249 | 250 | public function testSubtractingHours() 251 | { 252 | $this->assertEquals(strtotime('-1 hour'), $this->date->copy()->minusOneHour()->getTimestamp()); 253 | $this->assertEquals(strtotime('-4 hours'), $this->date->copy()->minusHours(4)->getTimestamp()); 254 | } 255 | 256 | 257 | public function testAddingMinutes() 258 | { 259 | $this->assertEquals(strtotime('+1 minute'), $this->date->copy()->addOneMinute()->getTimestamp()); 260 | $this->assertEquals(strtotime('+4 minutes'), $this->date->copy()->addMinutes(4)->getTimestamp()); 261 | } 262 | 263 | 264 | public function testSubtractingMinutes() 265 | { 266 | $this->assertEquals(strtotime('-1 minute'), $this->date->copy()->minusOneMinute()->getTimestamp()); 267 | $this->assertEquals(strtotime('-4 minutes'), $this->date->copy()->minusMinutes(4)->getTimestamp()); 268 | } 269 | 270 | 271 | public function testAddingSeconds() 272 | { 273 | $this->assertEquals(strtotime('+1 second'), $this->date->copy()->addOneSecond()->getTimestamp()); 274 | $this->assertEquals(strtotime('+4 seconds'), $this->date->copy()->addSeconds(4)->getTimestamp()); 275 | } 276 | 277 | 278 | public function testSubtractingSeconds() 279 | { 280 | $this->assertEquals(strtotime('-1 second'), $this->date->copy()->minusOneSecond()->getTimestamp()); 281 | $this->assertEquals(strtotime('-4 seconds'), $this->date->copy()->minusSeconds(4)->getTimestamp()); 282 | } 283 | 284 | 285 | public function testAddingWeeks() 286 | { 287 | $this->assertEquals(strtotime('+1 week'), $this->date->copy()->addOneWeek()->getTimestamp()); 288 | $this->assertEquals(strtotime('+4 weeks'), $this->date->copy()->addWeeks(4)->getTimestamp()); 289 | } 290 | 291 | 292 | public function testSubtractingWeeks() 293 | { 294 | $this->assertEquals(strtotime('-1 week'), $this->date->copy()->minusOneWeek()->getTimestamp()); 295 | $this->assertEquals(strtotime('-4 weeks'), $this->date->copy()->minusWeeks(4)->getTimestamp()); 296 | } 297 | 298 | 299 | public function testAddingDayFractions() 300 | { 301 | $this->assertEquals(strtotime('+12 hours'), $this->date->copy()->addDays(0.5)->getTimestamp()); 302 | $this->assertEquals(strtotime('+18 hours'), $this->date->copy()->addDays(0.75)->getTimestamp()); 303 | } 304 | 305 | 306 | public function testSubtractingDayFractions() 307 | { 308 | $this->assertEquals(strtotime('-12 hours'), $this->date->copy()->minusDays(0.5)->getTimestamp()); 309 | $this->assertEquals(strtotime('-18 hours'), $this->date->copy()->minusDays(0.75)->getTimestamp()); 310 | } 311 | 312 | 313 | public function testAddingMonthFractions() 314 | { 315 | $this->assertEquals(strtotime('+7 days'), $this->date->copy()->addMonths(0.25)->getTimestamp()); 316 | $this->assertEquals(strtotime('+7 weeks'), $this->date->copy()->addMonths(1.75)->getTimestamp()); 317 | } 318 | 319 | 320 | public function testSubtractingMonthFractions() 321 | { 322 | $this->assertEquals(strtotime('-7 days'), $this->date->copy()->minusMonths(0.25)->getTimestamp()); 323 | $this->assertEquals(strtotime('-7 weeks'), $this->date->copy()->minusMonths(1.75)->getTimestamp()); 324 | } 325 | 326 | 327 | public function testAddingYearFractions() 328 | { 329 | $this->assertEquals(strtotime('+3 months'), $this->date->copy()->addYears(0.25)->getTimestamp()); 330 | $this->assertEquals(strtotime('+15 months'), $this->date->copy()->addYears(1.25)->getTimestamp()); 331 | } 332 | 333 | 334 | public function testSubtractingYearFractions() 335 | { 336 | $this->assertEquals(strtotime('-3 months'), $this->date->copy()->minusYears(0.25)->getTimestamp()); 337 | $this->assertEquals(strtotime('-15 months'), $this->date->copy()->minusYears(1.25)->getTimestamp()); 338 | } 339 | 340 | 341 | public function testAddingHourFractions() 342 | { 343 | $this->assertEquals(strtotime('+30 minutes'), $this->date->copy()->addHours(0.5)->getTimestamp()); 344 | $this->assertEquals(strtotime('+75 minutes'), $this->date->copy()->addHours(1.25)->getTimestamp()); 345 | } 346 | 347 | 348 | public function testSubtractingHourFractions() 349 | { 350 | $this->assertEquals(strtotime('-30 minutes'), $this->date->copy()->minusHours(0.5)->getTimestamp()); 351 | $this->assertEquals(strtotime('-105 minutes'), $this->date->copy()->minusHours(1.75)->getTimestamp()); 352 | } 353 | 354 | 355 | public function testAddingMinuteFractions() 356 | { 357 | $this->assertEquals(strtotime('+54 seconds'), $this->date->copy()->addMinutes(0.9)->getTimestamp()); 358 | $this->assertEquals(strtotime('+12 seconds'), $this->date->copy()->addMinutes(0.2)->getTimestamp()); 359 | } 360 | 361 | 362 | public function testSubtractingMinuteFractions() 363 | { 364 | $this->assertEquals(strtotime('-24 seconds'), $this->date->copy()->minusMinutes(0.4)->getTimestamp()); 365 | $this->assertEquals(strtotime('-42 seconds'), $this->date->copy()->minusMinutes(0.7)->getTimestamp()); 366 | } 367 | 368 | 369 | public function testSettingTimezoneDuringRuntime() 370 | { 371 | $this->date->setTimezone('Europe/Paris'); 372 | $this->assertEquals(new DateTimeZone('Europe/Paris'), $this->date->getTimezone()); 373 | } 374 | 375 | 376 | public function testSetTimestampFromString() 377 | { 378 | $this->date->setTimestampFromString('Next week'); 379 | $this->assertEquals(strtotime('Next week'), $this->date->getTimestamp()); 380 | } 381 | 382 | 383 | public function testCanCheckIfDateIsWeekday() 384 | { 385 | $this->assertFalse($this->date->copy()->setTimestampFromString('Sunday')->isWeekday()); 386 | $this->assertTrue($this->date->copy()->setTimestampFromString('Monday')->isWeekday()); 387 | } 388 | 389 | 390 | public function testCanCheckIfDateIsWeekend() 391 | { 392 | $this->assertTrue($this->date->copy()->setTimestampFromString('Sunday')->isWeekend()); 393 | $this->assertFalse($this->date->copy()->setTimestampFromString('Monday')->isWeekend()); 394 | } 395 | 396 | public function testGetDateDifferenceInYears() 397 | { 398 | $past = new ExpressiveDate('January 2010'); 399 | $future = new ExpressiveDate('January 2013'); 400 | $this->assertEquals(-3, $future->getDifferenceInYears($past)); 401 | $this->assertEquals(3, $past->getDifferenceInYears($future)); 402 | } 403 | 404 | 405 | public function testGetDateDifferenceInMonths() 406 | { 407 | $past = new ExpressiveDate('January 2012'); 408 | $future = new ExpressiveDate('December 2013'); 409 | $this->assertEquals(-22, $future->getDifferenceInMonths($past)); 410 | $this->assertEquals(22, $past->getDifferenceInMonths($future)); 411 | } 412 | 413 | 414 | public function testGetDateDifferenceInDays() 415 | { 416 | $past = new ExpressiveDate('January 12'); 417 | $future = new ExpressiveDate('February 15'); 418 | $this->assertEquals(-34, $future->getDifferenceInDays($past)); 419 | $this->assertEquals(34, $past->getDifferenceInDays($future)); 420 | } 421 | 422 | 423 | public function testGetDateDifferenceInHours() 424 | { 425 | $past = new ExpressiveDate('-10 hours'); 426 | $future = new ExpressiveDate('+1 hour'); 427 | $this->assertEquals(-11, $future->getDifferenceInHours($past)); 428 | $this->assertEquals(11, $past->getDifferenceInHours($future)); 429 | } 430 | 431 | 432 | public function testGetDateDifferenceInMinutes() 433 | { 434 | $past = new ExpressiveDate('-10 minutes'); 435 | $future = new ExpressiveDate('+1 minute'); 436 | $this->assertEquals(-11, $future->getDifferenceInMinutes($past)); 437 | $this->assertEquals(11, $past->getDifferenceInMinutes($future)); 438 | } 439 | 440 | 441 | public function testGetDateDifferenceInSeconds() 442 | { 443 | $past = new ExpressiveDate('-1 day'); 444 | $future = new ExpressiveDate('+1 day'); 445 | $this->assertEquals(86400 * 2 * -1, $future->getDifferenceInSeconds($past)); 446 | $this->assertEquals(86400 * 2, $past->getDifferenceInSeconds($future)); 447 | } 448 | 449 | 450 | public function testGetDateAsRelativeDate() 451 | { 452 | $this->date->minusOneDay(); 453 | $this->assertEquals('1 day ago', $this->date->getRelativeDate()); 454 | $this->date->minusDays(2); 455 | $this->assertEquals('3 days ago', $this->date->getRelativeDate()); 456 | $this->date->addDays(4); 457 | $this->assertEquals('1 day from now', $this->date->getRelativeDate()); 458 | $this->date->addMonths(4); 459 | $this->assertEquals('4 months from now', $this->date->getRelativeDate()); 460 | $this->date->minusMonths(5)->minusOneYear(); 461 | $this->assertEquals('1 year ago', $this->date->getRelativeDate()); 462 | $this->date->minusYears(10); 463 | $this->assertEquals('11 years ago', $this->date->getRelativeDate()); 464 | } 465 | 466 | 467 | public function testGetDateString() 468 | { 469 | $this->assertEquals('1991-01-31', $this->date->setTimestampFromString('31 January 1991')->getDate()); 470 | } 471 | 472 | 473 | public function testGetDateTimeString() 474 | { 475 | $this->assertEquals('1991-01-31 00:00:00', $this->date->setTimestampFromString('31 January 1991')->getDateTime()); 476 | } 477 | 478 | 479 | public function testGetShortDateString() 480 | { 481 | $this->assertEquals('Jan 31, 1991', $this->date->setTimestampFromString('31 January 1991')->getShortDate()); 482 | } 483 | 484 | 485 | public function testGetLongDateString() 486 | { 487 | $this->assertEquals('January 31st, 1991 at 12:00am', $this->date->setTimestampFromString('31 January 1991')->getLongDate()); 488 | } 489 | 490 | 491 | public function testGetTimeString() 492 | { 493 | $this->assertEquals('00:00:00', $this->date->setTimestampFromString('31 January 1991')->getTime()); 494 | } 495 | 496 | 497 | public function testGetDayOfWeek() 498 | { 499 | $this->assertEquals('Thursday', $this->date->setTimestampFromString('31 January 1991')->getDayOfWeek()); 500 | } 501 | 502 | 503 | public function testGetDayOfWeekAsNumeric() 504 | { 505 | $this->assertEquals(4, $this->date->setTimestampFromString('31 January 1991')->getDayOfWeekAsNumeric()); 506 | } 507 | 508 | 509 | public function testGetDaysInMonth() 510 | { 511 | $this->assertEquals(31, $this->date->setTimestampFromString('31 January 1991')->getDaysInMonth()); 512 | } 513 | 514 | 515 | public function testGetDayOfYear() 516 | { 517 | $this->assertEquals(30, $this->date->setTimestampFromString('31 January 1991')->getDayOfYear()); 518 | } 519 | 520 | 521 | public function testGetDaySuffix() 522 | { 523 | $this->assertEquals('st', $this->date->setTimestampFromString('31 January 1991')->getDaySuffix()); 524 | } 525 | 526 | 527 | public function testIsLeapYear() 528 | { 529 | $this->assertFalse($this->date->setTimestampFromString('31 January 1991')->isLeapYear()); 530 | } 531 | 532 | 533 | public function testIsAmOrPm() 534 | { 535 | $this->assertEquals('AM', $this->date->setTimestampFromString('31 January 1991')->isAmOrPm()); 536 | } 537 | 538 | 539 | public function testIsDaylightSavings() 540 | { 541 | $this->assertTrue($this->date->setTimestampFromString('31 January 1991')->isDaylightSavings()); 542 | } 543 | 544 | 545 | public function testGetGmtDifference() 546 | { 547 | $this->assertEquals('+1100', $this->date->setTimestampFromString('31 January 1991')->getGmtDifference()); 548 | } 549 | 550 | 551 | public function testSecondsSinceEpoch() 552 | { 553 | $this->date->setTimestampFromString('31 January 1991'); 554 | $this->assertEquals(strtotime('31 January 1991') - strtotime('January 1 1970 00:00:00 GMT'), $this->date->getSecondsSinceEpoch()); 555 | } 556 | 557 | 558 | public function testGetTimezoneName() 559 | { 560 | $date = new ExpressiveDate('31 January 1991'); 561 | $this->assertEquals('Australia/Melbourne', $this->date->setTimestampFromString('31 January 1991')->getTimezoneName()); 562 | } 563 | 564 | 565 | public function testGetDefaultDateFormat() 566 | { 567 | $this->assertEquals('31st January, 1991 at 4:00pm', $this->date->setTimestampFromString('31 January 1991 16:00:00')->getDefaultDate()); 568 | } 569 | 570 | 571 | public function testSetDefaultDateFormat() 572 | { 573 | $this->date->setDefaultDateFormat('j F'); 574 | $this->assertEquals('31 January',$this->date->setTimestampFromString('31 January 1991 16:00:00')->getDefaultDate()); 575 | } 576 | 577 | 578 | public function testDefaultDateUsedOnObjectEcho() 579 | { 580 | $this->assertEquals('31st January, 1991 at 4:00pm', $this->date->setTimestampFromString('31 January 1991 16:00:00')); 581 | } 582 | 583 | 584 | /** 585 | * @expectedException InvalidArgumentException 586 | */ 587 | public function testGettingInvalidDateAttributeThrowsException() 588 | { 589 | $this->date->getInvalidDateAttribute(); 590 | } 591 | 592 | 593 | /** 594 | * @expectedException InvalidArgumentException 595 | */ 596 | public function testSettingInvalidDateAttributeThrowsException() 597 | { 598 | $this->date->setInvalidDateAttribute('foo'); 599 | } 600 | 601 | 602 | public function testCompareDatesEqualTo() 603 | { 604 | $this->assertTrue($this->date->equalTo($this->date->copy())); 605 | $this->assertFalse($this->date->sameAs($this->date->copy()->addOneDay())); 606 | } 607 | 608 | 609 | public function testCompareDatesGreaterThan() 610 | { 611 | $this->assertTrue($this->date->greaterThan($this->date->copy()->minusOneDay())); 612 | $this->assertFalse($this->date->greaterThan($this->date->copy())); 613 | $this->assertFalse($this->date->greaterThan($this->date->copy()->addOneDay())); 614 | } 615 | 616 | 617 | public function testCompareDatesLessThan() 618 | { 619 | $this->assertTrue($this->date->lessThan($this->date->copy()->addOneDay())); 620 | $this->assertFalse($this->date->lessThan($this->date->copy())); 621 | $this->assertFalse($this->date->lessThan($this->date->copy()->minusOneDay())); 622 | } 623 | 624 | 625 | public function testCompareDatesGreaterThanOrEqualTo() 626 | { 627 | $this->assertTrue($this->date->greaterOrEqualTo($this->date->copy()->minusOneDay())); 628 | $this->assertTrue($this->date->greaterOrEqualTo($this->date->copy())); 629 | $this->assertFalse($this->date->greaterOrEqualTo($this->date->copy()->addOneDay())); 630 | } 631 | 632 | 633 | public function testCompareDatesLessThanOrEqualTo() 634 | { 635 | $this->assertTrue($this->date->lessOrEqualTo($this->date->copy()->addOneDay())); 636 | $this->assertTrue($this->date->lessOrEqualTo($this->date->copy())); 637 | $this->assertFalse($this->date->lessOrEqualTo($this->date->copy()->minusOneDay())); 638 | } 639 | 640 | 641 | public function testCopy() 642 | { 643 | $this->assertEquals($this->date, $this->date->copy()); 644 | } 645 | 646 | 647 | } --------------------------------------------------------------------------------