# Elpatron's Date Calculator [![Test Coverage](https://img.shields.io/badge/test%20coverage-90%25-brightgreen)](https://github.com/elpatron/datecalc) [![Lighthouse Performance](https://img.shields.io/badge/lighthouse%20performance-100%25-brightgreen)](https://date.elpatron.me) [![Lighthouse Accessibility](https://img.shields.io/badge/lighthouse%20accessibility-100%25-brightgreen)](https://date.elpatron.me) [![Lighthouse Best Practices](https://img.shields.io/badge/lighthouse%20best%20practices-100%25-brightgreen)](https://date.elpatron.me) [![Lighthouse SEO](https://img.shields.io/badge/lighthouse%20seo-100%25-brightgreen)](https://date.elpatron.me) This modern Python web application (Flask) enables various date calculations through a clear, accessible web interface. ## Table of Contents - [Demo](#demo) - [Features](#features) - [Installation (local)](#installation-local) - [Starting the App](#starting-the-app) - [Statistics Dashboard & Password Protection](#statistics-dashboard--password-protection) - [Docker (recommended for production)](#docker-recommended-for-production) - [Mounting log directory](#mounting-log-directory-logs-stored-on-host) - [docker-compose example](#docker-compose-example) - [REST API](#rest-api) - [Days/Working days between two dates](#1-daysworking-days-between-two-dates) - [Weekday for a date](#2-weekday-for-a-date) - [Calendar week for date](#3-calendar-week-for-date) - [Start/End date of a calendar week](#4-startend-date-of-a-calendar-week) - [Date plus/minus days, weeks, months](#5-date-plusminus-days-weeks-months) - [Statistics](#6-statistics) - [Monitoring & Healthcheck](#7-monitoring--healthcheck) - [Progressive Web App (PWA)](#progressive-web-app-pwa) - [Monitoring & Healthcheck](#monitoring--healthcheck) - [Development & Notes](#development--notes) - [Automated Tests](#automated-tests) - [Notes](#notes) - [Motivation](#motivation) - [Vibe Coding](#vibe-coding) - [Statistics collection, Logging](#statistics-collection-logging) - [Accessibility](#accessibility) - [Code Statistics](#code-statistics) - [License](#license) ## Demo Date Calculator Live: [https://date.elpatron.me](https://date.elpatron.me) [![App Screenshot](./assets/image-20250725095959116.png)](https://date.elpatron.me) **[Lighthouse](https://en.wikipedia.org/wiki/Lighthouse_(software)) Performance Score:** The web application achieves excellent performance values in all categories (Performance, Accessibility, Best Practices, SEO). [Lighthouse Result (PDF)](./lighthouse/lighthouse-score.pdf) ## Features - Number of days between two dates - Number of working days between two dates (with optional consideration of state-specific holidays) - Display of the weekday of a date - Date plus/minus X days - Date plus/minus X working days - Date plus/minus X weeks/months - Calendar week for date - Start/End date of a calendar week of a year - Integrated calculator with history and speech output - Multilingual support (German/English) with automatic browser language detection - Speech output for all results (accessible) - Statistics dashboard with password protection under `/stats` ## State Holidays The working day calculation can optionally consider state-specific holidays. The free API from [feiertage-api.de](https://feiertage-api.de) is used for this purpose. **Available States:** - Baden-Württemberg (BW) - Bavaria (BY) - Berlin (BE) - Brandenburg (BB) - Bremen (HB) - Hamburg (HH) - Hesse (HE) - Mecklenburg-Vorpommern (MV) - Lower Saxony (NI) - North Rhine-Westphalia (NW) - Rhineland-Palatinate (RP) - Saarland (SL) - Saxony (SN) - Saxony-Anhalt (ST) - Schleswig-Holstein (SH) - Thuringia (TH) Holidays are automatically retrieved for the selected time period and treated as non-working days in the working day calculation. The result also shows the number of weekend days and holidays. ## Multilingual Support (i18n) The application supports German and English with the following features: ### Automatic Language Detection: - *Browser Language*: Automatic detection of browser settings - *URL Parameter*: Language selection via `?lang=de` or `?lang=en` - *localStorage*: Persistent language selection in browser - *Fallback*: German as default language ### *Privacy-friendly Implementation:* - *No Cookies*: Language selection without cookies - *URL Parameters*: Transparent language selection in URL - *localStorage*: Local storage in browser - *Shareable URLs*: URLs with language selection can be shared ### *Accessibility:* - *Screen Reader*: Full support - *Keyboard Navigation*: Fully operable - *ARIA Attributes*: Correct labels - *Semantic HTML*: Correct structure - *Calculator*: Fully accessible with keyboard operation and speech output ### *Technical Details:* - *Flask-Babel*: Professional i18n implementation - *Gettext*: Standard for translations - *Responsive Design*: Adapted for all devices - *SEO-friendly*: URLs are indexable ## Installation (local) 1. Install Python 3.8+ 2. Install dependencies: ```bash pip install -r requirements.txt ``` ## Starting the App ```bash python app.py ``` The app is then accessible at http://localhost:5000. ## Statistics Dashboard (/stats) & Password Protection The dashboard is protected with a static password that is set via the environment variable `STATS_PASSWORD`. ![Statistics page](./assets/image-20250725100127004.png) Example (PowerShell): ```powershell $env:STATS_PASSWORD = "mySecurePassword" python app.py ``` For Docker: ```powershell $env:STATS_PASSWORD = "mySecurePassword" docker run -e STATS_PASSWORD=$env:STATS_PASSWORD -p 5000:5000 datumsrechner ``` ## Docker (recommended for production) The app runs in a container with the **Gunicorn** WSGI server: ```bash docker build -t datumsrechner . docker run -p 5000:5000 datumsrechner ``` - Gunicorn starts automatically (see Dockerfile) - Recommended for production use ### Mounting log directory (Logs stored on host) To store log files outside the container, you can mount the log directory: **PowerShell Example:** ```powershell docker run -e STATS_PASSWORD=yourPassword -p 5000:5000 -v ${PWD}/log:/app/log datumsrechner ``` ### docker-compose example Create a `docker-compose.yml` file: ```yaml services: datumsrechner: build: . ports: - "5000:5000" environment: - STATS_PASSWORD=yourPassword volumes: - ./log:/app/log ``` Start with: ```bash docker-compose up --build ``` ## REST API All date functions are also available as a REST API. The API accepts and returns JSON. **Base URL:** `http://localhost:5000/api/` **Swagger Documentation:** [https://date.elpatron.me/api-docs](https://date.elpatron.me/api-docs) **Note:** The use of the REST API is evaluated in the statistics dashboard and displayed as a chart. ### Endpoints and Examples #### 1. Days/Working days between two dates **POST** `/api/tage_werktage` ```json { "start": "2024-06-01", "end": "2024-06-10", "werktage": true, "bundesland": "BY" } ``` **With curl:** ```bash curl -X POST http://localhost:5000/api/tage_werktage \ -H "Content-Type: application/json" \ -d '{"start": "2024-06-01", "end": "2024-06-10", "werktage": true, "bundesland": "BY"}' ``` **Response:** ```json { "result": 7 } ``` **Note:** The `bundesland` parameter is optional and is only considered when `"werktage": true`. Available state abbreviations see above. #### 2. Weekday for a date **POST** `/api/wochentag` ```json { "datum": "2024-06-10" } ``` **With curl:** ```bash curl -X POST http://localhost:5000/api/wochentag \ -H "Content-Type: application/json" \ -d '{"datum": "2024-06-10"}' ``` **Response:** ```json { "result": "Monday" } ``` #### 3. Calendar week for date **POST** `/api/kw_berechnen` ```json { "datum": "2024-06-10" } ``` **With curl:** ```bash curl -X POST http://localhost:5000/api/kw_berechnen \ -H "Content-Type: application/json" \ -d '{"datum": "2024-06-10"}' ``` **Response:** ```json { "result": "CW 24 (2024)", "kw": 24, "jahr": 2024 } ``` #### 4. Start/End date of a calendar week **POST** `/api/kw_datum` ```json { "jahr": 2024, "kw": 24 } ``` **With curl:** ```bash curl -X POST http://localhost:5000/api/kw_datum \ -H "Content-Type: application/json" \ -d '{"jahr": 2024, "kw": 24}' ``` **Response:** ```json { "result": "10.06.2024 to 16.06.2024", "start": "2024-06-10", "end": "2024-06-16" } ``` #### 5. Date plus/minus days, weeks, months **POST** `/api/plusminus` ```json { "datum": "2024-06-10", "anzahl": 5, "einheit": "tage", "richtung": "add", "werktage": false } ``` **With curl:** ```bash curl -X POST http://localhost:5000/api/plusminus \ -H "Content-Type: application/json" \ -d '{"datum": "2024-06-10", "anzahl": 5, "einheit": "tage", "richtung": "add", "werktage": false}' ``` **Response:** ```json { "result": "2024-06-15" } ``` **Note:** - `"einheit"`: `"tage"`, `"wochen"` or `"monate"` - `"richtung"`: `"add"` (plus) or `"sub"` (minus) - `"werktage"`: `true` for working days, otherwise `false` (only supported for `"tage"`) #### 6. Statistics **GET** `/api/stats` **With curl:** ```bash curl http://localhost:5000/api/stats ``` **Response:** ```json { "pageviews": 42, "func_counts": { "plusminus": 10, "tage_werktage": 5 }, "impressions_per_day": { "2024-06-10": 7 } } ``` #### 7. Monitoring & Healthcheck **GET** `/api/monitor` **With curl:** ```bash curl http://localhost:5000/api/monitor ``` **Response:** ```json { "status": "ok", "message": "App running", "time": "2025-07-24T13:37:00.123456", "uptime_seconds": 12345, "pageviews_last_7_days": 42 } ``` --- **Error cases** always return an HTTP status code 400 and JSON with an `"error"` field, e.g.: ```json { "error": "Invalid input", "details": "..." } ``` ## Progressive Web App (PWA) Elpatron's Date Calculator is installable as a PWA (e.g., on Android/iOS home screen or desktop). The app works offline for the homepage and static resources, date calculation remains server-side. - Manifest and Service Worker are integrated - App icon and theme color for home screen - Installation via browser menu ("Add to home screen") - Calculator works completely client-side (available offline) ## Monitoring & Healthcheck The app provides a monitoring endpoint at `/monitor` that returns status information as JSON (e.g., for Uptime Robot, Docker Healthcheck or own tools): - Status (ok) - Current server time - Uptime (seconds since start) - Pageviews of the last 7 days Example call: `GET https://date.elpatron.me/monitor` Response: ```json { "status": "ok", "message": "App running", "time": "2025-07-24T13:37:00.123456", "uptime_seconds": 12345, "pageviews_last_7_days": 42 } ``` ## Development & Notes - HTML templates are in the `templates/` folder (separation of logic and presentation) - The project is hosted on Codeberg: [https://codeberg.org/elpatron/datecalc](https://codeberg.org/elpatron/datecalc) - Modern, responsive design with accordion and icons ## Automated Tests Automated tests are possible with pytest: ```powershell pip install -r requirements.txt pytest test_app.py ``` The tests check, among other things, the accessibility of the app, the most important functions, and protection against XSS attacks. ## Notes ### Motivation Try to find a date calculator web app that isn't completely riddled with ads and tracking! Since I need something like this more often, I made my own. ### Vibe Coding This project was created almost 100% with the support of artificial intelligence (*[Vibe Coding](https://en.wikipedia.org/wiki/Vibe_Coding)*). The basic framework was completed after about 45 minutes, and the total development of the project took about 12 hours. ### Statistics collection, Logging No IP addresses or other personal data are stored, only the number of function calls in a cumulative representation. The log file only contains entries from the last seven days. ### Accessibility *Elpatron's Date Calculator* is designed to be accessible and meets central accessibility (a11y) requirements: - *Semantic HTML Structure:* Headings, labels, and form elements are correctly marked and linked. - *ARIA Attributes:* Accordion and status messages are equipped with ARIA attributes so that screen readers can recognize the structure and states. - *Keyboard Operability:* All interactive elements (accordion, buttons, forms) are fully operable by keyboard (including focus indicator and arrow key navigation in accordion). - *Focus Indicators:* Clear visual highlighting of focus for all control elements. - *Color Contrasts:* High contrasts for texts, buttons, and result boxes, tested according to WCAG guidelines. - *Status and Error Messages:* Results and errors are made accessible to screen readers with `aria-live`. - *Speech Output:* All results can be read aloud via 🔊 buttons (Web Speech API, German language). - *Calculator:* Fully accessible with keyboard operation, speech output, and history function. - *Mobile Optimization:* Additional meta tags for better usability on mobile devices and support for screen readers. - *SEO:* The accessibility topic is visible in meta tags for search engines. This makes the app well usable for people with different disabilities (e.g., visual impairment, motor limitations) and meets modern web standards. ### Code Statistics cloc|github.com/AlDanial/cloc v 2.06 T=0.22 s (124.7 files/s, 34058.5 lines/s) --- | --- Language|files|blank|comment|code :-------|-------:|-------:|-------:|-------: HTML|8|159|8|2806 Markdown|5|340|0|876 Python|2|68|76|744 JavaScript|2|95|88|580 PO File|2|260|266|544 JSON|3|0|0|243 CSS|1|186|3|188 XML|1|10|4|69 SVG|2|0|0|14 Dockerfile|1|5|6|8 DOS Batch|1|0|0|1 --------|--------|--------|--------|-------- SUM:|28|1123|451|6073 ## License This project is licensed under the [MIT License](LICENSE). --- (c) 2025 [Markus Busche](https://digitalcourage.social/@elpatron) **Version 1.4.12** - Integrated calculator with history and speech output added