Skip to content

Commit

Permalink
add utc support.
Browse files Browse the repository at this point in the history
  • Loading branch information
vistart committed Mar 21, 2017
1 parent 9adc0ba commit e46bc37
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 24 deletions.
4 changes: 4 additions & 0 deletions tests/data/ar/EntityAI.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

namespace rhosocial\base\models\tests\data\ar;

/**
* @version 1.0
* @author vistart <[email protected]>
*/
class EntityAI extends Entity
{
public $idAttributeType = 2; // Auto Increment.
Expand Down
22 changes: 22 additions & 0 deletions tests/data/ar/EntityUtc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

/**
* _ __ __ _____ _____ ___ ____ _____
* | | / // // ___//_ _// || __||_ _|
* | |/ // /(__ ) / / / /| || | | |
* |___//_//____/ /_/ /_/ |_||_| |_|
* @link https://vistart.me/
* @copyright Copyright (c) 2016 - 2017 vistart
* @license https://vistart.me/license/
*/

namespace rhosocial\base\models\tests\data\ar;

/**
* @version 1.0
* @author vistart <[email protected]>
*/
class EntityUtc extends Entity
{
public $timeType = 0;
}
10 changes: 10 additions & 0 deletions tests/entity/TimestampTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,16 @@ public function testRange()
$this->assertGreaterThanOrEqual(1, $this->entity->delete());
}

/**
* @group entity
* @group timestamp
*/
public function testUtcDatetime()
{
$this->entity = new \rhosocial\base\models\tests\data\ar\EntityUtc();
$this->assertTrue($this->entity->save());
}

public function severalTimes()
{
for ($i = 0; $i < 3; $i++)
Expand Down
99 changes: 75 additions & 24 deletions traits/TimestampTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ trait TimestampTrait
* Set this property to false if you do not want to record the creation time.
*/
public $createdAtAttribute = 'created_at';

/**
* @var string|false the attribute that receive datetime value.
* Set this property to false if you do not want to record the update time.
*/
public $updatedAtAttribute = 'updated_at';

/**
* @var string|false the attribute that determine when this entity expire.
* If this entity does not expire, set to false.
Expand All @@ -56,12 +56,20 @@ trait TimestampTrait
public static $timeFormatTimestamp = 1;
public static $initDatetime = '1970-01-01 00:00:00';
public static $initTimestamp = 0;
public $timeType = 1;
public static $timeTypeUtc = 0;
public static $timeTypeLocal = 1;
public static $timeTypes = [
0 => 'GMT',
1 => 'local',
];

/**
* @var Closure
*/
public $expiredRemovingCallback;
public static $eventExpiredRemoved = 'expiredRemoved';

/**
* Check this entity whether expired.
* This feature require creation time. If creation time didn't record, false
Expand All @@ -76,9 +84,14 @@ public function getIsExpired()
if ($this->getExpiredAfter() === false || $createdAt === null) {
return false;
}
return $this->offsetDatetime($this->currentDatetime(), -$this->getExpiredAfter()) > $createdAt;
if ($this->timeType == static::$timeTypeLocal) {
return $this->offsetDatetime($this->currentDatetime(), -$this->getExpiredAfter()) > $createdAt;
} elseif ($this->timeType == static::$timeTypeUtc) {
return $this->offsetUtcDatetime($this->currentUtcDatetime(), -$this->getExpiredAfter()) > $createdAt;
}
return false;
}

/**
* Remove myself if expired.
* The `expiredRemovingCallback` will be called before removing itself,
Expand All @@ -98,7 +111,7 @@ public function removeIfExpired()
}
return false;
}

/**
* Remove self.
* You can override this method for implementing more complex features.
Expand All @@ -109,7 +122,7 @@ public function removeSelf()
{
return $this->delete();
}

/**
* We recommened you attach this event when after finding this active record.
* @param ModelEvent $event
Expand All @@ -119,7 +132,7 @@ public function onRemoveExpired($event)
{
return $event->sender->removeIfExpired();
}

/**
* Get the current date & time in format of "Y-m-d H:i:s" or timestamp.
* You can override this method to customize the return value.
Expand All @@ -129,9 +142,15 @@ public function onRemoveExpired($event)
public static function getCurrentDatetime($event)
{
$sender = $event->sender;
return $sender->currentDatetime();
/* @var $sender static */
if ($sender->timeType == static::$timeTypeUtc) {
return $sender->currentUtcDatetime();
} elseif ($sender->timeType == static::$timeTypeLocal) {
return $sender->currentDatetime();
}
return null;
}

/**
* Get current date & time, by current time format.
* @return string|int Date & time string if format is datetime, or timestamp.
Expand All @@ -146,7 +165,22 @@ public function currentDatetime()
}
return null;
}


/**
* Get current Greenwich date & time (UTC), by current time format.
* @return string|int Date & time string if format is datetime, or timestamp.
*/
public function currentUtcDatetime()
{
if ($this->timeFormat === static::$timeFormatDatetime) {
return gmdate('Y-m-d H:i:s');
}
if ($this->timeFormat === static::$timeFormatTimestamp) {
return gmmktime();
}
return null;
}

/**
* Get offset date & time, by current time format.
* @param string|int $time Date &time string or timestamp.
Expand All @@ -163,7 +197,24 @@ public function offsetDatetime($time = null, $offset = 0)
}
return null;
}


/**
* Get offset date & time relative to Greenwich time(UTC), by current time format.
* @param string|int $time Date &time string or timestamp.
* @param int $offset Offset in seconds.
* @return string|int Date & time string if format is datetime, or timestamp.
*/
public function offsetUtcDatetime($time = null, $offset = 0)
{
if ($this->timeFormat === static::$timeFormatDatetime) {
return gmdate('Y-m-d H:i:s', strtotime(($offset >= 0 ? "+$offset" : $offset) . " seconds", is_string($time) ? strtotime($time) : (is_int($time) ? $time : gmmktime())));
}
if ($this->timeFormat === static::$timeFormatTimestamp) {
return (is_int($time) ? $time : gmmktime()) + $offset;
}
return null;
}

/**
* Get init date & time in format of "Y-m-d H:i:s" or timestamp.
* @param ModelEvent $event
Expand All @@ -174,7 +225,7 @@ public static function getInitDatetime($event)
$sender = $event->sender;
return $sender->initDatetime();
}

/**
* Get init date & time, by current time format.
* @return string|int Date & time string if format is datetime, or timestamp.
Expand All @@ -189,7 +240,7 @@ public function initDatetime()
}
return null;
}

/**
* Check whether the attribute is init datetime.
* @param mixed $attribute
Expand All @@ -205,7 +256,7 @@ protected function isInitDatetime($attribute)
}
return false;
}

/**
* Get the current date & time in format of "Y-m-d H:i:s".
* This method is ONLY used for being triggered by event. DO NOT call,
Expand All @@ -217,7 +268,7 @@ public function onUpdateCurrentDatetime($event)
{
return static::getCurrentDatetime($event);
}

/**
* Behaviors associated with timestamp.
* @return array behaviors
Expand All @@ -233,7 +284,7 @@ public function getTimestampBehaviors()
]
];
}

/**
* Get creation time.
* @return string timestamp
Expand All @@ -246,7 +297,7 @@ public function getCreatedAt()
}
return $this->$createdAtAttribute;
}

/**
* Get rules associated with createdAtAttribute.
* The default rule is safe. Because the [[TimestampBehavior]] will attach
Expand All @@ -264,7 +315,7 @@ public function getCreatedAtRules()
[[$this->createdAtAttribute], 'safe'],
];
}

/**
* Get update time.
* @return string timestamp
Expand All @@ -277,7 +328,7 @@ public function getUpdatedAt()
}
return $this->$updatedAtAttribute;
}

/**
* Get rules associated with `updatedAtAttribute`.
* The default rule is safe. Because the [[TimestampBehavior]] will attach
Expand All @@ -295,7 +346,7 @@ public function getUpdatedAtRules()
[[$this->updatedAtAttribute], 'safe'],
];
}

/**
* Get expiration duration.
* If `expiredAfterAttribute` is not specified, false will be given.
Expand All @@ -308,7 +359,7 @@ public function getExpiredAfter()
}
return (int)($this->{$this->expiredAfterAttribute});
}

/**
* Set expiration duration (in seconds).
* If `expiredAfterAttribute` is not specified, this feature will be skipped,
Expand All @@ -323,7 +374,7 @@ public function setExpiredAfter($expiredAfter)
}
return (int)($this->{$this->expiredAfterAttribute} = (int)$expiredAfter);
}

/**
* Get rules associated with `expiredAfterAttribute`.
* The default rule is unsigned integer.
Expand All @@ -340,7 +391,7 @@ public function getExpiredAfterRules()
[[$this->expiredAfterAttribute], 'integer', 'min' => 0],
];
}

/**
* Get enabled fields associated with timestamp, including `createdAtAttribute`,
* `updatedAtAttribute` and `expiredAfterAttribute`.
Expand Down

0 comments on commit e46bc37

Please sign in to comment.