diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/docs/difference.md | 2 | ||||
-rw-r--r-- | docs/docs/index.md | 2 | ||||
-rw-r--r-- | docs/docs/installation.md | 20 | ||||
-rw-r--r-- | docs/docs/interval.md (renamed from docs/docs/period.md) | 72 | ||||
-rw-r--r-- | docs/docs/introduction.md | 2 | ||||
-rw-r--r-- | docs/docs/limitations.md | 4 | ||||
-rw-r--r-- | docs/docs/testing.md | 94 | ||||
-rw-r--r-- | docs/docs/timezones.md | 2 |
8 files changed, 123 insertions, 75 deletions
diff --git a/docs/docs/difference.md b/docs/docs/difference.md index 3a7f063..2653f01 100644 --- a/docs/docs/difference.md +++ b/docs/docs/difference.md @@ -1,6 +1,6 @@ # Difference -The `diff()` method returns a [Period](#period) instance that represents the total duration +The `diff()` method returns an [Interval](#interval) instance that represents the total duration between two `DateTime` instances. This interval can be then expressed in various units. These interval methods always return *the total difference expressed* in the specified time requested. All values are truncated and not rounded. diff --git a/docs/docs/index.md b/docs/docs/index.md index daca205..107e043 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -12,6 +12,6 @@ {!docs/modifiers.md!} {!docs/timezones.md!} {!docs/duration.md!} -{!docs/period.md!} +{!docs/interval.md!} {!docs/testing.md!} {!docs/limitations.md!} diff --git a/docs/docs/installation.md b/docs/docs/installation.md index bfa9641..9f80e87 100644 --- a/docs/docs/installation.md +++ b/docs/docs/installation.md @@ -11,3 +11,23 @@ or, if you are using [poetry](https://python-poetry.org): ```bash $ poetry add pendulum ``` + +## Optional features + +Pendulum provides optional features that you must explicitly require in order to use them. + +These optional features are: + +- `test`: Provides a set of helpers to make testing easier by allowing you to control the flow of time. + +You can install them by specifying them when installing Pendulum + +```bash +$ pip install pendulum[test] +``` + +or, if you are using [poetry](https://python-poetry.org): + +```bash +$ poetry add pendulum[test] +``` diff --git a/docs/docs/period.md b/docs/docs/interval.md index a4dde16..fc70fb3 100644 --- a/docs/docs/period.md +++ b/docs/docs/interval.md @@ -1,6 +1,6 @@ -# Period +# Interval -When you subtract a `DateTime` instance from another, or use the `diff()` method, it will return a `Period` instance. +When you subtract a `DateTime` instance from another, or use the `diff()` method, it will return an `Interval` instance. It inherits from the [Duration](#duration) class with the added benefit that it is aware of the instances that generated it, so that it can give access to more methods and properties: @@ -10,29 +10,29 @@ instances that generated it, so that it can give access to more methods and prop >>> start = pendulum.datetime(2000, 11, 20) >>> end = pendulum.datetime(2016, 11, 5) ->>> period = end - start +>>> interval = end - start ->>> period.years +>>> interval.years 15 ->>> period.months +>>> interval.months 11 ->>> period.in_years() +>>> interval.in_years() 15 ->>> period.in_months() +>>> interval.in_months() 191 # Note that the weeks property # will change compared to the Duration class ->>> period.weeks +>>> interval.weeks 2 # 832 for the duration # However the days property will still remain the same # to keep the compatibility with the timedelta class ->>> period.days +>>> interval.days 5829 ``` -Be aware that a period, just like an interval, is compatible with the `timedelta` class regarding +Be aware that an interval, just like an duration, is compatible with the `timedelta` class regarding its attributes. However, its custom attributes (like `remaining_days`) will be aware of any DST transitions that might have occurred and adjust accordingly. Let's take an example: @@ -42,42 +42,42 @@ transitions that might have occurred and adjust accordingly. Let's take an examp >>> start = pendulum.datetime(2017, 3, 7, tz='America/Toronto') >>> end = start.add(days=6) ->>> period = end - start +>>> interval = end - start # timedelta properties ->>> period.days +>>> interval.days 5 ->>> period.seconds +>>> interval.seconds 82800 -# period properties ->>> period.remaining_days +# interval properties +>>> interval.remaining_days 6 ->>> period.hours +>>> interval.hours 0 ->>> period.remaining_seconds +>>> interval.remaining_seconds 0 ``` !!!warning Due to their nature (fixed duration between two datetimes), most arithmetic operations will - return a `Duration` instead of a `Period`. + return a `Duration` instead of an `Interval`. ```python >>> import pendulum >>> dt1 = pendulum.datetime(2016, 8, 7, 12, 34, 56) >>> dt2 = dt1.add(days=6, seconds=34) - >>> period = pendulum.period(dt1, dt2) - >>> period * 2 + >>> interval = pendulum.interval(dt1, dt2) + >>> interval * 2 Duration(weeks=1, days=5, minutes=1, seconds=8) ``` ## Instantiation -You can create an instance by using the `period()` helper: +You can create an instance by using the `interval()` helper: ```python @@ -86,29 +86,29 @@ You can create an instance by using the `period()` helper: >>> start = pendulum.datetime(2000, 1, 1) >>> end = pendulum.datetime(2000, 1, 31) ->>> period = pendulum.period(start, end) +>>> interval = pendulum.interval(start, end) ``` -You can also make an inverted period: +You can also make an inverted interval: ```python ->>> period = pendulum.period(end, start) ->>> period.remaining_days +>>> interval = pendulum.interval(end, start) +>>> interval.remaining_days -2 ``` -If you have inverted dates but want to make sure that the period is positive, +If you have inverted dates but want to make sure that the interval is positive, you should set the `absolute` keyword argument to `True`: ```python ->>> period = pendulum.period(end, start, absolute=True) ->>> period.remaining_days +>>> interval = pendulum.interval(end, start, absolute=True) +>>> interval.remaining_days 2 ``` ## Range -If you want to iterate over a period, you can use the `range()` method: +If you want to iterate over a interval, you can use the `range()` method: ```python >>> import pendulum @@ -116,9 +116,9 @@ If you want to iterate over a period, you can use the `range()` method: >>> start = pendulum.datetime(2000, 1, 1) >>> end = pendulum.datetime(2000, 1, 10) ->>> period = pendulum.period(start, end) +>>> interval = pendulum.interval(start, end) ->>> for dt in period.range('days'): +>>> for dt in interval.range('days'): >>> print(dt) '2000-01-01T00:00:00+00:00' @@ -141,7 +141,7 @@ If you want to iterate over a period, you can use the `range()` method: You can pass an amount for the passed unit to control the length of the gap: ```python ->>> for dt in period.range('days', 2): +>>> for dt in interval.range('days', 2): >>> print(dt) '2000-01-01T00:00:00+00:00' @@ -151,18 +151,18 @@ You can pass an amount for the passed unit to control the length of the gap: '2000-01-09T00:00:00+00:00' ``` -You can also directly iterate over the `Period` instance, +You can also directly iterate over the `Interval` instance, the unit will be `days` in this case: ```python ->>> for dt in period: +>>> for dt in interval: >>> print(dt) ``` -You can check if a `DateTime` instance is inside a period using the `in` keyword: +You can check if a `DateTime` instance is inside a interval using the `in` keyword: ```python >>> dt = pendulum.datetime(2000, 1, 4) ->>> dt in period +>>> dt in interval True ``` diff --git a/docs/docs/introduction.md b/docs/docs/introduction.md index fbbab97..0078b48 100644 --- a/docs/docs/introduction.md +++ b/docs/docs/introduction.md @@ -18,4 +18,4 @@ For example, all comparisons are done in `UTC` or in the timezone of the datetim 3 ``` -The default timezone, except when using the `now()`, method will always be `UTC`. +The default timezone, except when using the `now()` method, will always be `UTC`. diff --git a/docs/docs/limitations.md b/docs/docs/limitations.md index 7deff23..913aca1 100644 --- a/docs/docs/limitations.md +++ b/docs/docs/limitations.md @@ -4,7 +4,7 @@ Even though the `DateTime` class is a subclass of `datetime`, there are some rare cases where it can't replace the native class directly. Here is a list (non-exhaustive) of the reported cases with a possible solution, if any: -* `sqlite3` will use the the `type()` function to determine the type of the object by default. To work around it you can register a new adapter: +* `sqlite3` will use the `type()` function to determine the type of the object by default. To work around it you can register a new adapter: ```python import pendulum @@ -13,7 +13,7 @@ Here is a list (non-exhaustive) of the reported cases with a possible solution, register_adapter(pendulum.DateTime, lambda val: val.isoformat(' ')) ``` -* `mysqlclient` (former `MySQLdb`) and `PyMySQL` will use the the `type()` function to determine the type of the object by default. To work around it you can register a new adapter: +* `mysqlclient` (former `MySQLdb`) and `PyMySQL` will use the `type()` function to determine the type of the object by default. To work around it you can register a new adapter: ```python import pendulum diff --git a/docs/docs/testing.md b/docs/docs/testing.md index dfca054..25aad8d 100644 --- a/docs/docs/testing.md +++ b/docs/docs/testing.md @@ -1,59 +1,87 @@ # Testing -The testing methods allow you to set a `DateTime` instance (real or mock) to be returned -when a "now" instance is created. -The provided instance will be returned specifically under the following conditions: +Pendulum provides a few helpers to help you control the flow of time in your tests. Note that +these helpers are only available if you opted in the `test` extra during [installation](#installation). -* A call to the `now()` method, ex. `pendulum.now()`. -* When the string "now" is passed to the `parse()` method, ex. `pendulum.parse('now')` +!!!warning + If you are migrating from Pendulum 2, note that the `set_test_now()` and `test()` + helpers have been removed. + + +## Relative time travel + +You can travel in time relatively to the current time ```python >>> import pendulum -# Create testing datetime ->>> known = pendulum.datetime(2001, 5, 21, 12) +>>> now = pendulum.now() +>>> pendulum.travel(minutes=5) +>>> pendulum.now().diff_for_humans(now) +"5 minutes after" +``` -# Set the mock ->>> pendulum.set_test_now(known) +Note that once you've travelled in time the clock **keeps ticking**. If you prefer to stop the time completely +you can use the `freeze` parameter: ->>> print(pendulum.now()) -'2001-05-21T12:00:00+00:00' +```python +>>> import pendulum ->>> print(pendulum.parse('now')) -'2001-05-21T12:00:00+00:00' +>>> now = pendulum.now() +>>> pendulum.travel(minutes=5, freeze=True) +>>> pendulum.now().diff_for_humans(now) +"5 minutes after" # This will stay like this indefinitely +``` -# Clear the mock ->>> pendulum.set_test_now() ->>> print(pendulum.now()) -'2016-07-10T22:10:33.954851-05:00' -``` +## Absolute time travel -Related methods will also return values mocked according to the **now** instance. +Sometimes, you may want to place yourself at a specific point in time. +This is possible by using the `travel_to()` helper. This helper accepts a `DateTime` instance +that represents the point in time where you want to travel to. ```python ->>> print(pendulum.today()) -'2001-05-21T00:00:00+00:00' +>>> import pendulum ->>> print(pendulum.tomorrow()) -'2001-05-22T00:00:00+00:00' +>>> pendulum.travel_to(pendulum.yesterday()) +``` ->>> print(pendulum.yesterday()) -'2001-05-20T00:00:00+00:00' +Similarly to `travel`, it's important to remember that, by default, the time keeps ticking so, if you prefer +stopping the time, use the `freeze` parameter: + +```python +>>> import pendulum + +>>> pendulum.travel_to(pendulum.yesterday(), freeze=True) ``` -If you don't want to manually clear the mock (or you are afraid of forgetting), -you can use the provided `test()` contextmanager. +## Travelling back to the present + +Using any of the travel helpers will keep you in the past, or future, until you decide +to travel back to the present time. To do so, you may use the `travel_back()` helper. ```python >>> import pendulum ->>> known = pendulum.datetime(2001, 5, 21, 12) +>>> now = pendulum.now() +>>> pendulum.travel(minutes=5, freeze=True) +>>> pendulum.now().diff_for_humans(now) +"5 minutes after" +>>> pendulum.travel_back() +>>> pendulum.now().diff_for_humans(now) +"a few seconds after" +``` + +However, it might be cumbersome to remember to travel back so, instead, you can use any of the helpers as a context +manager: ->>> with pendulum.test(known): ->>> print(pendulum.now()) -'2001-05-21T12:00:00+00:00' +```python +>>> import pendulum ->>> print(pendulum.now()) -'2016-07-10T22:10:33.954851-05:00' +>>> now = pendulum.now() +>>> with pendulum.travel(minutes=5, freeze=True): +>>> pendulum.now().diff_for_humans(now) +"5 minutes after" +>>> pendulum.now().diff_for_humans(now) +"a few seconds after" ``` diff --git a/docs/docs/timezones.md b/docs/docs/timezones.md index 85ff147..e70034e 100644 --- a/docs/docs/timezones.md +++ b/docs/docs/timezones.md @@ -67,7 +67,7 @@ adopt the proper behavior and apply the transition accordingly. >>> dt = dt.add(microseconds=1) '2013-03-31T03:00:00+02:00' >>> dt.subtract(microseconds=1) -'2013-03-31T01:59:59.999998+01:00' +'2013-03-31T01:59:59.999999+01:00' >>> dt = pendulum.datetime(2013, 10, 27, 2, 59, 59, 999999, tz='Europe/Paris', |