add carbon lib for date operations
This commit is contained in:
parent
eee7c668cc
commit
9ed7f6ff7c
|
@ -17,7 +17,8 @@
|
||||||
"php": ">=5.4",
|
"php": ">=5.4",
|
||||||
"symfony/process": "~2.3",
|
"symfony/process": "~2.3",
|
||||||
"jms/serializer": "0.16.*",
|
"jms/serializer": "0.16.*",
|
||||||
"symfony/filesystem": "~2.3"
|
"symfony/filesystem": "~2.3",
|
||||||
|
"nesbot/carbon": "~1.14"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "~4.0"
|
"phpunit/phpunit": "~4.0"
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace DavidBadura\Taskwarrior\Serializer\Handler;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use JMS\Serializer\Context;
|
||||||
|
use JMS\Serializer\Exception\RuntimeException;
|
||||||
|
use JMS\Serializer\GraphNavigator;
|
||||||
|
use JMS\Serializer\Handler\SubscribingHandlerInterface;
|
||||||
|
use JMS\Serializer\VisitorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author David Badura <d.a.badura@gmail.com>
|
||||||
|
*/
|
||||||
|
class CarbonHandler implements SubscribingHandlerInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $defaultFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \DateTimeZone
|
||||||
|
*/
|
||||||
|
private $defaultTimezone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $defaultFormat
|
||||||
|
* @param string $defaultTimezone
|
||||||
|
*/
|
||||||
|
public function __construct($defaultFormat = 'Ymd\THis\Z', $defaultTimezone = 'UTC')
|
||||||
|
{
|
||||||
|
$this->defaultFormat = $defaultFormat;
|
||||||
|
$this->defaultTimezone = new \DateTimeZone($defaultTimezone);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getSubscribingMethods()
|
||||||
|
{
|
||||||
|
$methods = array();
|
||||||
|
$types = array('Carbon\Carbon', 'Carbon');
|
||||||
|
|
||||||
|
foreach ($types as $type) {
|
||||||
|
$methods[] = array(
|
||||||
|
'type' => $type,
|
||||||
|
'format' => 'json',
|
||||||
|
'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
|
||||||
|
'method' => 'deserializeCarbon'
|
||||||
|
);
|
||||||
|
|
||||||
|
$methods[] = array(
|
||||||
|
'type' => $type,
|
||||||
|
'format' => 'json',
|
||||||
|
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
|
||||||
|
'method' => 'serializeCarbon'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param VisitorInterface $visitor
|
||||||
|
* @param Carbon $date
|
||||||
|
* @param array $type
|
||||||
|
* @param Context $context
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function serializeCarbon(VisitorInterface $visitor, Carbon $date, array $type, Context $context)
|
||||||
|
{
|
||||||
|
return $visitor->visitString($date->format($this->getFormat($type)), $type, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param VisitorInterface $visitor
|
||||||
|
* @param string $data
|
||||||
|
* @param array $type
|
||||||
|
* @return \DateTime|null
|
||||||
|
*/
|
||||||
|
public function deserializeCarbon(VisitorInterface $visitor, $data, array $type)
|
||||||
|
{
|
||||||
|
if (null === $data) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$timezone = isset($type['params'][1]) ? new \DateTimeZone($type['params'][1]) : $this->defaultTimezone;
|
||||||
|
$format = $this->getFormat($type);
|
||||||
|
|
||||||
|
$datetime = Carbon::createFromFormat($format, (string)$data, $timezone);
|
||||||
|
|
||||||
|
if (false === $datetime) {
|
||||||
|
throw new RuntimeException(sprintf('Invalid datetime "%s", expected format %s.', $data, $format));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $datetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $type
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function getFormat(array $type)
|
||||||
|
{
|
||||||
|
return isset($type['params'][0]) ? $type['params'][0] : $this->defaultFormat;
|
||||||
|
}
|
||||||
|
}
|
34
src/Task.php
34
src/Task.php
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace DavidBadura\Taskwarrior;
|
namespace DavidBadura\Taskwarrior;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
use JMS\Serializer\Annotation as JMS;
|
use JMS\Serializer\Annotation as JMS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,23 +48,23 @@ class Task
|
||||||
private $project;
|
private $project;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \DateTime
|
* @var Carbon
|
||||||
*
|
*
|
||||||
* @JMS\Type(name="DateTime<'Ymd\THis\Z'>")
|
* @JMS\Type("Carbon")
|
||||||
*/
|
*/
|
||||||
private $due;
|
private $due;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \DateTime
|
* @var Carbon
|
||||||
*
|
*
|
||||||
* @JMS\Type(name="DateTime<'Ymd\THis\Z'>")
|
* @JMS\Type("Carbon")
|
||||||
*/
|
*/
|
||||||
private $wait;
|
private $wait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \DateTime
|
* @var Carbon
|
||||||
*
|
*
|
||||||
* @JMS\Type(name="DateTime<'Ymd\THis\Z'>")
|
* @JMS\Type("Carbon")
|
||||||
*/
|
*/
|
||||||
private $until;
|
private $until;
|
||||||
|
|
||||||
|
@ -82,24 +83,24 @@ class Task
|
||||||
private $urgency;
|
private $urgency;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \DateTime
|
* @var Carbon
|
||||||
*
|
*
|
||||||
* @JMS\Type(name="DateTime<'Ymd\THis\Z'>")
|
* @JMS\Type("Carbon")
|
||||||
*/
|
*/
|
||||||
private $entry;
|
private $entry;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \DateTime
|
* @var Carbon
|
||||||
*
|
*
|
||||||
* @JMS\Type(name="DateTime<'Ymd\THis\Z'>")
|
* @JMS\Type("Carbon")
|
||||||
*/
|
*/
|
||||||
private $modified;
|
private $modified;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \DateTime
|
* @var Carbon
|
||||||
*
|
*
|
||||||
* @JMS\Type(name="DateTime<'Ymd\THis\Z'>")
|
* @JMS\Type("Carbon")
|
||||||
*/
|
*/
|
||||||
private $end;
|
private $end;
|
||||||
|
|
||||||
|
@ -116,7 +117,7 @@ class Task
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->urgency = 0;
|
$this->urgency = 0;
|
||||||
$this->entry = new \DateTime('now', new \DateTimeZone('UTC'));
|
$this->entry = new Carbon('now', new \DateTimeZone('UTC'));
|
||||||
$this->status = self::STATUS_PENDING;
|
$this->status = self::STATUS_PENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +349,10 @@ class Task
|
||||||
private function parseDateTime($date)
|
private function parseDateTime($date)
|
||||||
{
|
{
|
||||||
if ($date instanceof \DateTime) {
|
if ($date instanceof \DateTime) {
|
||||||
|
return new Carbon($date->format('Y-m-d H:i:s'), new \DateTimeZone('UTC'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($date instanceof Carbon) {
|
||||||
$date = clone $date;
|
$date = clone $date;
|
||||||
$date->setTimezone(new \DateTimeZone('UTC'));
|
$date->setTimezone(new \DateTimeZone('UTC'));
|
||||||
|
|
||||||
|
@ -356,7 +360,7 @@ class Task
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_string($date)) {
|
if (is_string($date)) {
|
||||||
return new \DateTime($date, new \DateTimeZone('UTC'));
|
return new Carbon($date, new \DateTimeZone('UTC'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($date === null) {
|
if ($date === null) {
|
||||||
|
@ -372,7 +376,7 @@ class Task
|
||||||
public function __clone()
|
public function __clone()
|
||||||
{
|
{
|
||||||
$this->uuid = null;
|
$this->uuid = null;
|
||||||
$this->entry = new \DateTime('now', new \DateTimeZone('UTC'));
|
$this->entry = new Carbon('now', new \DateTimeZone('UTC'));
|
||||||
$this->status = self::STATUS_PENDING;
|
$this->status = self::STATUS_PENDING;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,9 +2,10 @@
|
||||||
|
|
||||||
namespace DavidBadura\Taskwarrior;
|
namespace DavidBadura\Taskwarrior;
|
||||||
|
|
||||||
|
use DavidBadura\Taskwarrior\Serializer\Handler\CarbonHandler;
|
||||||
|
use JMS\Serializer\Handler\HandlerRegistryInterface;
|
||||||
|
use JMS\Serializer\Serializer;
|
||||||
use JMS\Serializer\SerializerBuilder;
|
use JMS\Serializer\SerializerBuilder;
|
||||||
use Symfony\Component\Filesystem\Filesystem;
|
|
||||||
use Symfony\Component\Process\ProcessBuilder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author David Badura <d.a.badura@gmail.com>
|
* @author David Badura <d.a.badura@gmail.com>
|
||||||
|
@ -164,11 +165,7 @@ class TaskManager
|
||||||
{
|
{
|
||||||
$json = $this->taskwarrior->export($filter);
|
$json = $this->taskwarrior->export($filter);
|
||||||
|
|
||||||
$serializer = SerializerBuilder::create()
|
return $this->getSerializer()->deserialize($json, 'array<DavidBadura\Taskwarrior\Task>', 'json');
|
||||||
->addDefaultHandlers()
|
|
||||||
->build();
|
|
||||||
|
|
||||||
return $serializer->deserialize($json, 'array<DavidBadura\Taskwarrior\Task>', 'json');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -241,11 +238,7 @@ class TaskManager
|
||||||
*/
|
*/
|
||||||
private function serializeTask(Task $task)
|
private function serializeTask(Task $task)
|
||||||
{
|
{
|
||||||
$serializer = SerializerBuilder::create()
|
$result = $this->getSerializer()->serialize($task, 'json');
|
||||||
->addDefaultHandlers()
|
|
||||||
->build();
|
|
||||||
|
|
||||||
$result = $serializer->serialize($task, 'json');
|
|
||||||
|
|
||||||
return str_replace("\\/", "/", $result);
|
return str_replace("\\/", "/", $result);
|
||||||
}
|
}
|
||||||
|
@ -263,6 +256,20 @@ class TaskManager
|
||||||
$prop->setValue($task, $value);
|
$prop->setValue($task, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Serializer
|
||||||
|
*/
|
||||||
|
private function getSerializer()
|
||||||
|
{
|
||||||
|
return SerializerBuilder::create()
|
||||||
|
->configureHandlers(function (HandlerRegistryInterface $registry) {
|
||||||
|
$registry->registerSubscribingHandler(new CarbonHandler());
|
||||||
|
})
|
||||||
|
->addDefaultHandlers()
|
||||||
|
->setDebug(true)
|
||||||
|
->build();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -16,6 +16,11 @@ class Taskwarrior
|
||||||
*/
|
*/
|
||||||
private $rcOptions;
|
private $rcOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $version;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $taskrc
|
* @param string $taskrc
|
||||||
* @param string $taskData
|
* @param string $taskData
|
||||||
|
@ -56,7 +61,7 @@ class Taskwarrior
|
||||||
*/
|
*/
|
||||||
public function add(array $params)
|
public function add(array $params)
|
||||||
{
|
{
|
||||||
$this->command('modify', null, $this->getOptions($params));
|
$this->command('add', null, $this->getOptions($params));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -173,7 +178,11 @@ class Taskwarrior
|
||||||
*/
|
*/
|
||||||
public function version()
|
public function version()
|
||||||
{
|
{
|
||||||
return $this->command('_version');
|
if ($this->version) {
|
||||||
|
return $this->version;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->version = $this->command('_version');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -176,8 +176,15 @@ class TaskManagerTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertCount(1, $this->taskManager->filter('project:home prio:H +now'));
|
$this->assertCount(1, $this->taskManager->filter('project:home prio:H +now'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDates()
|
public function testModified()
|
||||||
{
|
{
|
||||||
|
if (version_compare($this->taskwarrior->version(), '2.2.0', '>=')) {
|
||||||
|
$this->markTestSkipped(sprintf(
|
||||||
|
'taskwarrior version %s dont support modified attr',
|
||||||
|
$this->taskwarrior->version()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
$task1 = new Task();
|
$task1 = new Task();
|
||||||
$task1->setDescription('foo1');
|
$task1->setDescription('foo1');
|
||||||
|
|
||||||
|
@ -185,7 +192,6 @@ class TaskManagerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
$this->assertInstanceOf('DateTime', $task1->getEntry());
|
$this->assertInstanceOf('DateTime', $task1->getEntry());
|
||||||
$this->assertNull($task1->getModified());
|
$this->assertNull($task1->getModified());
|
||||||
$this->assertNull($task1->getEnd());
|
|
||||||
|
|
||||||
$task1->setDescription('bar2');
|
$task1->setDescription('bar2');
|
||||||
|
|
||||||
|
@ -193,12 +199,28 @@ class TaskManagerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
$this->assertInstanceOf('DateTime', $task1->getEntry());
|
$this->assertInstanceOf('DateTime', $task1->getEntry());
|
||||||
$this->assertInstanceOf('DateTime', $task1->getModified());
|
$this->assertInstanceOf('DateTime', $task1->getModified());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testEnd()
|
||||||
|
{
|
||||||
|
$task1 = new Task();
|
||||||
|
$task1->setDescription('foo1');
|
||||||
|
|
||||||
|
$this->taskManager->save($task1);
|
||||||
|
|
||||||
|
$this->assertInstanceOf('DateTime', $task1->getEntry());
|
||||||
|
$this->assertNull($task1->getEnd());
|
||||||
|
|
||||||
|
$task1->setDescription('bar2');
|
||||||
|
|
||||||
|
$this->taskManager->save($task1);
|
||||||
|
|
||||||
|
$this->assertInstanceOf('DateTime', $task1->getEntry());
|
||||||
$this->assertNull($task1->getEnd());
|
$this->assertNull($task1->getEnd());
|
||||||
|
|
||||||
$this->taskManager->done($task1);
|
$this->taskManager->done($task1);
|
||||||
|
|
||||||
$this->assertInstanceOf('DateTime', $task1->getEntry());
|
$this->assertInstanceOf('DateTime', $task1->getEntry());
|
||||||
$this->assertInstanceOf('DateTime', $task1->getModified());
|
|
||||||
$this->assertInstanceOf('DateTime', $task1->getEnd());
|
$this->assertInstanceOf('DateTime', $task1->getEnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,6 +529,6 @@ class TaskManagerTest extends \PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
private function createDateTime($string = 'now')
|
private function createDateTime($string = 'now')
|
||||||
{
|
{
|
||||||
return new \DateTime($string);
|
return new \DateTime($string, new \DateTimeZone('UTC'));
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue