nominaldelta

nominal difference of date/datetime
git clone https://git.ce9e.org/nominaldelta.git

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