Skip to content
This repository has been archived by the owner on Dec 27, 2023. It is now read-only.

Commit

Permalink
Merge: conflict resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreu Correa Casablanca committed Jun 3, 2016
2 parents 385f4f2 + c8bafbc commit d3dbffa
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 70 deletions.
45 changes: 35 additions & 10 deletions .travis.yml
@@ -1,13 +1,37 @@
language: php

php:
- 5.5
- 5.6
- 7.0
- hhvm
cache:
directories:
- "$HOME/.composer/cache"

env:
- MONGO_VERSION=stable PREFER_LOWEST=""
matrix:
fast_finish: true
include:
- php: 5.5
env:
- MONGO_EXTENSION=mongo
- php: 5.5
env:
- MONGODB_EXTENSION=mongodb
- php: 5.5
env:
- MONGO_EXTENSION=mongo
- MONGODB_EXTENSION=mongodb
- php: 5.6
env:
- MONGO_EXTENSION=mongo
- php: 5.6
env:
- MONGODB_EXTENSION=mongodb
- php: 5.6
env:
- MONGO_EXTENSION=mongo
- MONGODB_EXTENSION=mongodb
- SEND_TO_OCULAR=yes
- php: 7.0
env:
- MONGODB_EXTENSION=mongodb
- php: hhvm

before_install:
- bash -c 'mkdir bin'
Expand All @@ -17,12 +41,13 @@ before_install:
- bash -c 'if [ "$TRAVIS_PHP_VERSION" == "hhvm" ]; then mv phpunit.hhvm.xml phpunit.xml; fi;'

install:
- travis_retry bash -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then yes "" | pecl -q install -f mongo-${MONGO_VERSION}; fi;'
- travis_retry bash -c 'if [ "$MONGO_EXTENSION" == "mongo" ]; then yes "" | pecl -q install -f mongo-stable; fi;'
- travis_retry bash -c 'if [ "$MONGODB_EXTENSION" == "mongodb" ]; then yes "" | pecl -q install -f mongodb-stable; fi;'
- travis_retry ./bin/composer.phar install --ignore-platform-reqs --no-interaction --prefer-source

script:
- vendor/bin/phpunit

after_script:
- travis_retry wget https://scrutinizer-ci.com/ocular.phar
- travis_retry bash -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then php ocular.phar code-coverage:upload --format=php-clover coverage.xml; fi;'
- travis_retry bash -c 'if [ "$SEND_TO_OCULAR" == "yes" ]; then wget https://scrutinizer-ci.com/ocular.phar; fi;'
- travis_retry bash -c 'if [ "$SEND_TO_OCULAR" == "yes" ]; then php ocular.phar code-coverage:upload --format=php-clover coverage.xml; fi;'
9 changes: 7 additions & 2 deletions README.md
Expand Up @@ -33,5 +33,10 @@ $fromDateTime = UniversalTimestamp::fromDateTimeInterface(new \DateTime());
$fromMongoDate = UniversalTimestamp::fromMongoDate(new \MongoDate());
```

**Notice:** The MongoDB related methods are only available when the `mongo` extension is loaded.
On *PHP 7.0* and *HHVM*, the `mongo` extension isn't loaded.
**Notice:** The MongoDB related methods are only available when the `mongo` or `mongodb` extensions are loaded.

## Integration with Doctrine
If you want to use Jiffy's UniversalTimesamp objects in your Doctrine models, you can use our adapter layers:

* [**Jiffy Universal Timestamps for MongoDB ODM**](https://github.com/Litipk/doctrine-mongodb-jiffy/)
* **Jiffy Universal Timestamps for Doctrine ORM** : *Work in progress*.
1 change: 1 addition & 0 deletions composer.json
Expand Up @@ -19,6 +19,7 @@
},
"require-dev": {
"ext-mongo": "*",
"ext-mongodb": "*",
"phpunit/phpunit": "~4.0"
},
"autoload": {
Expand Down
29 changes: 29 additions & 0 deletions src/MongodbAdapter.php
@@ -0,0 +1,29 @@
<?php


namespace Litipk\Jiffy;


/**
* Trait MongodbAdapter: Only to be used inside UniversalTimestamp.
* @package Litipk\Jiffy
*/
trait MongodbAdapter
{
/**
* @param \MongoDB\BSON\UTCDatetime $mongoDate
* @return UniversalTimestamp
*/
public static function fromMongodbUTCDateTime(\MongoDB\BSON\UTCDatetime $mongoDate)
{
return UniversalTimestamp::fromMillisecondsTimestamp((int)$mongoDate->__toString());
}

/**
* @return \MongoDate
*/
public function asMongodbUTCDateTime()
{
return new \MongoDB\BSON\UTCDatetime($this->millis);
}
}
49 changes: 26 additions & 23 deletions src/UniversalTimestamp.php
Expand Up @@ -4,10 +4,14 @@
namespace Litipk\Jiffy;


if (!extension_loaded('mongo')) {
trait TsExtension {};
} else {
if (extension_loaded('mongo') && extension_loaded('mongodb')) {
trait TsExtension { use MongoAdapter; use MongodbAdapter; };
} elseif (extension_loaded('mongo')) {
trait TsExtension { use MongoAdapter; };
} elseif (extension_loaded('mongodb')) {
trait TsExtension { use MongodbAdapter; };
} else {
trait TsExtension {};
}


Expand All @@ -17,6 +21,11 @@ trait TsExtension { use MongoAdapter; };
*/
final class UniversalTimestamp
{
const ISO8601_WITH_MILLISECONDS = '_ISO8601_WITH_MILLIS_';
const ISO8601_WITH_MILLISECONDS_WITHOUT_TZ = '_ISO8601_WITH_MILLIS_WITHOUT_TZ';
const ISO8601_WITH_MICROSECONDS = 'Y-m-d\TH:i:s.uO';
const ISO8601_WITH_MICROSECONDS_WITHOUT_TZ = 'Y-m-d\TH:i:s.u';

use TsExtension;

/** @var int */
Expand Down Expand Up @@ -117,6 +126,8 @@ public static function fromWhatever($dateObject) {
return self::fromDateTimeInterface($dateObject);
} elseif ($dateObject instanceof \MongoDate) {
return self::fromMongoDate($dateObject);
} elseif ($dateObject instanceof \MongoDB\BSON\UTCDatetime) {
return self::fromMongodbUTCDateTime($dateObject);
} else {
throw new JiffyException('The provided value cannot be interpreted as a timestamp');
}
Expand Down Expand Up @@ -188,40 +199,32 @@ public function getRemainingMicroseconds()
*/
public function asDateTimeInterface($tz = 'UTC')
{
$dateTime = new \DateTimeImmutable();
$dateTime = $dateTime
->setTimestamp($this->asSeconds())
->setTimezone(is_string($tz) ? new \DateTimeZone($tz) : $tz);
$dateTime = new \DateTimeImmutable('@'.((string)$this->asSeconds()));
$dateTime = $dateTime->setTimezone(is_string($tz) ? new \DateTimeZone($tz) : $tz);

return new \DateTimeImmutable(
$dateTime->format('Y-m-d\TH:i:s').'.'.
sprintf("%'.03d", $this->millis%1000).sprintf("%'.03d", $this->micros).
sprintf("%03d", $this->millis%1000).sprintf("%03d", $this->micros).
$dateTime->format('O')
);
}

/**
* @param string $format
* @param string|\DateTimeZone $tz
* @param bool $showMillis
* @param bool $stripTz
* @return string
*/
public function asFormattedString(
$format = \DateTime::ISO8601, $tz = 'UTC', $showMillis = false, $stripTz = false
)
public function asFormattedString($format = self::ISO8601_WITH_MICROSECONDS, $tz = 'UTC')
{
$r = $this->asDateTimeInterface($tz)->format($format);

if (\DateTime::ISO8601 === $format && $showMillis) {
$rParts = preg_split('/\+/', $r);
$r = $rParts[0].'.'.((string)$this->millis%1000).($stripTz?'':('+'.$rParts[1]));
} elseif (\DateTime::ISO8601 === $format && $stripTz) {
$rParts = preg_split('/\+/', $r);
$r = $rParts[0];
if (self::ISO8601_WITH_MILLISECONDS === $format) {
$rParts = preg_split('/\+/', $this->asDateTimeInterface($tz)->format(\DateTime::ISO8601));
return $rParts[0].'.'.((string)$this->millis%1000).'+'.$rParts[1];
} elseif (self::ISO8601_WITH_MILLISECONDS_WITHOUT_TZ === $format) {
$rParts = preg_split('/\+/', $this->asDateTimeInterface($tz)->format(\DateTime::ISO8601));
return $rParts[0].'.'.((string)$this->millis%1000);
} else {
return $this->asDateTimeInterface($tz)->format($format);
}

return $r;
}

/**
Expand Down
35 changes: 35 additions & 0 deletions tests/MongoAdapterTests.php
@@ -0,0 +1,35 @@
<?php


use Litipk\Jiffy\UniversalTimestamp;


class MongoAdapterTests extends \PHPUnit_Framework_TestCase
{
public function testFromMongoDate()
{
if (!extension_loaded('mongo')) return;

$uTs_A = UniversalTimestamp::now();
$uTs_B = UniversalTimestamp::fromMongoDate(new \MongoDate());
$uTs_C = UniversalTimestamp::now();

$this->assertGreaterThanOrEqual(4, 5);

$this->assertGreaterThanOrEqual($uTs_A->asMilliseconds(), $uTs_B->asMilliseconds());
$this->assertGreaterThanOrEqual($uTs_B->asMilliseconds(), $uTs_C->asMilliseconds());
$this->assertGreaterThanOrEqual($uTs_A->asMilliseconds(), $uTs_C->asMilliseconds());
}

public function testAsMongoDate()
{
if (!extension_loaded('mongo')) return;

$ts1 = UniversalTimestamp::fromMongoDate(new \MongoDate());
$md1 = $ts1->asMongoDate();

$this->assertTrue($md1 instanceof \MongoDate);
$this->assertEquals($ts1->asSeconds(), $md1->sec);
$this->assertEquals($ts1->asMilliseconds()%1000, $md1->usec/1000);
}
}
39 changes: 39 additions & 0 deletions tests/MongodbAdapterTests.php
@@ -0,0 +1,39 @@
<?php


use Litipk\Jiffy\UniversalTimestamp;


class MongodbAdapterTests extends \PHPUnit_Framework_TestCase
{
public function testFromMongoDate()
{
if (!extension_loaded('mongodb')) return;

$uTs_A = UniversalTimestamp::now();
$uTs_B = UniversalTimestamp::fromMongodbUTCDateTime(
new \MongoDB\BSON\UTCDatetime($uTs_A->asMilliseconds()+1)
);
$uTs_C = UniversalTimestamp::fromMillisecondsTimestamp($uTs_A->asMilliseconds()+2);

$this->assertGreaterThanOrEqual(4, 5);

$this->assertGreaterThanOrEqual($uTs_A->asMilliseconds(), $uTs_B->asMilliseconds());
$this->assertGreaterThanOrEqual($uTs_B->asMilliseconds(), $uTs_C->asMilliseconds());
$this->assertGreaterThanOrEqual($uTs_A->asMilliseconds(), $uTs_C->asMilliseconds());
}

public function testAsMongoDate()
{
if (!extension_loaded('mongodb')) return;

$ts1 = UniversalTimestamp::fromMongodbUTCDateTime(
new \MongoDB\BSON\UTCDatetime(UniversalTimestamp::now()->asMilliseconds())
);
$md1 = $ts1->asMongodbUTCDateTime();

$this->assertTrue($md1 instanceof \MongoDB\BSON\UTCDatetime);
$this->assertEquals($ts1->asSeconds(), (int)floor(((int)$md1->__toString())/1000));
$this->assertEquals($ts1->asMilliseconds()%1000, ((int)$md1->__toString())%1000);
}
}
55 changes: 20 additions & 35 deletions tests/UniversalTimestampTests.php
Expand Up @@ -28,21 +28,6 @@ public function testFromDateTimeInterface()
$this->assertGreaterThanOrEqual($uTs_A->asSeconds(), $classicTs_B);
}

public function testFromMongoDate()
{
if (!extension_loaded('mongo')) return;

$uTs_A = UniversalTimestamp::now();
$uTs_B = UniversalTimestamp::fromMongoDate(new \MongoDate());
$uTs_C = UniversalTimestamp::now();

$this->assertGreaterThanOrEqual(4, 5);

$this->assertGreaterThanOrEqual($uTs_A->asMilliseconds(), $uTs_B->asMilliseconds());
$this->assertGreaterThanOrEqual($uTs_B->asMilliseconds(), $uTs_C->asMilliseconds());
$this->assertGreaterThanOrEqual($uTs_A->asMilliseconds(), $uTs_C->asMilliseconds());
}

public function testFromSeconds()
{
$classicTs_A = time();
Expand Down Expand Up @@ -86,6 +71,12 @@ public function testFromWhatever()
$ts4 = UniversalTimestamp::fromWhatever(new \MongoDate());
$this->assertTrue($ts4 instanceof UniversalTimestamp);
}
if (extension_loaded('mongodb')) {
$ts4 = UniversalTimestamp::fromWhatever(
new \MongoDB\BSON\UTCDatetime(UniversalTimestamp::now()->asMilliseconds())
);
$this->assertTrue($ts4 instanceof UniversalTimestamp);
}
}

/**
Expand Down Expand Up @@ -153,47 +144,41 @@ public function testGetRemainingMicroseconds()
}
}

public function testAsMongoDate()
{
if (!extension_loaded('mongo')) return;

$ts1 = UniversalTimestamp::fromMongoDate(new \MongoDate());
$md1 = $ts1->asMongoDate();

$this->assertTrue($md1 instanceof \MongoDate);
$this->assertEquals($ts1->asSeconds(), $md1->sec);
$this->assertEquals($ts1->asMilliseconds()%1000, $md1->usec/1000);
}

public function testToString()
{
$ts1 = UniversalTimestamp::fromSecondsTimestamp(1445817646);
$ts1 = UniversalTimestamp::fromMillisecondsTimestamp(1445817646455, 378);

$d1 = \DateTime::createFromFormat(\DateTime::ISO8601, $ts1->asFormattedString());
$d2 = \DateTime::createFromFormat(\DateTime::ISO8601, (string)$ts1);
$d1 = new \DateTime($ts1->asFormattedString());
$d2 = new \DateTime((string)$ts1);

$ts2 = UniversalTimestamp::fromDateTimeInterface($d1);
$ts3 = UniversalTimestamp::fromDateTimeInterface($d2);

$this->assertEquals($ts1->asSeconds(), $ts2->asSeconds());
$this->assertEquals($ts1->asMilliseconds(), $ts2->asMilliseconds());
$this->assertEquals($ts1->asSeconds(), $ts3->asSeconds());
$this->assertEquals($ts1->asMilliseconds(), $ts3->asMilliseconds());
}

public function testAsFormattedString_WithSpecialSettings()
{
$ts1 = UniversalTimestamp::fromMillisecondsTimestamp(1445817646571);
$ts1 = UniversalTimestamp::fromMillisecondsTimestamp(1445817646571, 473);

$this->assertEquals(
'2015-10-26T00:00:46.571+0000',
$ts1->asFormattedString(\DateTime::ISO8601, 'UTC', true, false)
$ts1->asFormattedString(UniversalTimestamp::ISO8601_WITH_MILLISECONDS, 'UTC')
);
$this->assertEquals(
'2015-10-26T00:00:46.571',
$ts1->asFormattedString(\DateTime::ISO8601, 'UTC', true, true)
$ts1->asFormattedString(UniversalTimestamp::ISO8601_WITH_MILLISECONDS_WITHOUT_TZ, 'UTC')
);
$this->assertEquals(
'2015-10-26T00:00:46.571473+0000',
$ts1->asFormattedString(UniversalTimestamp::ISO8601_WITH_MICROSECONDS, 'UTC')
);
$this->assertEquals(
'2015-10-26T00:00:46',
$ts1->asFormattedString(\DateTime::ISO8601, 'UTC', false, true)
'2015-10-26T00:00:46.571473',
$ts1->asFormattedString(UniversalTimestamp::ISO8601_WITH_MICROSECONDS_WITHOUT_TZ, 'UTC')
);
}
}

0 comments on commit d3dbffa

Please sign in to comment.