diff --git a/src/Jms/Handler/XmlSchemaDateHandler.php b/src/Jms/Handler/XmlSchemaDateHandler.php
index 11a2b13..eae4517 100644
--- a/src/Jms/Handler/XmlSchemaDateHandler.php
+++ b/src/Jms/Handler/XmlSchemaDateHandler.php
@@ -58,6 +58,12 @@ public static function getSubscribingMethods()
                 'format' => 'xml',
                 'method' => 'deserializeDateIntervalXml',
             ),
+            array(
+                'type' => 'DateInterval',
+                'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
+                'format' => 'xml',
+                'method' => 'serializeDateInterval',
+            ),
         );
     }
 
@@ -72,12 +78,50 @@ public function deserializeDateIntervalXml(XmlDeserializationVisitor $visitor, $
         if (isset($attributes['nil'][0]) && (string) $attributes['nil'][0] === 'true') {
             return null;
         }
-        return new \DateInterval((string)$data);
+
+        //Accept negative intervals like -PT1M23S.  Safe to assume that "-" doesn't exist elsewhere in a valid interval spec.
+        $interval = str_replace('-', '', (string)$data, $count);
+        $dateInterval = new \DateInterval($interval);
+
+        //Invert if a negative sign was found
+        $dateInterval->invert = !!$count;
+
+        return $dateInterval;
     }
 
-    public function serializeDate(XmlSerializationVisitor $visitor, \DateTime $date, array $type, Context $context)
+    public function serializeDateInterval(XmlSerializationVisitor $visitor, \DateInterval $interval, array $type, Context $context)
     {
+        $date = array_filter(array(
+            'Y' => $interval->y,
+            'M' => $interval->m,
+            'D' => $interval->d
+        ));
+
+        // Reading all non-zero time parts.
+        $time = array_filter(array(
+            'H' => $interval->h,
+            'M' => $interval->i,
+            'S' => $interval->s
+        ));
+
+        $specString = ($interval->invert === 1) ? '-P' : 'P';
+
+        // Adding each part to the spec-string.
+        foreach ($date as $key => $value) {
+            $specString .= $value . $key;
+        }
+        if (count($time) > 0) {
+            $specString .= 'T';
+            foreach ($time as $key => $value) {
+                $specString .= $value . $key;
+            }
+        }
 
+        return $visitor->visitSimpleString($specString, $type, $context);
+    }
+
+    public function serializeDate(XmlSerializationVisitor $visitor, \DateTime $date, array $type, Context $context)
+    {
         $v = $date->format('Y-m-d');
 
         return $visitor->visitSimpleString($v, $type, $context);
diff --git a/tests/XmlSchemaDateHandlerDeserializationTest.php b/tests/XmlSchemaDateHandlerDeserializationTest.php
index e33df0b..84e33ad 100644
--- a/tests/XmlSchemaDateHandlerDeserializationTest.php
+++ b/tests/XmlSchemaDateHandlerDeserializationTest.php
@@ -95,4 +95,35 @@ public function testDeserializeInvalidDate()
         $element = new \SimpleXMLElement("<Date>2015-01-01T</Date>");
         $this->handler->deserializeDate($this->visitor, $element, [], $this->context);
     }
+
+    /**
+     * @dataProvider getDeserializeDateInterval
+     * @param string        $interval
+     * @param \DateInterval $expected
+     */
+    public function testDeserializeDateInterval(string $interval, \DateInterval $expected)
+    {
+        $element = new \SimpleXMLElement("<DateInterval>$interval</DateInterval>");
+        $deserialized = $this->handler->deserializeDateIntervalXml($this->visitor, $element, []);
+        $this->assertEquals($expected, $deserialized);
+    }
+
+    public function getDeserializeDateInterval()
+    {
+        $interval1 = new \DateInterval('PT1M23S');
+        $interval2 = new \DateInterval('P2DT3H');
+
+        $interval1Invert = clone $interval1;
+        $interval1Invert->invert = 1;
+
+        $interval2Invert = clone $interval2;
+        $interval2Invert->invert = 1;
+
+        return [
+            ['PT1M23S', $interval1],
+            ['-PT1M23S', $interval1Invert],
+            ['P2DT3H', $interval2],
+            ['-P2DT3H', $interval2Invert],
+        ];
+    }
 }
diff --git a/tests/XmlSchemaDateHandlerSerializationTest.php b/tests/XmlSchemaDateHandlerSerializationTest.php
index f445aff..637dbaf 100644
--- a/tests/XmlSchemaDateHandlerSerializationTest.php
+++ b/tests/XmlSchemaDateHandlerSerializationTest.php
@@ -110,4 +110,36 @@ public function getSerializeDate()
             [new \DateTime('2015-01-01 12:00:56', new \DateTimeZone("Europe/London")), '2015-01-01'],
         ];
     }
+
+    /**
+     * @dataProvider getSerializeDateInterval
+     * @param \DateInterval $interval
+     * @param string        $expected
+     */
+    public function testSerializeDateInterval(\DateInterval $interval, string $expected)
+    {
+        $ret = $this->handler->serializeDateInterval($this->visitor, $interval, [], $this->context);
+
+        $actual = $ret ? $ret->nodeValue : $this->visitor->getCurrentNode()->nodeValue;
+        $this->assertEquals($expected, $actual);
+    }
+
+    public function getSerializeDateInterval()
+    {
+        $interval1 = new \DateInterval('PT1M23S');
+        $interval2 = new \DateInterval('P2DT3H');
+
+        $interval1Invert = clone $interval1;
+        $interval1Invert->invert = 1;
+
+        $interval2Invert = clone $interval2;
+        $interval2Invert->invert = 1;
+
+        return [
+            [$interval1, 'PT1M23S'],
+            [$interval1Invert, '-PT1M23S'],
+            [$interval2, 'P2DT3H'],
+            [$interval2Invert, '-P2DT3H'],
+        ];
+    }
 }