├── .github └── FUNDING.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── composer.json ├── composer.lock ├── phpunit.xml ├── src ├── DateInterval.php └── DateTime.php └── test ├── DateIntervalTest.php └── DateTimeTest.php /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [Alroniks] 2 | patreon: ivanklimchuk 3 | custom: https://money.yandex.ru/to/41001878021446 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | /build 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | addons: 4 | apt_packages: 5 | - parallel 6 | 7 | php: 8 | - 5.3 9 | - 5.4 10 | - 5.5 11 | - 5.6 12 | - 7.0 13 | 14 | before_script: 15 | - composer install --dev 16 | 17 | script: vendor/bin/phpunit 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Ivan Klimchuk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DateTime with Microseconds ![](https://travis-ci.org/Alroniks/dtms.svg) 2 | 3 | DateTime and DateInterval classes with support of microseconds 4 | 5 | ## NOTE! This package not fully tested, so use it with caution. 6 | 7 | This small package with two classes just wrapper around built in PHP classes for work with date and time but with support operations with microseconds. 8 | 9 | ## Installation 10 | 11 | Package use PSR-4 standard, so for using this classes just install package using Composer. 12 | 13 | ```bash 14 | $ composer require alroniks/dtms 15 | ``` 16 | 17 | ```json 18 | { 19 | "require": { 20 | "alroniks/dtms": "~0.5" 21 | } 22 | } 23 | ``` 24 | 25 | ```php 26 | format('Y-m-d H:i:s.u'); // 2015-08-08 10:10:10.123456 41 | ``` 42 | 43 | Also you can modify DateTime with microseconds. Supported words "microseconds", "microsecond", "micro", "mic". 44 | 45 | ```php 46 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 47 | $dt->modify('123456 micro'); 48 | echo $dt->format('u'); // 246912 49 | ``` 50 | 51 | And of course this package allow usage true ISO8601 format for date intervals with microseconds. 52 | 53 | ```php 54 | $interval = new DateInterval('PT2.2S'); 55 | echo $interval->format('PT%sS'); // PT2.200000S 56 | ``` 57 | 58 | Class DateTime support standard methods, such as `add`, `sub`, `diff`, `format` etc. 59 | 60 | For using native DateTime and DateInteval classes together with package use root namespace for it: 61 | 62 | ```php 63 | $uDateTime = new DateTime(); // DateTime from package 64 | $nativeDateTime = new \DateTime(); // built in DateTime 65 | ``` 66 | 67 | __Note!__ Current package may work incorrectly with different time zones, so it need extra check and more tests. 68 | 69 | If you found error or weird behavior, send me [issue report](/issues/new), please. 70 | 71 | ## Credits 72 | 73 | - [Ivan Klimchuk](http://klimchuk.com), [Alroniks](https://github.com/Alroniks) 74 | 75 | ## License 76 | 77 | The MIT License (MIT). Please see [LICENSE](/LICENSE) for more information. 78 | 79 | 80 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alroniks/dtms", 3 | "type": "library", 4 | "description": "Classes for manipulate dates and intervals with microseconds precision", 5 | "keywords": ["date", "time", "datetime", "ms", "microseconds", "milliseconds", "interval", "ISO8601", "fractions"], 6 | "license": "MIT", 7 | "homepage": "http://alroniks.github.io/dtms", 8 | "authors": [ 9 | { 10 | "name": "Ivan Klimchuk", 11 | "email": "ivan@klimchuk.com", 12 | "homepage" : "http://klimchuk.com", 13 | "role" : "Developer" 14 | } 15 | ], 16 | "support": { 17 | "issues": "https://github.com/alroniks/dtms/issues" 18 | }, 19 | "require": { 20 | "php" : ">=5.3.0" 21 | }, 22 | "require-dev": { 23 | "phpunit/phpunit" : "4.*" 24 | }, 25 | "autoload": { 26 | "psr-4": { 27 | "alroniks\\dtms\\": "src" 28 | } 29 | }, 30 | "autoload-dev": { 31 | "psr-4": { 32 | "alroniks\\dtms\\Test\\": "test" 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "hash": "8d564c8aa4255f05770d54baef00aae3", 8 | "packages": [], 9 | "packages-dev": [ 10 | { 11 | "name": "doctrine/instantiator", 12 | "version": "1.0.5", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/doctrine/instantiator.git", 16 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", 21 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "php": ">=5.3,<8.0-DEV" 26 | }, 27 | "require-dev": { 28 | "athletic/athletic": "~0.1.8", 29 | "ext-pdo": "*", 30 | "ext-phar": "*", 31 | "phpunit/phpunit": "~4.0", 32 | "squizlabs/php_codesniffer": "~2.0" 33 | }, 34 | "type": "library", 35 | "extra": { 36 | "branch-alias": { 37 | "dev-master": "1.0.x-dev" 38 | } 39 | }, 40 | "autoload": { 41 | "psr-4": { 42 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 43 | } 44 | }, 45 | "notification-url": "https://packagist.org/downloads/", 46 | "license": [ 47 | "MIT" 48 | ], 49 | "authors": [ 50 | { 51 | "name": "Marco Pivetta", 52 | "email": "ocramius@gmail.com", 53 | "homepage": "http://ocramius.github.com/" 54 | } 55 | ], 56 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 57 | "homepage": "https://github.com/doctrine/instantiator", 58 | "keywords": [ 59 | "constructor", 60 | "instantiate" 61 | ], 62 | "time": "2015-06-14 21:17:01" 63 | }, 64 | { 65 | "name": "phpdocumentor/reflection-docblock", 66 | "version": "2.0.4", 67 | "source": { 68 | "type": "git", 69 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 70 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" 71 | }, 72 | "dist": { 73 | "type": "zip", 74 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", 75 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", 76 | "shasum": "" 77 | }, 78 | "require": { 79 | "php": ">=5.3.3" 80 | }, 81 | "require-dev": { 82 | "phpunit/phpunit": "~4.0" 83 | }, 84 | "suggest": { 85 | "dflydev/markdown": "~1.0", 86 | "erusev/parsedown": "~1.0" 87 | }, 88 | "type": "library", 89 | "extra": { 90 | "branch-alias": { 91 | "dev-master": "2.0.x-dev" 92 | } 93 | }, 94 | "autoload": { 95 | "psr-0": { 96 | "phpDocumentor": [ 97 | "src/" 98 | ] 99 | } 100 | }, 101 | "notification-url": "https://packagist.org/downloads/", 102 | "license": [ 103 | "MIT" 104 | ], 105 | "authors": [ 106 | { 107 | "name": "Mike van Riel", 108 | "email": "mike.vanriel@naenius.com" 109 | } 110 | ], 111 | "time": "2015-02-03 12:10:50" 112 | }, 113 | { 114 | "name": "phpspec/prophecy", 115 | "version": "v1.5.0", 116 | "source": { 117 | "type": "git", 118 | "url": "https://github.com/phpspec/prophecy.git", 119 | "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7" 120 | }, 121 | "dist": { 122 | "type": "zip", 123 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7", 124 | "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7", 125 | "shasum": "" 126 | }, 127 | "require": { 128 | "doctrine/instantiator": "^1.0.2", 129 | "phpdocumentor/reflection-docblock": "~2.0", 130 | "sebastian/comparator": "~1.1" 131 | }, 132 | "require-dev": { 133 | "phpspec/phpspec": "~2.0" 134 | }, 135 | "type": "library", 136 | "extra": { 137 | "branch-alias": { 138 | "dev-master": "1.4.x-dev" 139 | } 140 | }, 141 | "autoload": { 142 | "psr-0": { 143 | "Prophecy\\": "src/" 144 | } 145 | }, 146 | "notification-url": "https://packagist.org/downloads/", 147 | "license": [ 148 | "MIT" 149 | ], 150 | "authors": [ 151 | { 152 | "name": "Konstantin Kudryashov", 153 | "email": "ever.zet@gmail.com", 154 | "homepage": "http://everzet.com" 155 | }, 156 | { 157 | "name": "Marcello Duarte", 158 | "email": "marcello.duarte@gmail.com" 159 | } 160 | ], 161 | "description": "Highly opinionated mocking framework for PHP 5.3+", 162 | "homepage": "https://github.com/phpspec/prophecy", 163 | "keywords": [ 164 | "Double", 165 | "Dummy", 166 | "fake", 167 | "mock", 168 | "spy", 169 | "stub" 170 | ], 171 | "time": "2015-08-13 10:07:40" 172 | }, 173 | { 174 | "name": "phpunit/php-code-coverage", 175 | "version": "2.2.2", 176 | "source": { 177 | "type": "git", 178 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 179 | "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c" 180 | }, 181 | "dist": { 182 | "type": "zip", 183 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2d7c03c0e4e080901b8f33b2897b0577be18a13c", 184 | "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c", 185 | "shasum": "" 186 | }, 187 | "require": { 188 | "php": ">=5.3.3", 189 | "phpunit/php-file-iterator": "~1.3", 190 | "phpunit/php-text-template": "~1.2", 191 | "phpunit/php-token-stream": "~1.3", 192 | "sebastian/environment": "^1.3.2", 193 | "sebastian/version": "~1.0" 194 | }, 195 | "require-dev": { 196 | "ext-xdebug": ">=2.1.4", 197 | "phpunit/phpunit": "~4" 198 | }, 199 | "suggest": { 200 | "ext-dom": "*", 201 | "ext-xdebug": ">=2.2.1", 202 | "ext-xmlwriter": "*" 203 | }, 204 | "type": "library", 205 | "extra": { 206 | "branch-alias": { 207 | "dev-master": "2.2.x-dev" 208 | } 209 | }, 210 | "autoload": { 211 | "classmap": [ 212 | "src/" 213 | ] 214 | }, 215 | "notification-url": "https://packagist.org/downloads/", 216 | "license": [ 217 | "BSD-3-Clause" 218 | ], 219 | "authors": [ 220 | { 221 | "name": "Sebastian Bergmann", 222 | "email": "sb@sebastian-bergmann.de", 223 | "role": "lead" 224 | } 225 | ], 226 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 227 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 228 | "keywords": [ 229 | "coverage", 230 | "testing", 231 | "xunit" 232 | ], 233 | "time": "2015-08-04 03:42:39" 234 | }, 235 | { 236 | "name": "phpunit/php-file-iterator", 237 | "version": "1.4.1", 238 | "source": { 239 | "type": "git", 240 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 241 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" 242 | }, 243 | "dist": { 244 | "type": "zip", 245 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 246 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 247 | "shasum": "" 248 | }, 249 | "require": { 250 | "php": ">=5.3.3" 251 | }, 252 | "type": "library", 253 | "extra": { 254 | "branch-alias": { 255 | "dev-master": "1.4.x-dev" 256 | } 257 | }, 258 | "autoload": { 259 | "classmap": [ 260 | "src/" 261 | ] 262 | }, 263 | "notification-url": "https://packagist.org/downloads/", 264 | "license": [ 265 | "BSD-3-Clause" 266 | ], 267 | "authors": [ 268 | { 269 | "name": "Sebastian Bergmann", 270 | "email": "sb@sebastian-bergmann.de", 271 | "role": "lead" 272 | } 273 | ], 274 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 275 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 276 | "keywords": [ 277 | "filesystem", 278 | "iterator" 279 | ], 280 | "time": "2015-06-21 13:08:43" 281 | }, 282 | { 283 | "name": "phpunit/php-text-template", 284 | "version": "1.2.1", 285 | "source": { 286 | "type": "git", 287 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 288 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 289 | }, 290 | "dist": { 291 | "type": "zip", 292 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 293 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 294 | "shasum": "" 295 | }, 296 | "require": { 297 | "php": ">=5.3.3" 298 | }, 299 | "type": "library", 300 | "autoload": { 301 | "classmap": [ 302 | "src/" 303 | ] 304 | }, 305 | "notification-url": "https://packagist.org/downloads/", 306 | "license": [ 307 | "BSD-3-Clause" 308 | ], 309 | "authors": [ 310 | { 311 | "name": "Sebastian Bergmann", 312 | "email": "sebastian@phpunit.de", 313 | "role": "lead" 314 | } 315 | ], 316 | "description": "Simple template engine.", 317 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 318 | "keywords": [ 319 | "template" 320 | ], 321 | "time": "2015-06-21 13:50:34" 322 | }, 323 | { 324 | "name": "phpunit/php-timer", 325 | "version": "1.0.7", 326 | "source": { 327 | "type": "git", 328 | "url": "https://github.com/sebastianbergmann/php-timer.git", 329 | "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" 330 | }, 331 | "dist": { 332 | "type": "zip", 333 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", 334 | "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", 335 | "shasum": "" 336 | }, 337 | "require": { 338 | "php": ">=5.3.3" 339 | }, 340 | "type": "library", 341 | "autoload": { 342 | "classmap": [ 343 | "src/" 344 | ] 345 | }, 346 | "notification-url": "https://packagist.org/downloads/", 347 | "license": [ 348 | "BSD-3-Clause" 349 | ], 350 | "authors": [ 351 | { 352 | "name": "Sebastian Bergmann", 353 | "email": "sb@sebastian-bergmann.de", 354 | "role": "lead" 355 | } 356 | ], 357 | "description": "Utility class for timing", 358 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 359 | "keywords": [ 360 | "timer" 361 | ], 362 | "time": "2015-06-21 08:01:12" 363 | }, 364 | { 365 | "name": "phpunit/php-token-stream", 366 | "version": "1.4.6", 367 | "source": { 368 | "type": "git", 369 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 370 | "reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b" 371 | }, 372 | "dist": { 373 | "type": "zip", 374 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3ab72c62e550370a6cd5dc873e1a04ab57562f5b", 375 | "reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b", 376 | "shasum": "" 377 | }, 378 | "require": { 379 | "ext-tokenizer": "*", 380 | "php": ">=5.3.3" 381 | }, 382 | "require-dev": { 383 | "phpunit/phpunit": "~4.2" 384 | }, 385 | "type": "library", 386 | "extra": { 387 | "branch-alias": { 388 | "dev-master": "1.4-dev" 389 | } 390 | }, 391 | "autoload": { 392 | "classmap": [ 393 | "src/" 394 | ] 395 | }, 396 | "notification-url": "https://packagist.org/downloads/", 397 | "license": [ 398 | "BSD-3-Clause" 399 | ], 400 | "authors": [ 401 | { 402 | "name": "Sebastian Bergmann", 403 | "email": "sebastian@phpunit.de" 404 | } 405 | ], 406 | "description": "Wrapper around PHP's tokenizer extension.", 407 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 408 | "keywords": [ 409 | "tokenizer" 410 | ], 411 | "time": "2015-08-16 08:51:00" 412 | }, 413 | { 414 | "name": "phpunit/phpunit", 415 | "version": "4.8.6", 416 | "source": { 417 | "type": "git", 418 | "url": "https://github.com/sebastianbergmann/phpunit.git", 419 | "reference": "2246830f4a1a551c67933e4171bf2126dc29d357" 420 | }, 421 | "dist": { 422 | "type": "zip", 423 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2246830f4a1a551c67933e4171bf2126dc29d357", 424 | "reference": "2246830f4a1a551c67933e4171bf2126dc29d357", 425 | "shasum": "" 426 | }, 427 | "require": { 428 | "ext-dom": "*", 429 | "ext-json": "*", 430 | "ext-pcre": "*", 431 | "ext-reflection": "*", 432 | "ext-spl": "*", 433 | "php": ">=5.3.3", 434 | "phpspec/prophecy": "^1.3.1", 435 | "phpunit/php-code-coverage": "~2.1", 436 | "phpunit/php-file-iterator": "~1.4", 437 | "phpunit/php-text-template": "~1.2", 438 | "phpunit/php-timer": ">=1.0.6", 439 | "phpunit/phpunit-mock-objects": "~2.3", 440 | "sebastian/comparator": "~1.1", 441 | "sebastian/diff": "~1.2", 442 | "sebastian/environment": "~1.3", 443 | "sebastian/exporter": "~1.2", 444 | "sebastian/global-state": "~1.0", 445 | "sebastian/version": "~1.0", 446 | "symfony/yaml": "~2.1|~3.0" 447 | }, 448 | "suggest": { 449 | "phpunit/php-invoker": "~1.1" 450 | }, 451 | "bin": [ 452 | "phpunit" 453 | ], 454 | "type": "library", 455 | "extra": { 456 | "branch-alias": { 457 | "dev-master": "4.8.x-dev" 458 | } 459 | }, 460 | "autoload": { 461 | "classmap": [ 462 | "src/" 463 | ] 464 | }, 465 | "notification-url": "https://packagist.org/downloads/", 466 | "license": [ 467 | "BSD-3-Clause" 468 | ], 469 | "authors": [ 470 | { 471 | "name": "Sebastian Bergmann", 472 | "email": "sebastian@phpunit.de", 473 | "role": "lead" 474 | } 475 | ], 476 | "description": "The PHP Unit Testing framework.", 477 | "homepage": "https://phpunit.de/", 478 | "keywords": [ 479 | "phpunit", 480 | "testing", 481 | "xunit" 482 | ], 483 | "time": "2015-08-24 04:09:38" 484 | }, 485 | { 486 | "name": "phpunit/phpunit-mock-objects", 487 | "version": "2.3.7", 488 | "source": { 489 | "type": "git", 490 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 491 | "reference": "5e2645ad49d196e020b85598d7c97e482725786a" 492 | }, 493 | "dist": { 494 | "type": "zip", 495 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/5e2645ad49d196e020b85598d7c97e482725786a", 496 | "reference": "5e2645ad49d196e020b85598d7c97e482725786a", 497 | "shasum": "" 498 | }, 499 | "require": { 500 | "doctrine/instantiator": "^1.0.2", 501 | "php": ">=5.3.3", 502 | "phpunit/php-text-template": "~1.2", 503 | "sebastian/exporter": "~1.2" 504 | }, 505 | "require-dev": { 506 | "phpunit/phpunit": "~4.4" 507 | }, 508 | "suggest": { 509 | "ext-soap": "*" 510 | }, 511 | "type": "library", 512 | "extra": { 513 | "branch-alias": { 514 | "dev-master": "2.3.x-dev" 515 | } 516 | }, 517 | "autoload": { 518 | "classmap": [ 519 | "src/" 520 | ] 521 | }, 522 | "notification-url": "https://packagist.org/downloads/", 523 | "license": [ 524 | "BSD-3-Clause" 525 | ], 526 | "authors": [ 527 | { 528 | "name": "Sebastian Bergmann", 529 | "email": "sb@sebastian-bergmann.de", 530 | "role": "lead" 531 | } 532 | ], 533 | "description": "Mock Object library for PHPUnit", 534 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 535 | "keywords": [ 536 | "mock", 537 | "xunit" 538 | ], 539 | "time": "2015-08-19 09:14:08" 540 | }, 541 | { 542 | "name": "sebastian/comparator", 543 | "version": "1.2.0", 544 | "source": { 545 | "type": "git", 546 | "url": "https://github.com/sebastianbergmann/comparator.git", 547 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" 548 | }, 549 | "dist": { 550 | "type": "zip", 551 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", 552 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", 553 | "shasum": "" 554 | }, 555 | "require": { 556 | "php": ">=5.3.3", 557 | "sebastian/diff": "~1.2", 558 | "sebastian/exporter": "~1.2" 559 | }, 560 | "require-dev": { 561 | "phpunit/phpunit": "~4.4" 562 | }, 563 | "type": "library", 564 | "extra": { 565 | "branch-alias": { 566 | "dev-master": "1.2.x-dev" 567 | } 568 | }, 569 | "autoload": { 570 | "classmap": [ 571 | "src/" 572 | ] 573 | }, 574 | "notification-url": "https://packagist.org/downloads/", 575 | "license": [ 576 | "BSD-3-Clause" 577 | ], 578 | "authors": [ 579 | { 580 | "name": "Jeff Welch", 581 | "email": "whatthejeff@gmail.com" 582 | }, 583 | { 584 | "name": "Volker Dusch", 585 | "email": "github@wallbash.com" 586 | }, 587 | { 588 | "name": "Bernhard Schussek", 589 | "email": "bschussek@2bepublished.at" 590 | }, 591 | { 592 | "name": "Sebastian Bergmann", 593 | "email": "sebastian@phpunit.de" 594 | } 595 | ], 596 | "description": "Provides the functionality to compare PHP values for equality", 597 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 598 | "keywords": [ 599 | "comparator", 600 | "compare", 601 | "equality" 602 | ], 603 | "time": "2015-07-26 15:48:44" 604 | }, 605 | { 606 | "name": "sebastian/diff", 607 | "version": "1.3.0", 608 | "source": { 609 | "type": "git", 610 | "url": "https://github.com/sebastianbergmann/diff.git", 611 | "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" 612 | }, 613 | "dist": { 614 | "type": "zip", 615 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", 616 | "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", 617 | "shasum": "" 618 | }, 619 | "require": { 620 | "php": ">=5.3.3" 621 | }, 622 | "require-dev": { 623 | "phpunit/phpunit": "~4.2" 624 | }, 625 | "type": "library", 626 | "extra": { 627 | "branch-alias": { 628 | "dev-master": "1.3-dev" 629 | } 630 | }, 631 | "autoload": { 632 | "classmap": [ 633 | "src/" 634 | ] 635 | }, 636 | "notification-url": "https://packagist.org/downloads/", 637 | "license": [ 638 | "BSD-3-Clause" 639 | ], 640 | "authors": [ 641 | { 642 | "name": "Kore Nordmann", 643 | "email": "mail@kore-nordmann.de" 644 | }, 645 | { 646 | "name": "Sebastian Bergmann", 647 | "email": "sebastian@phpunit.de" 648 | } 649 | ], 650 | "description": "Diff implementation", 651 | "homepage": "http://www.github.com/sebastianbergmann/diff", 652 | "keywords": [ 653 | "diff" 654 | ], 655 | "time": "2015-02-22 15:13:53" 656 | }, 657 | { 658 | "name": "sebastian/environment", 659 | "version": "1.3.2", 660 | "source": { 661 | "type": "git", 662 | "url": "https://github.com/sebastianbergmann/environment.git", 663 | "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44" 664 | }, 665 | "dist": { 666 | "type": "zip", 667 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44", 668 | "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44", 669 | "shasum": "" 670 | }, 671 | "require": { 672 | "php": ">=5.3.3" 673 | }, 674 | "require-dev": { 675 | "phpunit/phpunit": "~4.4" 676 | }, 677 | "type": "library", 678 | "extra": { 679 | "branch-alias": { 680 | "dev-master": "1.3.x-dev" 681 | } 682 | }, 683 | "autoload": { 684 | "classmap": [ 685 | "src/" 686 | ] 687 | }, 688 | "notification-url": "https://packagist.org/downloads/", 689 | "license": [ 690 | "BSD-3-Clause" 691 | ], 692 | "authors": [ 693 | { 694 | "name": "Sebastian Bergmann", 695 | "email": "sebastian@phpunit.de" 696 | } 697 | ], 698 | "description": "Provides functionality to handle HHVM/PHP environments", 699 | "homepage": "http://www.github.com/sebastianbergmann/environment", 700 | "keywords": [ 701 | "Xdebug", 702 | "environment", 703 | "hhvm" 704 | ], 705 | "time": "2015-08-03 06:14:51" 706 | }, 707 | { 708 | "name": "sebastian/exporter", 709 | "version": "1.2.1", 710 | "source": { 711 | "type": "git", 712 | "url": "https://github.com/sebastianbergmann/exporter.git", 713 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e" 714 | }, 715 | "dist": { 716 | "type": "zip", 717 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", 718 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e", 719 | "shasum": "" 720 | }, 721 | "require": { 722 | "php": ">=5.3.3", 723 | "sebastian/recursion-context": "~1.0" 724 | }, 725 | "require-dev": { 726 | "phpunit/phpunit": "~4.4" 727 | }, 728 | "type": "library", 729 | "extra": { 730 | "branch-alias": { 731 | "dev-master": "1.2.x-dev" 732 | } 733 | }, 734 | "autoload": { 735 | "classmap": [ 736 | "src/" 737 | ] 738 | }, 739 | "notification-url": "https://packagist.org/downloads/", 740 | "license": [ 741 | "BSD-3-Clause" 742 | ], 743 | "authors": [ 744 | { 745 | "name": "Jeff Welch", 746 | "email": "whatthejeff@gmail.com" 747 | }, 748 | { 749 | "name": "Volker Dusch", 750 | "email": "github@wallbash.com" 751 | }, 752 | { 753 | "name": "Bernhard Schussek", 754 | "email": "bschussek@2bepublished.at" 755 | }, 756 | { 757 | "name": "Sebastian Bergmann", 758 | "email": "sebastian@phpunit.de" 759 | }, 760 | { 761 | "name": "Adam Harvey", 762 | "email": "aharvey@php.net" 763 | } 764 | ], 765 | "description": "Provides the functionality to export PHP variables for visualization", 766 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 767 | "keywords": [ 768 | "export", 769 | "exporter" 770 | ], 771 | "time": "2015-06-21 07:55:53" 772 | }, 773 | { 774 | "name": "sebastian/global-state", 775 | "version": "1.0.0", 776 | "source": { 777 | "type": "git", 778 | "url": "https://github.com/sebastianbergmann/global-state.git", 779 | "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" 780 | }, 781 | "dist": { 782 | "type": "zip", 783 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", 784 | "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", 785 | "shasum": "" 786 | }, 787 | "require": { 788 | "php": ">=5.3.3" 789 | }, 790 | "require-dev": { 791 | "phpunit/phpunit": "~4.2" 792 | }, 793 | "suggest": { 794 | "ext-uopz": "*" 795 | }, 796 | "type": "library", 797 | "extra": { 798 | "branch-alias": { 799 | "dev-master": "1.0-dev" 800 | } 801 | }, 802 | "autoload": { 803 | "classmap": [ 804 | "src/" 805 | ] 806 | }, 807 | "notification-url": "https://packagist.org/downloads/", 808 | "license": [ 809 | "BSD-3-Clause" 810 | ], 811 | "authors": [ 812 | { 813 | "name": "Sebastian Bergmann", 814 | "email": "sebastian@phpunit.de" 815 | } 816 | ], 817 | "description": "Snapshotting of global state", 818 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 819 | "keywords": [ 820 | "global state" 821 | ], 822 | "time": "2014-10-06 09:23:50" 823 | }, 824 | { 825 | "name": "sebastian/recursion-context", 826 | "version": "1.0.1", 827 | "source": { 828 | "type": "git", 829 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 830 | "reference": "994d4a811bafe801fb06dccbee797863ba2792ba" 831 | }, 832 | "dist": { 833 | "type": "zip", 834 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/994d4a811bafe801fb06dccbee797863ba2792ba", 835 | "reference": "994d4a811bafe801fb06dccbee797863ba2792ba", 836 | "shasum": "" 837 | }, 838 | "require": { 839 | "php": ">=5.3.3" 840 | }, 841 | "require-dev": { 842 | "phpunit/phpunit": "~4.4" 843 | }, 844 | "type": "library", 845 | "extra": { 846 | "branch-alias": { 847 | "dev-master": "1.0.x-dev" 848 | } 849 | }, 850 | "autoload": { 851 | "classmap": [ 852 | "src/" 853 | ] 854 | }, 855 | "notification-url": "https://packagist.org/downloads/", 856 | "license": [ 857 | "BSD-3-Clause" 858 | ], 859 | "authors": [ 860 | { 861 | "name": "Jeff Welch", 862 | "email": "whatthejeff@gmail.com" 863 | }, 864 | { 865 | "name": "Sebastian Bergmann", 866 | "email": "sebastian@phpunit.de" 867 | }, 868 | { 869 | "name": "Adam Harvey", 870 | "email": "aharvey@php.net" 871 | } 872 | ], 873 | "description": "Provides functionality to recursively process PHP variables", 874 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 875 | "time": "2015-06-21 08:04:50" 876 | }, 877 | { 878 | "name": "sebastian/version", 879 | "version": "1.0.6", 880 | "source": { 881 | "type": "git", 882 | "url": "https://github.com/sebastianbergmann/version.git", 883 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" 884 | }, 885 | "dist": { 886 | "type": "zip", 887 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 888 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 889 | "shasum": "" 890 | }, 891 | "type": "library", 892 | "autoload": { 893 | "classmap": [ 894 | "src/" 895 | ] 896 | }, 897 | "notification-url": "https://packagist.org/downloads/", 898 | "license": [ 899 | "BSD-3-Clause" 900 | ], 901 | "authors": [ 902 | { 903 | "name": "Sebastian Bergmann", 904 | "email": "sebastian@phpunit.de", 905 | "role": "lead" 906 | } 907 | ], 908 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 909 | "homepage": "https://github.com/sebastianbergmann/version", 910 | "time": "2015-06-21 13:59:46" 911 | }, 912 | { 913 | "name": "symfony/yaml", 914 | "version": "v2.7.3", 915 | "source": { 916 | "type": "git", 917 | "url": "https://github.com/symfony/Yaml.git", 918 | "reference": "71340e996171474a53f3d29111d046be4ad8a0ff" 919 | }, 920 | "dist": { 921 | "type": "zip", 922 | "url": "https://api.github.com/repos/symfony/Yaml/zipball/71340e996171474a53f3d29111d046be4ad8a0ff", 923 | "reference": "71340e996171474a53f3d29111d046be4ad8a0ff", 924 | "shasum": "" 925 | }, 926 | "require": { 927 | "php": ">=5.3.9" 928 | }, 929 | "require-dev": { 930 | "symfony/phpunit-bridge": "~2.7" 931 | }, 932 | "type": "library", 933 | "extra": { 934 | "branch-alias": { 935 | "dev-master": "2.7-dev" 936 | } 937 | }, 938 | "autoload": { 939 | "psr-4": { 940 | "Symfony\\Component\\Yaml\\": "" 941 | } 942 | }, 943 | "notification-url": "https://packagist.org/downloads/", 944 | "license": [ 945 | "MIT" 946 | ], 947 | "authors": [ 948 | { 949 | "name": "Fabien Potencier", 950 | "email": "fabien@symfony.com" 951 | }, 952 | { 953 | "name": "Symfony Community", 954 | "homepage": "https://symfony.com/contributors" 955 | } 956 | ], 957 | "description": "Symfony Yaml Component", 958 | "homepage": "https://symfony.com", 959 | "time": "2015-07-28 14:07:07" 960 | } 961 | ], 962 | "aliases": [], 963 | "minimum-stability": "stable", 964 | "stability-flags": [], 965 | "prefer-stable": false, 966 | "prefer-lowest": false, 967 | "platform": { 968 | "php": ">=5.3.0" 969 | }, 970 | "platform-dev": [] 971 | } 972 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | 15 | 16 | test 17 | 18 | 19 | 20 | 21 | 22 | src/ 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/DateInterval.php: -------------------------------------------------------------------------------- 1 | u = $u; 33 | $this->invert = $invert; 34 | 35 | return $this; 36 | } 37 | 38 | /** 39 | * @param $format 40 | * @return mixed|string 41 | */ 42 | public function format($format) 43 | { 44 | $formatted = parent::format($format); 45 | 46 | if ($this instanceof DateInterval 47 | && property_exists($this, 'u') 48 | && $this->u != 0 49 | ) { 50 | $formatted = preg_replace( 51 | '/([0-9]{1,2})S/', 52 | "$1." . str_pad($this->u, 6, 0, STR_PAD_LEFT) . 'S', 53 | $formatted 54 | ); 55 | } 56 | 57 | return $formatted; 58 | } 59 | 60 | /** 61 | * @param string $time 62 | * @return \DateInterval 63 | */ 64 | public static function createFromDateString($time) 65 | { 66 | $interval = parent::createFromDateString($time); 67 | $interval->u = 0; // should be implemented 68 | 69 | return $interval; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/DateTime.php: -------------------------------------------------------------------------------- 1 | microseconds = intval($microseconds); 27 | } 28 | 29 | /** 30 | * Gets microseconds data from object 31 | * 32 | * @param boolean $asSeconds If defined, microseconds will be converted to seconds with fractions 33 | * @return int|float 34 | */ 35 | public function getMicroseconds($asSeconds = false) 36 | { 37 | if ($asSeconds) { 38 | return round($this->microseconds * 1/1e6, 6); 39 | } 40 | 41 | return intval($this->microseconds); 42 | } 43 | 44 | /** 45 | * Parse a string into a new DateTime object according to the specified format 46 | * 47 | * @param string $format 48 | * @param string $time 49 | * @param null $timezone 50 | * @return DateTime|\DateTime 51 | */ 52 | public static function createFromFormat($format, $time, $timezone = null) 53 | { 54 | if ($timezone === null) { 55 | $timezone = new DateTimeZone(date_default_timezone_get()); 56 | } 57 | 58 | $datetime = \DateTime::createFromFormat($format, $time, $timezone); 59 | 60 | return new self($datetime->format(DateTime::ISO8601), $timezone); 61 | } 62 | 63 | /** 64 | * Instantiates custom DateTime object with support of microseconds. 65 | * 66 | * @param string $time 67 | * @param DateTimeZone|null $timezone 68 | */ 69 | public function __construct($time = 'now', \DateTimeZone $timezone = null) 70 | { 71 | if ($timezone === null) { 72 | $timezone = new DateTimeZone(date_default_timezone_get()); 73 | } 74 | 75 | $nativeTime = new \DateTime($time, $timezone); 76 | list($u, $s) = $time == 'now' 77 | ? explode(' ', microtime()) 78 | : array( 79 | $nativeTime->format('u') / 1e6, 80 | $nativeTime->getTimestamp() 81 | ); 82 | 83 | $time = \DateTime::createFromFormat('U.u', join('.', array($s, str_replace('0.', '', sprintf('%6f', $u))))); 84 | $this->microseconds = $time->format('u') ?: 0; 85 | 86 | return parent::__construct($time->format(static::ISO8601), $timezone); 87 | } 88 | 89 | /** 90 | * Gets the Unix timestamp in seconds with microseconds. 91 | * 92 | * @return int 93 | */ 94 | public function getTimestampWithMicroseconds() 95 | { 96 | return $this->getTimestamp() + $this->getMicroseconds(true); 97 | } 98 | 99 | /** 100 | * Subtracts an amount of microseconds from a DateTime object 101 | * 102 | * @param $microseconds 103 | */ 104 | protected function addMicroseconds($microseconds) 105 | { 106 | if ($microseconds < 0) { 107 | throw new \InvalidArgumentException("Value of microseconds should be positive."); 108 | } 109 | 110 | $diff = $this->getMicroseconds() + $microseconds; 111 | $seconds = floor($diff / 1e6); 112 | $diff -= $seconds * 1e6; 113 | 114 | if ($diff >= 1e6) { 115 | $diff -= 1e6; 116 | $seconds++; 117 | } 118 | 119 | $this->modify("+$seconds seconds"); 120 | $this->setMicroseconds($diff); 121 | } 122 | 123 | /** 124 | * Adds an amount of microseconds to a DateTime object 125 | * 126 | * @param $microseconds 127 | */ 128 | protected function subMicroseconds($microseconds) 129 | { 130 | if ($microseconds < 0) { 131 | throw new \InvalidArgumentException("Value of microseconds should be positive."); 132 | } 133 | 134 | $diff = $this->getMicroseconds() - $microseconds; 135 | $seconds = floor($diff / 1e6); 136 | $diff -= $seconds * 1e6; 137 | 138 | if ($diff < 0) { 139 | $diff = abs($diff); 140 | $seconds++; 141 | } 142 | 143 | $this->modify("$seconds seconds"); 144 | $this->setMicroseconds($diff); 145 | } 146 | 147 | /** 148 | * Adds an amount of days, months, years, hours, minutes, seconds and microseconds to a DateTime object 149 | * 150 | * @param DateInterval $interval 151 | * @return DateTime $this 152 | */ 153 | public function add($interval) 154 | { 155 | parent::add($interval); 156 | 157 | if ($interval instanceof DateInterval) { 158 | if ($interval->invert) { // is negative, then sub 159 | $this->subMicroseconds($interval->u); 160 | } else { 161 | $this->addMicroseconds($interval->u); 162 | } 163 | } 164 | 165 | return $this; 166 | } 167 | 168 | /** 169 | * Subtracts an amount of days, months, years, hours, minutes and seconds from a DateTime object 170 | * 171 | * @param DateInterval $interval 172 | * @return DateTime $this 173 | */ 174 | public function sub($interval) 175 | { 176 | parent::sub($interval); 177 | 178 | if ($interval instanceof DateInterval) { 179 | if ($interval->invert) { 180 | $this->addMicroseconds($interval->u); 181 | } else { 182 | $this->subMicroseconds($interval->u); 183 | } 184 | } 185 | 186 | return $this; 187 | } 188 | 189 | /** 190 | * Alter the timestamp of a DateTime object by incrementing or decrementing in a format accepted by strtotime(). 191 | * Added support for microseconds: (+|-)10 mic|micro|microsecond|microseconds 192 | * 193 | * @param string $modify 194 | * @return \DateTime 195 | */ 196 | public function modify($modify) 197 | { 198 | if (preg_match('/(\+|-)([0-9]+)(?:\s?)(?:microseconds|microsecond|micro|mic)$/', $modify, $matches)) { 199 | $modify = str_replace($matches[0], '', $modify); 200 | $number = intval($matches[2]); 201 | switch ($matches[1]) { 202 | case '-': 203 | $this->subMicroseconds($number); 204 | break; 205 | case '+': 206 | $this->addMicroseconds($number); 207 | break; 208 | } 209 | } 210 | 211 | if (!$modify) { 212 | $modify = '0 seconds'; 213 | } 214 | 215 | return parent::modify($modify); 216 | } 217 | 218 | /** 219 | * Returns the difference between two DateTime objects represented as a DateInterval. 220 | * 221 | * @param \DateTime $datetime 222 | * @param bool|false $absolute 223 | * @return DateInterval 224 | */ 225 | public function diff($datetime, $absolute = false) 226 | { 227 | $d1 = clone $this; 228 | $d2 = $datetime instanceof \DateTime ? new static($datetime->format(DateTime::ISO8601)) : clone $datetime; 229 | 230 | $interval = new DateInterval('PT0.000000S'); 231 | foreach (get_object_vars(parent::diff($datetime)) as $property => $value) { 232 | $interval->{$property} = $value; 233 | } 234 | $interval->s = 0; 235 | 236 | $negative = $d1->getTimestampWithMicroseconds() > $d2->getTimestampWithMicroseconds(); 237 | $diff = abs($d1->getTimestampWithMicroseconds() - $d2->getTimestampWithMicroseconds()); 238 | 239 | $seconds = intval($diff); 240 | $microseconds = round($diff - $seconds, 6) * 1e6; 241 | 242 | $now = new \DateTime('now'); 243 | $start = $now->getTimestamp(); 244 | 245 | $operation = $negative ? 'sub' : 'add'; 246 | $now->$operation($interval); 247 | 248 | $end = $now->getTimestamp(); 249 | $antiseconds = abs($end - $start); 250 | 251 | $interval->s = $seconds - $antiseconds; 252 | $interval->u = $microseconds; 253 | $interval->invert = $absolute ? false : $negative; 254 | 255 | return $interval; 256 | } 257 | 258 | /** 259 | * Returns date formatted according to given format. 260 | * 261 | * @param string $format 262 | * @return string 263 | */ 264 | public function format($format) 265 | { 266 | $format = str_replace('u', sprintf('%06d', $this->microseconds), $format); 267 | 268 | return parent::format($format); 269 | } 270 | 271 | /** 272 | * Converts DateTime object to string using ISO8601 format. 273 | * 274 | * @return string 275 | */ 276 | public function __toString() 277 | { 278 | return $this->format(static::ISO8601); 279 | } 280 | } 281 | -------------------------------------------------------------------------------- /test/DateIntervalTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf('alroniks\\dtms\\DateInterval', $interval); 33 | $this->assertEquals('PT2S', $interval->format('PT%sS')); 34 | 35 | // with microseconds 36 | $interval = new DateInterval('PT2.2S'); 37 | $this->assertInstanceOf('alroniks\\dtms\\DateInterval', $interval); 38 | $this->assertEquals('PT2.200000S', $interval->format('PT%sS')); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/DateTimeTest.php: -------------------------------------------------------------------------------- 1 | getMethod($methodName); 24 | $method->setAccessible(true); 25 | 26 | return $method->invokeArgs($object, $parameters); 27 | } 28 | 29 | /** 30 | * @covers alroniks\dtms\DateTime::getMicroseconds 31 | */ 32 | public function testSetMicroseconds() 33 | { 34 | $dt = new DateTime(); 35 | $dt->setMicroseconds(123456); 36 | $this->assertSame(123456, $dt->microseconds); 37 | $dt->setMicroseconds('123456'); 38 | $this->assertSame(123456, $dt->microseconds); 39 | 40 | $dt->setMicroseconds(654); 41 | $this->assertSame(654, $dt->microseconds); 42 | 43 | $dt->setMicroseconds('987000'); 44 | $this->assertSame(987000, $dt->microseconds); 45 | 46 | $dt->setMicroseconds('000123'); 47 | $this->assertSame(123, $dt->microseconds); 48 | } 49 | 50 | /** 51 | * @covers alroniks\dtms\DateTime::getMicroseconds 52 | */ 53 | public function testGetMicroseconds() 54 | { 55 | $dt = new DateTime(); 56 | $dt->microseconds = 123456; 57 | $this->assertSame(123456, $dt->getMicroseconds()); 58 | $this->assertSame(0.123456, $dt->getMicroseconds(true)); 59 | 60 | $dt->microseconds = 456; 61 | $this->assertSame(456, $dt->getMicroseconds()); 62 | $this->assertSame(0.000456, $dt->getMicroseconds(true)); 63 | } 64 | 65 | /** 66 | * @covers alroniks\dtms\DateTime::createFromFormat 67 | */ 68 | public function testCreateFromFormat() 69 | { 70 | $dt1 = new DateTime('2015-08-08 10:10:10.123456'); 71 | $dt2 = DateTime::createFromFormat(DateTime::ISO8601, '2015-08-08T10:10:10.123456Z'); 72 | 73 | $this->assertEquals($dt1, $dt2); 74 | } 75 | 76 | /** 77 | * @covers alroniks\dtms\DateTime::__construct 78 | */ 79 | public function testConstruct() 80 | { 81 | $dt = new DateTime(); 82 | $this->assertInstanceOf('alroniks\\dtms\\DateTime', $dt); 83 | $this->assertObjectHasAttribute('microseconds', $dt); 84 | 85 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 86 | $this->assertSame(123456, $dt->getMicroseconds()); 87 | } 88 | 89 | /** 90 | * @covers alroniks\dtms\DateTime::getTimestampWithMicroseconds 91 | */ 92 | public function testGetTimestampWithMicroseconds() 93 | { 94 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 95 | $this->assertSame(1439028610 + 123456 / 1e6, $dt->getTimestampWithMicroseconds()); 96 | } 97 | 98 | /** 99 | * @covers alroniks\dtms\DateTime::addMicroseconds 100 | */ 101 | public function testAddMicroseconds() 102 | { 103 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 104 | $this->invokeMethod($dt, 'addMicroseconds', array(0)); 105 | $this->assertEquals('1439028610.123456', $dt->format('U.u')); 106 | 107 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 108 | $this->invokeMethod($dt, 'addMicroseconds', array(123456)); 109 | $this->assertEquals('1439028610.246912', $dt->format('U.u')); 110 | 111 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 112 | $this->invokeMethod($dt, 'addMicroseconds', array(999999)); 113 | $this->assertEquals('1439028611.123455', $dt->format('U.u')); 114 | 115 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 116 | $this->invokeMethod($dt, 'addMicroseconds', array(876544)); 117 | $this->assertEquals('1439028611.000000', $dt->format('U.u')); 118 | 119 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 120 | $this->invokeMethod($dt, 'addMicroseconds', array(1876544)); 121 | $this->assertEquals('1439028612.000000', $dt->format('U.u')); 122 | 123 | $this->setExpectedException( 124 | 'InvalidArgumentException', 'Value of microseconds should be positive.' 125 | ); 126 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 127 | $this->invokeMethod($dt, 'addMicroseconds', array(-111111)); 128 | } 129 | 130 | /** 131 | * @covers alroniks\dtms\DateTime::subMicroseconds 132 | */ 133 | public function testSubMicroseconds() 134 | { 135 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 136 | $this->invokeMethod($dt, 'subMicroseconds', array(0)); 137 | $this->assertEquals('1439028610.123456', $dt->format('U.u')); 138 | 139 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 140 | $this->invokeMethod($dt, 'subMicroseconds', array(12345)); 141 | $this->assertEquals('1439028610.111111', $dt->format('U.u')); 142 | 143 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 144 | $this->invokeMethod($dt, 'subMicroseconds', array(654321)); 145 | $this->assertEquals('1439028609.469135', $dt->format('U.u')); 146 | 147 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 148 | $this->invokeMethod($dt, 'subMicroseconds', array(123456)); 149 | $this->assertEquals('1439028610.000000', $dt->format('U.u')); 150 | 151 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 152 | $this->invokeMethod($dt, 'subMicroseconds', array(1123456)); 153 | $this->assertEquals('1439028609.000000', $dt->format('U.u')); 154 | 155 | $this->setExpectedException( 156 | 'InvalidArgumentException', 'Value of microseconds should be positive.' 157 | ); 158 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 159 | $this->invokeMethod($dt, 'subMicroseconds', array(-111111)); 160 | } 161 | 162 | /** 163 | * @covers alroniks\dtms\DateTime::add 164 | */ 165 | public function testAdd() 166 | { 167 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 168 | $dt->add(new DateInterval('PT0.000000S')); 169 | $this->assertEquals('1439028610.123456', $dt->format('U.u')); 170 | 171 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 172 | $dt->add(new DateInterval('PT1.123456S')); 173 | $this->assertEquals('1439028611.246912', $dt->format('U.u')); 174 | 175 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 176 | $dt->add(new DateInterval('PT1.999999S')); 177 | $this->assertEquals('1439028612.123455', $dt->format('U.u')); 178 | 179 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 180 | $dt->add(new DateInterval('PT1.876544S')); 181 | $this->assertEquals('1439028612.000000', $dt->format('U.u')); 182 | 183 | 184 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 185 | $dt->add(new DateInterval('-PT0.000000S')); 186 | $this->assertEquals('1439028610.123456', $dt->format('U.u')); 187 | 188 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 189 | $dt->add(new DateInterval('-PT1.123456S')); 190 | $this->assertEquals('1439028609.000000', $dt->format('U.u')); 191 | 192 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 193 | $dt->add(new DateInterval('-PT1.999999S')); 194 | $this->assertEquals('1439028608.123457', $dt->format('U.u')); 195 | 196 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 197 | $dt->add(new DateInterval('-PT1.876544S')); 198 | $this->assertEquals('1439028608.246912', $dt->format('U.u')); 199 | } 200 | 201 | /** 202 | * @covers alroniks\dtms\DateTime::sub 203 | */ 204 | public function testSub() 205 | { 206 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 207 | $dt->sub(new DateInterval('PT0.000000S')); 208 | $this->assertEquals('1439028610.123456', $dt->format('U.u')); 209 | 210 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 211 | $dt->sub(new DateInterval('PT1.123456S')); 212 | $this->assertEquals('1439028609.000000', $dt->format('U.u')); 213 | 214 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 215 | $dt->sub(new DateInterval('PT1.999999S')); 216 | $this->assertEquals('1439028608.123457', $dt->format('U.u')); 217 | 218 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 219 | $dt->sub(new DateInterval('PT1.876544S')); 220 | $this->assertEquals('1439028608.246912', $dt->format('U.u')); 221 | 222 | 223 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 224 | $dt->sub(new DateInterval('-PT0.000000S')); 225 | $this->assertEquals('1439028610.123456', $dt->format('U.u')); 226 | 227 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 228 | $dt->sub(new DateInterval('-PT1.123456S')); 229 | $this->assertEquals('1439028611.246912', $dt->format('U.u')); 230 | 231 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 232 | $dt->sub(new DateInterval('-PT1.999999S')); 233 | $this->assertEquals('1439028612.123455', $dt->format('U.u')); 234 | 235 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 236 | $dt->sub(new DateInterval('-PT1.876544S')); 237 | $this->assertEquals('1439028612.000000', $dt->format('U.u')); 238 | } 239 | 240 | /** 241 | * @covers alroniks\dtms\DateTime::modify 242 | */ 243 | public function testModify() 244 | { 245 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 246 | $dt->modify('+10 microseconds'); 247 | $this->assertEquals('1439028610.123466', $dt->format('U.u')); 248 | 249 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 250 | $dt->modify('+10 microsecond'); 251 | $this->assertEquals('1439028610.123466', $dt->format('U.u')); 252 | 253 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 254 | $dt->modify('+10 micro'); 255 | $this->assertEquals('1439028610.123466', $dt->format('U.u')); 256 | 257 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 258 | $dt->modify('+10 mic'); 259 | $this->assertEquals('1439028610.123466', $dt->format('U.u')); 260 | 261 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 262 | $dt->modify('+10microseconds'); 263 | $this->assertEquals('1439028610.123466', $dt->format('U.u')); 264 | 265 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 266 | $dt->modify('+10microsecond'); 267 | $this->assertEquals('1439028610.123466', $dt->format('U.u')); 268 | 269 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 270 | $dt->modify('+10micro'); 271 | $this->assertEquals('1439028610.123466', $dt->format('U.u')); 272 | 273 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 274 | $dt->modify('+10mic'); 275 | $this->assertEquals('1439028610.123466', $dt->format('U.u')); 276 | 277 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 278 | $dt->modify('-10 microseconds'); 279 | $this->assertEquals('1439028610.123446', $dt->format('U.u')); 280 | 281 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 282 | $dt->modify('-10 microsecond'); 283 | $this->assertEquals('1439028610.123446', $dt->format('U.u')); 284 | 285 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 286 | $dt->modify('-10 micro'); 287 | $this->assertEquals('1439028610.123446', $dt->format('U.u')); 288 | 289 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 290 | $dt->modify('-10 mic'); 291 | $this->assertEquals('1439028610.123446', $dt->format('U.u')); 292 | 293 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 294 | $dt->modify('+999999 micro'); 295 | $this->assertEquals('1439028611.123455', $dt->format('U.u')); 296 | 297 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 298 | $dt->modify('-999999 micro'); 299 | $this->assertEquals('1439028609.123457', $dt->format('U.u')); 300 | 301 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 302 | $dt->modify('+1999999 micro'); 303 | $this->assertEquals('1439028612.123455', $dt->format('U.u')); 304 | 305 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 306 | $dt->modify('-1999999 micro'); 307 | $this->assertEquals('1439028608.123457', $dt->format('U.u')); 308 | 309 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 310 | $dt->modify('+10 min +10 seconds +123456 micro'); 311 | $this->assertEquals('1439029220.246912', $dt->format('U.u')); 312 | 313 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 314 | $dt->modify('-10 min -10 seconds -123456 micro'); 315 | $this->assertEquals('1439028000.000000', $dt->format('U.u')); 316 | } 317 | 318 | /** 319 | * @covers alroniks\dtms\DateTime::diff 320 | */ 321 | public function testDiff() 322 | { 323 | $dt1 = new DateTime('2015-08-08 10:10:10.123456'); 324 | $dt2 = new DateTime('2015-08-08 10:10:05.654321'); 325 | $this->assertEquals('-PT4.469135S', $dt1->diff($dt2)->format('%RPT%sS')); 326 | $this->assertEquals('+PT4.469135S', $dt2->diff($dt1)->format('%RPT%sS')); 327 | 328 | $dt1 = new DateTime('2015-08-08 10:10:10.123456'); 329 | $dt2 = new DateTime('2015-08-08 10:10:10.123455'); 330 | $this->assertEquals('-PT0.000001S', $dt1->diff($dt2)->format('%RPT%sS')); 331 | $this->assertEquals('+PT0.000001S', $dt2->diff($dt1)->format('%RPT%sS')); 332 | 333 | $dt1 = new DateTime('2015-08-08 10:10:10.123456'); 334 | $dt2 = new DateTime('2015-08-08 10:10:15.654321'); 335 | $this->assertEquals('+PT5.530865S', $dt1->diff($dt2)->format('%RPT%sS')); 336 | $this->assertEquals('-PT5.530865S', $dt2->diff($dt1)->format('%RPT%sS')); 337 | 338 | $dt1 = new DateTime('2015-08-08 10:10:10.123456'); 339 | $dt2 = new DateTime('2015-08-08 10:10:10.123456'); 340 | $this->assertEquals('+PT0S', $dt1->diff($dt2)->format('%RPT%sS')); 341 | $this->assertEquals('+PT0S', $dt2->diff($dt1)->format('%RPT%sS')); 342 | 343 | $dt1 = new DateTime('2015-08-08 10:10:10.123456'); 344 | $dt2 = new DateTime('2015-08-08 10:10:11.654321'); 345 | $this->assertEquals('+PT1.530865S', $dt1->diff($dt2, true)->format('%RPT%sS')); 346 | $this->assertEquals('+PT1.530865S', $dt2->diff($dt1, true)->format('%RPT%sS')); 347 | 348 | $dt1 = new DateTime('2015-08-08 10:10:10.123456'); 349 | $dt2 = new DateTime('2015-08-18 10:10:05.654321'); 350 | $this->assertEquals('+P9DT55.530865S', $dt1->diff($dt2)->format('%RP%dDT%sS')); 351 | $this->assertEquals('-P9DT55.530865S', $dt2->diff($dt1)->format('%RP%dDT%sS')); 352 | 353 | $dt1 = new DateTime('2015-08-08 10:10:10.123456'); 354 | $dt2 = new DateTime('2015-12-12 10:10:10.123456'); 355 | $this->assertEquals('+P4M4DT0S', $dt1->diff($dt2)->format('%RP%mM%dDT%sS')); 356 | $this->assertEquals('-P4M4DT0S', $dt2->diff($dt1)->format('%RP%mM%dDT%sS')); 357 | 358 | $dt1 = new DateTime('2015-08-10 10:10:10.101010'); 359 | $dt2 = new DateTime('2018-08-14 16:18:10.101010'); 360 | $this->assertEquals('+P3Y0M4DT6H8I0S', $dt1->diff($dt2)->format('%RP%yY%mM%dDT%hH%iI%sS')); 361 | $this->assertEquals('-P3Y0M4DT6H8I0S', $dt2->diff($dt1)->format('%RP%yY%mM%dDT%hH%iI%sS')); 362 | } 363 | 364 | /** 365 | * @covers alroniks\dtms\DateTime::__toString 366 | */ 367 | public function testToString() 368 | { 369 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 370 | $this->assertSame('2015-08-08T10:10:10.123456Z', '' . $dt); 371 | 372 | $dt->setMicroseconds(456); 373 | $this->assertSame('2015-08-08T10:10:10.000456Z', '' . $dt); 374 | 375 | $dt->setMicroseconds(101010); 376 | $this->assertSame('2015-08-08T10:10:10.101010Z', '' . $dt); 377 | } 378 | 379 | /** 380 | * @covers alroniks\dtms\DateTime::format 381 | */ 382 | public function testFormat() 383 | { 384 | $dt = new DateTime('2015-08-08 10:10:10.123456'); 385 | $this->assertSame('08.08.2015 10:10:10.123456', $dt->format('d.m.Y H:i:s.u')); 386 | $this->assertSame('08.08.2015 10:10:10', $dt->format('d.m.Y H:i:s')); 387 | $this->assertSame('1439028610.123456', $dt->format('U.u')); 388 | } 389 | } 390 | --------------------------------------------------------------------------------