bdew-datetimes


Namebdew-datetimes JSON
Version 0.4.0 PyPI version JSON
download
home_page
SummaryGenerate and work with holidays of the BDEW-Calendar for power and gas in Germany
upload_time2024-01-03 10:52:13
maintainer
docs_urlNone
authorKonstantin Klein
requires_python>=3.8
licenseMIT
keywords bdew edi@energy
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # bdew_datetimes
![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/mj0nez/bdew-datetimes/packaging_test.yml?style=plastic)![PyPI - Python Version](https://img.shields.io/pypi/pyversions/bdew-datetimes?style=plastic)![PyPI - License](https://img.shields.io/pypi/l/bdew-datetimes?style=plastic)![PyPI](https://img.shields.io/pypi/v/bdew-datetimes?style=plastic)

A collection of utils to work with datetimes and holidays in the German energy
market and is based on the [python-holiday](https://github.com/dr-prodigy/python-holidays) package.

The implementation considers the publications of the **BDEW** (Bundesverband der Energie- und Wasserwirtschaft e. V.) and **EDI@Energy**, which provide boundaries and guidance for the data exchange on the german energy market. 

### Current highlights:
* BDEW-holiday calendar
    * allows dict like evaluation of dates and datetimes and contains all holidays considered by the BDEW
* Statutory Periods ("_Gesetzliche Fristen_")
    * calculate dates of the kind "_x Werktage ab Stichtag_"
    * calculate dates of the kind "_nter Werktag des Fristen- bzw. Liefermonats_"
* Gas-Day / Market Day evaluation

### Future Scope:

* providing subdivision holiday calendars to allow granular load profiles


## Quick Start and Examples

Install the package from [pypi](https://pypi.org/project/bdew-datetimes/):
```bash
pip install bdew-datetimes
```

### Check if a date is a _specific_ BDEW Holidays

The `HolidaySum` returned by `create_bdew_calendar` contains the BDEW specific holidays.
This means it contains those holidays which are _defined_ by BDEW which includes Heiligabend and Silvester as well as special days without Marktkommunikation but _not_ the local or nationwide holidays in Germany and its states. 
```python
from datetime import date
from bdew_datetimes import create_bdew_calendar

bdew_holidays = create_bdew_calendar()  # this behaves like a dict

assert date(2022, 12, 31) in bdew_holidays # Silvester is a BDEW holiday
assert date(2022, 8, 8) in bdew_holidays is False # Augsburger Friedensfest is _not_ a BDEW holiday (but a holiday in Augsburg only)
assert date(2022, 12, 2) in bdew_holidays is False # The 12th of February is not a BDEW holiday

print(bdew_holidays.get('2022-01-01'))  # prints "Neujahr"
```
The **union** (type `HolidaySum`) of both nation and state wide holidays **and** the BDEW holidays (only the latter is returned by `create_bdew_calendar`) is the relevant calendar for German utilities.

### Check if a given Date is a BDEW Working Day
BDEW working days are those days taken into account for the "Fristenberechnung".
The function `is_bdew_working_day` considers both national and state wide holidays as well as BDEW holidays:
```python
from datetime import date

from bdew_datetimes.periods import is_bdew_working_day

assert is_bdew_working_day(date(2023, 1, 1)) is False  # Neujahr (national holiday)
assert is_bdew_working_day(date(2023, 1, 2)) is True  # regular weekday
assert is_bdew_working_day(date(2023, 1, 6)) is False  # Heilige Drei Könige (local holiday in parts of Germany)
assert is_bdew_working_day(date(2023, 4, 7)) is False  # Karfreitag (national holiday, but based on an astronomical calendar)
assert is_bdew_working_day(date(2023, 12, 24)) is False  # Heiligabend (BDEW holiday)
```

You can also get the next or previous working day for any date:
```python
from datetime import date

from bdew_datetimes.periods import get_next_working_day, get_previous_working_day

assert get_next_working_day(date(2023, 1, 1)) == date(2023, 1, 2)  # the next working day after Neujahr
assert get_previous_working_day(date(2023, 1, 1)) == date(2022, 12, 30)  # the last working day of 2022
assert get_next_working_day(date(2023, 1, 20)) == date(2023, 1, 23)  # the next working day after a friday is the next monday
```

### Calculate Statutory Periods
Statutory periods define the maximum time between e.g. the EDIFACT message for the "Anmeldung" and the actual start of supply ("Lieferbeginn").
```python
from datetime import date

from bdew_datetimes.periods import DayType, EndDateType, Period, add_frist

# Eingang der Anmeldung des LFN erfolgt am 04.07.2016. Der Mindestzeitraum von zehn WT
# beginnt am 05.07.2016 und endet am 18.07.2016. Frühestes zulässiges Anmeldedatum
# ist damit der 19.07.2016, sodass die Marktlokation dem LFN frühestens zum Beginn
# des vorgenannten Tages zugeordnet wird.
eingang_der_anmeldung = date(2016, 7, 4)
gesetzliche_frist = Period(
    10,
    DayType.WORKING_DAY,
    end_date_type=EndDateType.EXCLUSIVE
    # lieferbeginn is the exclusive end of the previous supply contract
)
fruehest_moeglicher_lieferbeginn = add_frist(eingang_der_anmeldung, gesetzliche_frist)
assert fruehest_moeglicher_lieferbeginn == date(2016, 7, 19)
```
### Calculate "Liefer- and Fristenmonate"
Liefer- and Fristenmonat are concepts used in MaBiS and GPKE:
```python
from datetime import date

from bdew_datetimes.periods import get_nth_working_day_of_month, MonthType

# returns the 18th working day of the current month in Germany
get_nth_working_day_of_month(18)

# the 18th working day of November 2023
assert get_nth_working_day_of_month(18, start=date(2023, 11, 1)) == date(2023, 11, 28)

# the 42th working day of Fristenmonat July 2023
assert get_nth_working_day_of_month(42, month_type=MonthType.FRISTENMONAT, start=date(2023, 7, 1)) == date(2023, 9, 29)
```

## Notes

The BDEW considers all days as holidays, which are nationwide holidays and days, which are a holiday in at least one state.
Furthermore, the 24. and the 31. December are holidays as well.
Therefore, this package utilizes the composition of all available german holiday calendars and adds the two additional days.

Shifting holidays to the next weekday if they fall on a weekend is currently not considered.  


## License

This library is licensed under the *MIT* license, see the [LICENSE file](LICENSE).

## Users
This library is used by the following projects:
- [Hochfrequenz Fristenkalender](https://www.hochfrequenz.de/#fristenkalender)

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "bdew-datetimes",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "",
    "keywords": "bdew,edi@energy",
    "author": "Konstantin Klein",
    "author_email": "Marcel Johannesmann <mj0nez@fn.de>",
    "download_url": "https://files.pythonhosted.org/packages/35/30/a8aa4e6d9d485b6acd30d706c4836afdab47ae8a0c9ec4bf3fef2e9f3eb7/bdew_datetimes-0.4.0.tar.gz",
    "platform": null,
    "description": "# bdew_datetimes\n![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/mj0nez/bdew-datetimes/packaging_test.yml?style=plastic)![PyPI - Python Version](https://img.shields.io/pypi/pyversions/bdew-datetimes?style=plastic)![PyPI - License](https://img.shields.io/pypi/l/bdew-datetimes?style=plastic)![PyPI](https://img.shields.io/pypi/v/bdew-datetimes?style=plastic)\n\nA collection of utils to work with datetimes and holidays in the German energy\nmarket and is based on the [python-holiday](https://github.com/dr-prodigy/python-holidays) package.\n\nThe implementation considers the publications of the **BDEW** (Bundesverband der Energie- und Wasserwirtschaft e. V.) and **EDI@Energy**, which provide boundaries and guidance for the data exchange on the german energy market. \n\n### Current highlights:\n* BDEW-holiday calendar\n    * allows dict like evaluation of dates and datetimes and contains all holidays considered by the BDEW\n* Statutory Periods (\"_Gesetzliche Fristen_\")\n    * calculate dates of the kind \"_x Werktage ab Stichtag_\"\n    * calculate dates of the kind \"_nter Werktag des Fristen- bzw. Liefermonats_\"\n* Gas-Day / Market Day evaluation\n\n### Future Scope:\n\n* providing subdivision holiday calendars to allow granular load profiles\n\n\n## Quick Start and Examples\n\nInstall the package from [pypi](https://pypi.org/project/bdew-datetimes/):\n```bash\npip install bdew-datetimes\n```\n\n### Check if a date is a _specific_ BDEW Holidays\n\nThe `HolidaySum` returned by `create_bdew_calendar` contains the BDEW specific holidays.\nThis means it contains those holidays which are _defined_ by BDEW which includes Heiligabend and Silvester as well as special days without Marktkommunikation but _not_ the local or nationwide holidays in Germany and its states. \n```python\nfrom datetime import date\nfrom bdew_datetimes import create_bdew_calendar\n\nbdew_holidays = create_bdew_calendar()  # this behaves like a dict\n\nassert date(2022, 12, 31) in bdew_holidays # Silvester is a BDEW holiday\nassert date(2022, 8, 8) in bdew_holidays is False # Augsburger Friedensfest is _not_ a BDEW holiday (but a holiday in Augsburg only)\nassert date(2022, 12, 2) in bdew_holidays is False # The 12th of February is not a BDEW holiday\n\nprint(bdew_holidays.get('2022-01-01'))  # prints \"Neujahr\"\n```\nThe **union** (type `HolidaySum`) of both nation and state wide holidays **and** the BDEW holidays (only the latter is returned by `create_bdew_calendar`) is the relevant calendar for German utilities.\n\n### Check if a given Date is a BDEW Working Day\nBDEW working days are those days taken into account for the \"Fristenberechnung\".\nThe function `is_bdew_working_day` considers both national and state wide holidays as well as BDEW holidays:\n```python\nfrom datetime import date\n\nfrom bdew_datetimes.periods import is_bdew_working_day\n\nassert is_bdew_working_day(date(2023, 1, 1)) is False  # Neujahr (national holiday)\nassert is_bdew_working_day(date(2023, 1, 2)) is True  # regular weekday\nassert is_bdew_working_day(date(2023, 1, 6)) is False  # Heilige Drei K\u00f6nige (local holiday in parts of Germany)\nassert is_bdew_working_day(date(2023, 4, 7)) is False  # Karfreitag (national holiday, but based on an astronomical calendar)\nassert is_bdew_working_day(date(2023, 12, 24)) is False  # Heiligabend (BDEW holiday)\n```\n\nYou can also get the next or previous working day for any date:\n```python\nfrom datetime import date\n\nfrom bdew_datetimes.periods import get_next_working_day, get_previous_working_day\n\nassert get_next_working_day(date(2023, 1, 1)) == date(2023, 1, 2)  # the next working day after Neujahr\nassert get_previous_working_day(date(2023, 1, 1)) == date(2022, 12, 30)  # the last working day of 2022\nassert get_next_working_day(date(2023, 1, 20)) == date(2023, 1, 23)  # the next working day after a friday is the next monday\n```\n\n### Calculate Statutory Periods\nStatutory periods define the maximum time between e.g. the EDIFACT message for the \"Anmeldung\" and the actual start of supply (\"Lieferbeginn\").\n```python\nfrom datetime import date\n\nfrom bdew_datetimes.periods import DayType, EndDateType, Period, add_frist\n\n# Eingang der Anmeldung des LFN erfolgt am 04.07.2016. Der Mindestzeitraum von zehn WT\n# beginnt am 05.07.2016 und endet am 18.07.2016. Fr\u00fchestes zul\u00e4ssiges Anmeldedatum\n# ist damit der 19.07.2016, sodass die Marktlokation dem LFN fr\u00fchestens zum Beginn\n# des vorgenannten Tages zugeordnet wird.\neingang_der_anmeldung = date(2016, 7, 4)\ngesetzliche_frist = Period(\n    10,\n    DayType.WORKING_DAY,\n    end_date_type=EndDateType.EXCLUSIVE\n    # lieferbeginn is the exclusive end of the previous supply contract\n)\nfruehest_moeglicher_lieferbeginn = add_frist(eingang_der_anmeldung, gesetzliche_frist)\nassert fruehest_moeglicher_lieferbeginn == date(2016, 7, 19)\n```\n### Calculate \"Liefer- and Fristenmonate\"\nLiefer- and Fristenmonat are concepts used in MaBiS and GPKE:\n```python\nfrom datetime import date\n\nfrom bdew_datetimes.periods import get_nth_working_day_of_month, MonthType\n\n# returns the 18th working day of the current month in Germany\nget_nth_working_day_of_month(18)\n\n# the 18th working day of November 2023\nassert get_nth_working_day_of_month(18, start=date(2023, 11, 1)) == date(2023, 11, 28)\n\n# the 42th working day of Fristenmonat July 2023\nassert get_nth_working_day_of_month(42, month_type=MonthType.FRISTENMONAT, start=date(2023, 7, 1)) == date(2023, 9, 29)\n```\n\n## Notes\n\nThe BDEW considers all days as holidays, which are nationwide holidays and days, which are a holiday in at least one state.\nFurthermore, the 24. and the 31. December are holidays as well.\nTherefore, this package utilizes the composition of all available german holiday calendars and adds the two additional days.\n\nShifting holidays to the next weekday if they fall on a weekend is currently not considered.  \n\n\n## License\n\nThis library is licensed under the *MIT* license, see the [LICENSE file](LICENSE).\n\n## Users\nThis library is used by the following projects:\n- [Hochfrequenz Fristenkalender](https://www.hochfrequenz.de/#fristenkalender)\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Generate and work with holidays of the BDEW-Calendar for power and gas in Germany",
    "version": "0.4.0",
    "project_urls": {
        "Changelog": "https://github.com/mj0nez/bdew-datetimes/releases",
        "Homepage": "https://github.com/mj0nez/bdew-datetimes/"
    },
    "split_keywords": [
        "bdew",
        "edi@energy"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0cec8a3e7422d8ac83dfb47dc3aa927c057cec173dec5ec4917a5441437ed344",
                "md5": "c04b46108dcb7015909d09c03a832074",
                "sha256": "7d474bbabcc794c67309439a71c1a518b0eae8e74bf159f11fa1d1de55a73c7d"
            },
            "downloads": -1,
            "filename": "bdew_datetimes-0.4.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c04b46108dcb7015909d09c03a832074",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 10747,
            "upload_time": "2024-01-03T10:52:12",
            "upload_time_iso_8601": "2024-01-03T10:52:12.122517Z",
            "url": "https://files.pythonhosted.org/packages/0c/ec/8a3e7422d8ac83dfb47dc3aa927c057cec173dec5ec4917a5441437ed344/bdew_datetimes-0.4.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3530a8aa4e6d9d485b6acd30d706c4836afdab47ae8a0c9ec4bf3fef2e9f3eb7",
                "md5": "a4fd6181c63cf2a6df21a287c042466d",
                "sha256": "9e99d04f4f619db185c5d1e3c810c3a2077abd2d7f7a17f03d15303ca489aa0b"
            },
            "downloads": -1,
            "filename": "bdew_datetimes-0.4.0.tar.gz",
            "has_sig": false,
            "md5_digest": "a4fd6181c63cf2a6df21a287c042466d",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 15314,
            "upload_time": "2024-01-03T10:52:13",
            "upload_time_iso_8601": "2024-01-03T10:52:13.751138Z",
            "url": "https://files.pythonhosted.org/packages/35/30/a8aa4e6d9d485b6acd30d706c4836afdab47ae8a0c9ec4bf3fef2e9f3eb7/bdew_datetimes-0.4.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-01-03 10:52:13",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "mj0nez",
    "github_project": "bdew-datetimes",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "tox": true,
    "lcname": "bdew-datetimes"
}
        
Elapsed time: 0.15896s