bdew_datetimes 0.12.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bdew_datetimes-0.12.0/.github/dependabot.yml +20 -0
- bdew_datetimes-0.12.0/.github/release.yml +4 -0
- bdew_datetimes-0.12.0/.github/workflows/dependabot_automerge.yml +29 -0
- bdew_datetimes-0.12.0/.github/workflows/format.yml +28 -0
- bdew_datetimes-0.12.0/.github/workflows/linters.yml +41 -0
- bdew_datetimes-0.12.0/.github/workflows/packaging_test.yml +35 -0
- bdew_datetimes-0.12.0/.github/workflows/release.yml +73 -0
- bdew_datetimes-0.12.0/.github/workflows/unittests.yml +31 -0
- bdew_datetimes-0.12.0/.gitignore +60 -0
- bdew_datetimes-0.12.0/.python-version +1 -0
- bdew_datetimes-0.12.0/LICENSE +21 -0
- bdew_datetimes-0.12.0/Makefile +43 -0
- bdew_datetimes-0.12.0/PKG-INFO +216 -0
- bdew_datetimes-0.12.0/README.md +187 -0
- bdew_datetimes-0.12.0/domain-specific-terms.txt +11 -0
- bdew_datetimes-0.12.0/pyproject.toml +175 -0
- bdew_datetimes-0.12.0/src/_bdew_datetimes_version.py +1 -0
- bdew_datetimes-0.12.0/src/bdew_datetimes/__init__.py +29 -0
- bdew_datetimes-0.12.0/src/bdew_datetimes/calendar.py +104 -0
- bdew_datetimes-0.12.0/src/bdew_datetimes/enums.py +68 -0
- bdew_datetimes-0.12.0/src/bdew_datetimes/german_strom_and_gas_tag.py +99 -0
- bdew_datetimes-0.12.0/src/bdew_datetimes/german_time_zone.py +6 -0
- bdew_datetimes-0.12.0/src/bdew_datetimes/models.py +57 -0
- bdew_datetimes-0.12.0/src/bdew_datetimes/periods.py +142 -0
- bdew_datetimes-0.12.0/src/bdew_datetimes/py.typed +2 -0
- bdew_datetimes-0.12.0/src/bdew_datetimes/utils.py +47 -0
- bdew_datetimes-0.12.0/uv.lock +513 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# To get started with Dependabot version updates, you'll need to specify which
|
|
2
|
+
# package ecosystems to update and where the package manifests are located.
|
|
3
|
+
# Please see the documentation for all configuration options:
|
|
4
|
+
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
|
5
|
+
|
|
6
|
+
version: 2
|
|
7
|
+
updates:
|
|
8
|
+
- package-ecosystem: "uv" # See documentation for possible values
|
|
9
|
+
directory: "/" # Location of package manifests
|
|
10
|
+
schedule:
|
|
11
|
+
interval: "weekly"
|
|
12
|
+
cooldown:
|
|
13
|
+
default-days: 7
|
|
14
|
+
# Maintain dependencies for GitHub Actions
|
|
15
|
+
- package-ecosystem: "github-actions"
|
|
16
|
+
directory: "/"
|
|
17
|
+
schedule:
|
|
18
|
+
interval: "daily"
|
|
19
|
+
cooldown:
|
|
20
|
+
default-days: 7
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Dependabot auto-approve / -merge
|
|
2
|
+
on: pull_request
|
|
3
|
+
|
|
4
|
+
permissions: {}
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
dependabot:
|
|
8
|
+
if: ${{ github.actor == 'dependabot[bot]' }}
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
timeout-minutes: 5
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
pull-requests: write
|
|
14
|
+
env:
|
|
15
|
+
PR_URL: ${{github.event.pull_request.html_url}}
|
|
16
|
+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v7.0.1
|
|
19
|
+
- name: Verify commit signature.
|
|
20
|
+
run: |
|
|
21
|
+
curl -s https://github.com/web-flow.gpg | gpg --import
|
|
22
|
+
echo "Imported GitHub keys."
|
|
23
|
+
|
|
24
|
+
echo "Verifying signature of commit: $GITHUB_SHA"
|
|
25
|
+
git verify-commit "$GITHUB_SHA"
|
|
26
|
+
- name: Approve a PR
|
|
27
|
+
run: gh pr review --approve "$PR_URL"
|
|
28
|
+
- name: Enable auto-merge for Dependabot PRs
|
|
29
|
+
run: gh pr merge --auto --squash "$PR_URL"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: "Format"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
|
|
9
|
+
permissions: {}
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
UV_LOCKED: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
format:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
timeout-minutes: 5
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v7.0.1
|
|
22
|
+
- name: Install uv
|
|
23
|
+
uses: astral-sh/setup-uv@v10.3.0
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.15"
|
|
26
|
+
- name: ruff ci-format
|
|
27
|
+
run: |
|
|
28
|
+
make ci-format
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: "Linters"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
|
|
9
|
+
permissions: {}
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
UV_LOCKED: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
linters:
|
|
16
|
+
name: Python Code Quality and Lint
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
timeout-minutes: 5
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
strategy:
|
|
22
|
+
matrix:
|
|
23
|
+
linter-env: ["linting", "type_check", "spell_check"]
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v7.0.1
|
|
26
|
+
- name: Install uv
|
|
27
|
+
uses: astral-sh/setup-uv@v10.3.0
|
|
28
|
+
with:
|
|
29
|
+
python-version: "3.15"
|
|
30
|
+
- name: Run linting
|
|
31
|
+
if: matrix.linter-env == 'linting'
|
|
32
|
+
run: |
|
|
33
|
+
make lint
|
|
34
|
+
- name: Run type_check
|
|
35
|
+
if: matrix.linter-env == 'type_check'
|
|
36
|
+
run: |
|
|
37
|
+
make typing
|
|
38
|
+
- name: Run spell_check
|
|
39
|
+
if: matrix.linter-env == 'spell_check'
|
|
40
|
+
run: |
|
|
41
|
+
make spell-check
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: "Packaging Test"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
|
|
9
|
+
permissions: {}
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
UV_LOCKED: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
test_packaging:
|
|
16
|
+
runs-on: ${{ matrix.os }}
|
|
17
|
+
timeout-minutes: 5
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
strategy:
|
|
21
|
+
matrix:
|
|
22
|
+
python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"]
|
|
23
|
+
os: [ubuntu-latest]
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v7.0.1
|
|
26
|
+
- name: Install uv
|
|
27
|
+
uses: astral-sh/setup-uv@v10.3.0
|
|
28
|
+
with:
|
|
29
|
+
python-version: ${{ matrix.python-version }}
|
|
30
|
+
- name: Build the package
|
|
31
|
+
run: |
|
|
32
|
+
make build
|
|
33
|
+
- name: Check the built distributions
|
|
34
|
+
run: |
|
|
35
|
+
make build-check
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# This GitHub workflow is only needed for python package releases which are supposed to be published on pypi.
|
|
2
|
+
# It requires the Github "environments" feature (see instructions below) it might not be available for private free accounts (but works for public or organization repos).
|
|
3
|
+
# After creating the "release" environment in the Github repo settings, you need to enter your Github organization/username + repo name + "release.yml" workflow file name in the PyPI UI to make this work.
|
|
4
|
+
|
|
5
|
+
# This workflow uploads a Python Package using uv when a release is created.
|
|
6
|
+
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
|
|
7
|
+
|
|
8
|
+
name: Upload Python Package
|
|
9
|
+
|
|
10
|
+
on:
|
|
11
|
+
release:
|
|
12
|
+
types: [created, edited]
|
|
13
|
+
|
|
14
|
+
permissions: {}
|
|
15
|
+
|
|
16
|
+
env:
|
|
17
|
+
UV_LOCKED: true
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
tests:
|
|
21
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
timeout-minutes: 5
|
|
24
|
+
permissions:
|
|
25
|
+
contents: read
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v7.0.1
|
|
28
|
+
- name: Install uv
|
|
29
|
+
uses: astral-sh/setup-uv@v10.3.0
|
|
30
|
+
with:
|
|
31
|
+
python-version: "3.15"
|
|
32
|
+
enable-cache: false # avoid cache poisoning
|
|
33
|
+
- name: Run the tests
|
|
34
|
+
run: |
|
|
35
|
+
make tests
|
|
36
|
+
- name: Run the type checks
|
|
37
|
+
run: |
|
|
38
|
+
make typing
|
|
39
|
+
- name: Run the linter
|
|
40
|
+
run: |
|
|
41
|
+
make lint
|
|
42
|
+
- name: Run the formatters (check only)
|
|
43
|
+
run: |
|
|
44
|
+
make ci-format
|
|
45
|
+
- name: Run the spell check
|
|
46
|
+
run: |
|
|
47
|
+
make spell-check
|
|
48
|
+
|
|
49
|
+
build-n-publish:
|
|
50
|
+
name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
timeout-minutes: 5
|
|
53
|
+
# Specifying a GitHub environment, # Specifying a GitHub environment, which is strongly recommended by PyPI: https://docs.pypi.org/trusted-publishers/adding-a-publisher/
|
|
54
|
+
# you have to create an environment in your repository settings and add the environment name here
|
|
55
|
+
environment: release
|
|
56
|
+
permissions:
|
|
57
|
+
# IMPORTANT: this permission is mandatory for trusted publishing
|
|
58
|
+
id-token: write
|
|
59
|
+
needs: tests
|
|
60
|
+
steps:
|
|
61
|
+
- uses: actions/checkout@v7.0.1
|
|
62
|
+
- name: Install uv
|
|
63
|
+
uses: astral-sh/setup-uv@v10.3.0
|
|
64
|
+
with:
|
|
65
|
+
python-version: "3.15"
|
|
66
|
+
enable-cache: false # # avoid cache poisoning
|
|
67
|
+
- name: Build wheel and source distributions
|
|
68
|
+
run: |
|
|
69
|
+
make build
|
|
70
|
+
- name: Publish distribution 📦 to PyPI
|
|
71
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
72
|
+
run: |
|
|
73
|
+
make release
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: "Unittests"
|
|
2
|
+
on:
|
|
3
|
+
pull_request:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
permissions: {}
|
|
9
|
+
|
|
10
|
+
env:
|
|
11
|
+
UV_LOCKED: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
pytest:
|
|
15
|
+
runs-on: ${{ matrix.os }}
|
|
16
|
+
timeout-minutes: 5
|
|
17
|
+
permissions:
|
|
18
|
+
contents: read
|
|
19
|
+
strategy:
|
|
20
|
+
matrix:
|
|
21
|
+
python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"]
|
|
22
|
+
os: [ubuntu-latest]
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v7.0.1
|
|
25
|
+
- name: Install uv
|
|
26
|
+
uses: astral-sh/setup-uv@v10.3.0
|
|
27
|
+
with:
|
|
28
|
+
python-version: ${{ matrix.python-version }}
|
|
29
|
+
- name: Run the Unit Tests
|
|
30
|
+
run: |
|
|
31
|
+
make tests
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Python artifacts
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.egg-info/
|
|
6
|
+
*.egg
|
|
7
|
+
build/
|
|
8
|
+
dist/
|
|
9
|
+
sdist/
|
|
10
|
+
|
|
11
|
+
# Test artifacts
|
|
12
|
+
.coverage
|
|
13
|
+
.coverage.*.*
|
|
14
|
+
.prefect-results
|
|
15
|
+
.pytest_cache/
|
|
16
|
+
|
|
17
|
+
# Type checking artifacts
|
|
18
|
+
.mypy_cache/
|
|
19
|
+
.dmypy.json
|
|
20
|
+
dmypy.json
|
|
21
|
+
.pyre/
|
|
22
|
+
|
|
23
|
+
# IPython
|
|
24
|
+
profile_default/
|
|
25
|
+
ipython_config.py
|
|
26
|
+
*.ipynb_checkpoints/*
|
|
27
|
+
|
|
28
|
+
# Profiling
|
|
29
|
+
/prof
|
|
30
|
+
|
|
31
|
+
# Environments
|
|
32
|
+
.env
|
|
33
|
+
.venv
|
|
34
|
+
env/
|
|
35
|
+
venv/
|
|
36
|
+
|
|
37
|
+
# Documentation artifacts
|
|
38
|
+
docs/api-ref/schema.json
|
|
39
|
+
site/
|
|
40
|
+
.cache/
|
|
41
|
+
|
|
42
|
+
# UI artifacts
|
|
43
|
+
src/prefect/orion/ui/*
|
|
44
|
+
**/node_modules
|
|
45
|
+
|
|
46
|
+
# Databases
|
|
47
|
+
*.db
|
|
48
|
+
|
|
49
|
+
# MacOS
|
|
50
|
+
.DS_Store
|
|
51
|
+
|
|
52
|
+
# Dask
|
|
53
|
+
dask-worker-space/
|
|
54
|
+
|
|
55
|
+
# Editors
|
|
56
|
+
.idea/
|
|
57
|
+
.vscode/
|
|
58
|
+
*.code-workspace
|
|
59
|
+
|
|
60
|
+
src/_bdew_datetimes_version.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.15
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 mj0nez
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
|
|
2
|
+
dev:
|
|
3
|
+
uv sync
|
|
4
|
+
.PHONY: dev
|
|
5
|
+
|
|
6
|
+
build:
|
|
7
|
+
uv build
|
|
8
|
+
.PHONY: build
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
build-check:
|
|
12
|
+
uv publish --dry-run -t _token_ dist/*
|
|
13
|
+
.PHONY: build-check
|
|
14
|
+
|
|
15
|
+
release:
|
|
16
|
+
uv publish
|
|
17
|
+
.PHONY: release
|
|
18
|
+
|
|
19
|
+
tests:
|
|
20
|
+
uv run pytest tests
|
|
21
|
+
.PHONY: tests
|
|
22
|
+
|
|
23
|
+
typing:
|
|
24
|
+
uv run mypy --strict src/bdew_datetimes tests
|
|
25
|
+
.PHONY: typing
|
|
26
|
+
|
|
27
|
+
lint:
|
|
28
|
+
uv run ruff check .
|
|
29
|
+
.PHONY: lint
|
|
30
|
+
|
|
31
|
+
format:
|
|
32
|
+
uv run ruff format .
|
|
33
|
+
.PHONY: format
|
|
34
|
+
|
|
35
|
+
spell-check:
|
|
36
|
+
uv run codespell --ignore-words=domain-specific-terms.txt src/bdew_datetimes README.md
|
|
37
|
+
.PHONY: spell-check
|
|
38
|
+
|
|
39
|
+
# ci-only targets
|
|
40
|
+
ci-format:
|
|
41
|
+
uv run ruff format --check .
|
|
42
|
+
uv run ruff check --select I .
|
|
43
|
+
.PHONY: format
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: bdew_datetimes
|
|
3
|
+
Version: 0.12.0
|
|
4
|
+
Summary: Generate and work with holidays of the BDEW-Calendar for power and gas in Germany
|
|
5
|
+
Project-URL: Changelog, https://github.com/mj0nez/bdew-datetimes/releases
|
|
6
|
+
Project-URL: Homepage, https://github.com/mj0nez/bdew-datetimes/
|
|
7
|
+
Author: Konstantin Klein
|
|
8
|
+
Author-email: Marcel Johannesmann <mj0nez@fn.de>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: bdew,edi@energy
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
24
|
+
Requires-Python: >=3.11
|
|
25
|
+
Requires-Dist: holidays>=0.84; python_version >= '3.10'
|
|
26
|
+
Requires-Dist: python-dateutil
|
|
27
|
+
Requires-Dist: pytz>=2022.7.1
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# bdew_datetimes
|
|
31
|
+
|
|
32
|
+

|
|
33
|
+
|
|
34
|
+
A collection of utils to work with datetimes and holidays in the German energy
|
|
35
|
+
market and is based on the [python-holiday](https://github.com/vacanza/holidays) package.
|
|
36
|
+
|
|
37
|
+
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.
|
|
38
|
+
|
|
39
|
+
### Current highlights:
|
|
40
|
+
|
|
41
|
+
- BDEW-holiday calendar
|
|
42
|
+
- allows dict like evaluation of dates and datetimes and contains all holidays considered by the BDEW
|
|
43
|
+
- Statutory Periods ("_Gesetzliche Fristen_")
|
|
44
|
+
- calculate dates of the kind "_x Werktage ab Stichtag_"
|
|
45
|
+
- calculate dates of the kind "_nter Werktag des Fristen- bzw. Liefermonats_"
|
|
46
|
+
- Gas-Day / Market Day evaluation
|
|
47
|
+
|
|
48
|
+
### Future Scope:
|
|
49
|
+
|
|
50
|
+
- providing subdivision holiday calendars to allow granular load profiles
|
|
51
|
+
|
|
52
|
+
## Quick Start and Examples
|
|
53
|
+
|
|
54
|
+
Install the package from [pypi](https://pypi.org/project/bdew-datetimes/):
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install bdew-datetimes
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Check if a date is a _specific_ BDEW Holidays
|
|
61
|
+
|
|
62
|
+
> [!NOTE]
|
|
63
|
+
> By "specific" we mean: Holidays that are neither nation- nor statewide holidays (those are defined in the [upstream package holidays](https://github.com/vacanza/holidays)) but defined by the BDEW directly.
|
|
64
|
+
> In 2025 those are: Sonderfeiertag 24h Lieferantenwechsel, Heiligabend and Silvester only.
|
|
65
|
+
|
|
66
|
+
The `HolidaySum` returned by `create_bdew_calendar` contains the BDEW specific holidays.
|
|
67
|
+
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.
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from datetime import date
|
|
71
|
+
from bdew_datetimes import create_bdew_calendar
|
|
72
|
+
|
|
73
|
+
bdew_holidays = create_bdew_calendar() # this behaves like a dict
|
|
74
|
+
|
|
75
|
+
assert date(2022, 12, 31) in bdew_holidays # Silvester is a BDEW holiday
|
|
76
|
+
assert date(2022, 8, 8) in bdew_holidays is False # Augsburger Friedensfest is _not_ a BDEW holiday (but a holiday in Augsburg only)
|
|
77
|
+
assert date(2022, 12, 2) in bdew_holidays is False # The 12th of February is not a BDEW holiday
|
|
78
|
+
|
|
79
|
+
print(bdew_holidays.get('2022-01-01')) # prints "Neujahr"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
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.
|
|
83
|
+
|
|
84
|
+
### Check if a given Date is a BDEW Working Day
|
|
85
|
+
|
|
86
|
+
BDEW working days are those days taken into account for the "Fristenberechnung".
|
|
87
|
+
The function `is_bdew_working_day` considers both national **and** state wide holidays **and** BDEW holidays:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from datetime import date
|
|
91
|
+
|
|
92
|
+
from bdew_datetimes import is_bdew_working_day
|
|
93
|
+
|
|
94
|
+
assert is_bdew_working_day(date(2023, 1, 1)) is False # Neujahr (national holiday)
|
|
95
|
+
assert is_bdew_working_day(date(2023, 1, 2)) is True # regular weekday
|
|
96
|
+
assert is_bdew_working_day(date(2023, 1, 6)) is False # Heilige Drei Könige (local holiday in parts of Germany)
|
|
97
|
+
assert is_bdew_working_day(date(2023, 4, 7)) is False # Karfreitag (national holiday, but based on an astronomical calendar)
|
|
98
|
+
assert is_bdew_working_day(date(2023, 12, 24)) is False # Heiligabend (BDEW holiday)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
You can also get the next or previous working day for any date:
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from datetime import date
|
|
105
|
+
|
|
106
|
+
from bdew_datetimes import get_next_working_day, get_previous_working_day
|
|
107
|
+
|
|
108
|
+
assert get_next_working_day(date(2023, 1, 1)) == date(2023, 1, 2) # the next working day after Neujahr
|
|
109
|
+
assert get_previous_working_day(date(2023, 1, 1)) == date(2022, 12, 30) # the last working day of 2022
|
|
110
|
+
assert get_next_working_day(date(2023, 1, 20)) == date(2023, 1, 23) # the next working day after a friday is the next monday
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Calculate Statutory Periods
|
|
114
|
+
|
|
115
|
+
Statutory periods define the maximum time between e.g. the EDIFACT message for the "Anmeldung" and the actual start of supply ("Lieferbeginn").
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
from datetime import date
|
|
119
|
+
|
|
120
|
+
from bdew_datetimes import add_frist
|
|
121
|
+
from bdew_datetimes import Period
|
|
122
|
+
from bdew_datetimes.enums import DayType, EndDateType
|
|
123
|
+
|
|
124
|
+
# Eingang der Anmeldung des LFN erfolgt am 04.07.2016. Der Mindestzeitraum von zehn WT
|
|
125
|
+
# beginnt am 05.07.2016 und endet am 18.07.2016. Frühestes zulässiges Anmeldedatum
|
|
126
|
+
# ist damit der 19.07.2016, sodass die Marktlokation dem LFN frühestens zum Beginn
|
|
127
|
+
# des vorgenannten Tages zugeordnet wird.
|
|
128
|
+
eingang_der_anmeldung = date(2016, 7, 4)
|
|
129
|
+
gesetzliche_frist = Period(
|
|
130
|
+
10,
|
|
131
|
+
DayType.WORKING_DAY,
|
|
132
|
+
end_date_type=EndDateType.EXCLUSIVE
|
|
133
|
+
# lieferbeginn is the exclusive end of the previous supply contract
|
|
134
|
+
)
|
|
135
|
+
fruehest_moeglicher_lieferbeginn = add_frist(eingang_der_anmeldung, gesetzliche_frist)
|
|
136
|
+
assert fruehest_moeglicher_lieferbeginn == date(2016, 7, 19)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Calculate "Liefer- and Fristenmonate"
|
|
140
|
+
|
|
141
|
+
Liefer- and Fristenmonat are concepts used in MaBiS and GPKE:
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from datetime import date
|
|
145
|
+
|
|
146
|
+
from bdew_datetimes import get_nth_working_day_of_month
|
|
147
|
+
from bdew_datetimes.enums import MonthType
|
|
148
|
+
|
|
149
|
+
# returns the 18th working day of the current month in Germany
|
|
150
|
+
get_nth_working_day_of_month(18)
|
|
151
|
+
|
|
152
|
+
# the 18th working day of November 2023
|
|
153
|
+
assert get_nth_working_day_of_month(18, start=date(2023, 11, 1)) == date(2023, 11, 28)
|
|
154
|
+
|
|
155
|
+
# the 42th working day of Fristenmonat July 2023
|
|
156
|
+
assert get_nth_working_day_of_month(42, month_type=MonthType.FRISTENMONAT, start=date(2023, 7, 1)) == date(2023, 9, 29)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Notes
|
|
160
|
+
|
|
161
|
+
The BDEW considers all days as holidays, which are nationwide holidays and days, which are a holiday in at least one state.
|
|
162
|
+
Furthermore, the 24. and the 31. December are holidays as well.
|
|
163
|
+
Therefore, this package utilizes the composition of all available german holiday calendars and adds the two additional days.
|
|
164
|
+
|
|
165
|
+
Shifting holidays to the next weekday if they fall on a weekend is currently not considered.
|
|
166
|
+
|
|
167
|
+
## Development
|
|
168
|
+
|
|
169
|
+
This project uses [uv](https://docs.astral.sh/uv/) for dependency management & tooling and a [GNU Makefile](https://makefiletutorial.com/) to standardize common development commands. If you want to avoid `make` you can run each command manually, in this case please still refer to the [Makefile](./Makefile).
|
|
170
|
+
|
|
171
|
+
After installing uv & make, set up the development environment with:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
make dev
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Run the tests and the individual tooling via the corresponding target:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
make tests
|
|
181
|
+
|
|
182
|
+
make typing
|
|
183
|
+
|
|
184
|
+
make lint
|
|
185
|
+
|
|
186
|
+
make format
|
|
187
|
+
|
|
188
|
+
make spell-check
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Development
|
|
192
|
+
|
|
193
|
+
This project uses [uv](https://docs.astral.sh/uv/) for dependency management and tooling.
|
|
194
|
+
After installing uv, set up the development environment with:
|
|
195
|
+
```bash
|
|
196
|
+
uv sync --group dev
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Run the tests and the individual tooling via the corresponding dependency groups:
|
|
200
|
+
```bash
|
|
201
|
+
uv run --group tests pytest
|
|
202
|
+
uv run --group type_check mypy --strict src/bdew_datetimes tests
|
|
203
|
+
uv run --group linting ruff check .
|
|
204
|
+
uv run --group linting ruff format .
|
|
205
|
+
uv run --group spell_check codespell --ignore-words=domain-specific-terms.txt src/bdew_datetimes README.md
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## License
|
|
209
|
+
|
|
210
|
+
This library is licensed under the _MIT_ license, see the [LICENSE file](LICENSE).
|
|
211
|
+
|
|
212
|
+
## Users
|
|
213
|
+
|
|
214
|
+
This library is used by the following projects:
|
|
215
|
+
|
|
216
|
+
- [Hochfrequenz Fristenkalender](https://fristenkalender.hochfrequenz.de); the respective backend is also available [online](https://fristenkalender-api.happyfield-64ecc075.westeurope.azurecontainerapps.io/docs) and as [Docker image](https://github.com/Hochfrequenz/fristenkalender-functions/pkgs/container/fristenkalender-functions)
|