Repository: sdispater/pendulum

Issue:
Expose ParserError exception to top level imports
Currently if you want to catch the `ParserError` when calling `pendulum.parse('string')`, you have to catch it with:

```
try:
  pendulum.parse('string')
except pendulum.parsing.exceptions.ParserError:
  pass
```

unless you've explicitly imported that part of the module in. There is already a `pendulum.exceptions`, so is there any reason why the `ParserError` couldn't be put into that same module or imported into the base init? I can make the PR for it, I just wanted to get clarity around whether this was by design or if it was something that wasn't a use case. I don't want to catch `ValueError`, mostly because that's not the exception being thrown. 

Comments:

Patch:
diff --git a/pendulum/exceptions.py b/pendulum/exceptions.py
index 2695c6d..b777018 100644
--- a/pendulum/exceptions.py
+++ b/pendulum/exceptions.py
@@ -1,5 +1,7 @@
 # -*- coding: utf-8 -*-
 
+from .parsing.exceptions import ParserError
+
 
 class PendulumException(BaseException):
 
diff --git a/pendulum/formatting/difference_formatter.py b/pendulum/formatting/difference_formatter.py
index 771f756..e3457e3 100644
--- a/pendulum/formatting/difference_formatter.py
+++ b/pendulum/formatting/difference_formatter.py
@@ -63,9 +63,9 @@ class DifferenceFormatter(object):
 
             if diff.remaining_days > 3:
                 count += 1
-        elif diff.days > 0:
+        elif diff.remaining_days > 0:
             unit = 'day'
-            count = diff.days
+            count = diff.remaining_days
         elif diff.hours > 0:
             unit = 'hour'
             count = diff.hours
diff --git a/pendulum/period.py b/pendulum/period.py
index 2966c68..82b0abb 100644
--- a/pendulum/period.py
+++ b/pendulum/period.py
@@ -99,6 +99,14 @@ class Period(WordableIntervalMixin, BaseInterval):
     def remaining_days(self):
         return abs(self._delta['days']) % 7 * self._sign(self._days)
 
+    @property
+    def hours(self):
+        return self._delta['hours']
+
+    @property
+    def minutes(self):
+        return self._delta['minutes']
+
     @property
     def start(self):
         return self._start


Test patch:
diff --git a/tests/date_tests/test_diff.py b/tests/date_tests/test_diff.py
index 1ba9a5a..a84b1f1 100644
--- a/tests/date_tests/test_diff.py
+++ b/tests/date_tests/test_diff.py
@@ -284,6 +284,17 @@ class DiffTest(AbstractTestCase):
         self.assertEqual('1 year', Date.today().diff_for_humans(Date.today().subtract(years=1), True))
         self.assertEqual('1 year', Date.today().diff_for_humans(Date.today().add(years=1), True))
 
+    def test_diff_accuracy(self):
+        # DST
+        today = Pendulum.create(2017, 3, 7, tz='America/Toronto')
+
+        with self.wrap_with_test_now(today):
+            diff = today.add(days=6).diff(today, abs=True)
+            self.assertEqual(5, diff.days)
+            self.assertEqual(6, diff.remaining_days)
+            self.assertEqual(0, diff.hours)
+            self.assertEqual('6 days', diff.in_words())
+
     def test_diff_for_humans_accuracy(self):
         today = Pendulum.today()
 
@@ -297,6 +308,11 @@ class DiffTest(AbstractTestCase):
             self.assertEqual('2 weeks', today.add(days=14).diff_for_humans(absolute=True))
             self.assertEqual('2 weeks', today.add(days=13).diff_for_humans(absolute=True))
 
+        # DST
+        today = Pendulum.create(2017, 3, 7, tz='America/Toronto')
+        with self.wrap_with_test_now(today):
+            self.assertEqual('6 days', today.add(days=6).diff_for_humans(absolute=True))
+
     def test_subtraction(self):
         d = Date(2016, 7, 5)
         future_dt = date(2016, 7, 6)
diff --git a/tests/pendulum_tests/test_diff.py b/tests/pendulum_tests/test_diff.py
index a633a32..c0f2e6d 100644
--- a/tests/pendulum_tests/test_diff.py
+++ b/tests/pendulum_tests/test_diff.py
@@ -573,6 +573,11 @@ class DiffTest(AbstractTestCase):
             self.assertEqual('1 year', now.add(years=1, months=3).diff_for_humans(absolute=True))
             self.assertEqual('2 years', now.add(years=1, months=8).diff_for_humans(absolute=True))
 
+        # DST
+        now = Pendulum.create(2017, 3, 7, tz='America/Toronto')
+        with self.wrap_with_test_now(now):
+            self.assertEqual('6 days', now.add(days=6).diff_for_humans(absolute=True))
+
     def test_seconds_since_midnight(self):
         d = Pendulum.create(2016, 7, 5, 12, 32, 25, 0)
         self.assertEqual(25 + 32 * 60 + 12 * 3600, d.seconds_since_midnight())