Files
datecalc/README_en.md
2025-08-04 11:50:52 +02:00

512 lines
14 KiB
Markdown

# Elpatrons 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