- commit
- 363d9a24147468444915fdc62357462d0ab01ce5
- parent
- 553add86af32354eec4808ad7327418adfcc35c6
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2024-08-31 01:49
add README
Diffstat
| A | README.md | 89 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 files changed, 89 insertions, 0 deletions
diff --git a/README.md b/README.md
@@ -0,0 +1,89 @@
-1 1 # nominaldelta - nominal difference of date/datetime
-1 2
-1 3 Python's [`datetime` module][1] is great: It has `ordinal` and `timestamp` as
-1 4 absolute values, and `date` and `datetime` as nominal ones for the Gregorian
-1 5 calendar. The only issue is `timedelta`: It is really an absolute delta, so
-1 6 basically the same as `date1.toordinal() - date2.toordinal()` or
-1 7 `dt1.timestamp() - dt2.timestamp()`.
-1 8
-1 9 The third party library [python-dateutil][2] adds `relativedelta`, which is a
-1 10 nominal delta. However, it acts as if every day had 24 hours, which is not
-1 11 quite true.
-1 12
-1 13 So this is an attempt to add a proper nominal delta.
-1 14
-1 15 ## Example
-1 16
-1 17 ```python
-1 18 >>> from datetime import date
-1 19 >>> from datetime import datetime
-1 20 >>> from zoneinfo import ZoneInfo
-1 21 >>> from nominaldelta import NominalDelta
-1 22
-1 23 # adding months does what you would expect
-1 24 >>> datetime(1970, 1, 15, 13) + NominalDelta(months=1)
-1 25 datetime(1970, 2, 15, 13)
-1 26
-1 27 # for shorter months, result are clipped to the last day of the month
-1 28 >>> datetime(1970, 1, 30, 13) + NominalDelta(months=1)
-1 29 datetime(1970, 2, 28, 13)
-1 30
-1 31 # daylight saving time is handled correctly
-1 32 >>> tz = ZoneInfo('Europe/Berlin')
-1 33 >>> datetime(2019, 3, 31, 3, 1, tzinfo=tz) - NominalDelta(minutes=2)
-1 34 datetime(2019, 3, 31, 1, 59, tzinfo=tz)
-1 35
-1 36 # you can compute top-heavy differences
-1 37 >>> delta = NominalDelta.diff(date(1970, 1, 1), date.today())
-1 38 >>> f'{delta.months // 12} years'
-1 39 '54 years'
-1 40 ```
-1 41
-1 42 ## Status
-1 43
-1 44 This is just an experiment, so I did not publish it to pypi. Feel free to open
-1 45 an issue if you think this should be published.
-1 46
-1 47 ## Usage
-1 48
-1 49 ### `class NominalDelta(years, months, weeks, days, hours, minutes, seconds)`
-1 50
-1 51 All values are optional and default to 0.
-1 52
-1 53 `NominalDelta` only stores months, days, and seconds. All other values are
-1 54 converted to one of them:
-1 55
-1 56 - `years` are converted to 12 months
-1 57 - `weeks` are converted to 7 days
-1 58 - `hours` are converted to 3600 seconds
-1 59 - `minutes` are converted to 60 seconds
-1 60 - `seconds` can be a float to represent milli- and micoseconds
-1 61
-1 62 Notably, `NominalDelta` avoids to perpetuate some common misconceptions:
-1 63
-1 64 - `years` are not converted to 365 days because leap years have 366 days
-1 65 - `days` are not converted to 24 hours because of daylight saving time. Also,
-1 66 days with leap seconds have an extra second.
-1 67
-1 68 The three values are independent from each other. Seconds are never converted
-1 69 to days, and days are never converted to months.
-1 70
-1 71 ### `a + NominalDelta()`
-1 72
-1 73 When a `NominalDelta` is added to a `date` or `datetime`, the months are added
-1 74 first. If the original day does not exist in that month (e.g. there is no
-1 75 1970-02-30), the last day of that month is used instead. Days are added after
-1 76 that and seconds are added last.
-1 77
-1 78 When adding to a `date`, seconds are ignored.
-1 79
-1 80 ### `NominalDelta.diff(a, b)`
-1 81
-1 82 Calculate the delta between two `date` or `datetime` objects. This will first
-1 83 check how many months can be added without overshooting. Then it will check how
-1 84 many days can be added on top of the month. Last, the remaining difference in
-1 85 seconds is calculated. This approach is called "top heavy" because it
-1 86 prioritizes larger units over smaller ones.
-1 87
-1 88 [1]: https://docs.python.org/3/library/datetime.html
-1 89 [2]: https://github.com/dateutil/dateutil