SVG sample output below, shows cropped here but in reality the entire week gets output. See also: online web app (PHP, in Finnish)
from datetime import datetime, timedelta
# Date settings
start_date = datetime(2024, 4, 1)
finnish_days = ['Maanantai', 'Tiistai', 'Keskiviikko', 'Torstai', 'Perjantai', 'Lauantai', 'Sunnuntai']
# Calculate week number
week_number = start_date.isocalendar()[1]
# Generate dates for the week, including the month number
week_dates = [(start_date + timedelta(days=i)).strftime("%d.%-m.") for i in range(7)]
# SVG adjustments
margin = 20 # Margin between days
num_hours = 14 # Number of hour slots (8-21, inclusive)
hour_height = 40
hour_number_width = 70 # Additional space for hour numbers
# Adjusted SVG dimensions to accommodate margins and hour numbers
width = 1000 + (len(finnish_days) - 1) * margin + hour_number_width
height = (num_hours + 1) * hour_height # Add extra space for the last hour
# Adjusted calculations for layout
day_width = (width - margin * (len(finnish_days) - 1) - hour_number_width) / len(finnish_days)
# Starting SVG
svg_start = f'<svg width="{width}" height="{height}" xmlns="http://www.w3.org/2000/svg" style="font-family:sans-serif;">'
# Week Number
week_number_svg = f'<text x="{width/2}" y="20" font-size="24" text-anchor="middle">Viikko {week_number}</text>'
# Drawing Days, Dates
days_svg = ''
for i, (day, date) in enumerate(zip(finnish_days, week_dates), start=1):
x_position = (i-1) * (day_width + margin) + hour_number_width
days_svg += f'<text x="{x_position + day_width/2}" y="50" font-size="20" text-anchor="middle">{day} {date}</text>'
# Drawing Hours and Shading, Adjust for Hour Number Space
hours_svg = ''
for i, hour in enumerate(range(8, 22)):
y_position = hour_height * (i + 1) + 30
shade_of_grey = "#f0f0f0" if i % 2 == 0 else "#d0d0d0"
hours_svg += f'<rect x="{hour_number_width}" y="{y_position}" width="{width - hour_number_width}" height="{hour_height}" fill="{shade_of_grey}" />'
hours_svg += f'<text x="10" y="{y_position + hour_height/2 + 5}" font-size="20" text-anchor="start">{hour}:00</text>'
# Drawing Vertical Lines on Top
lines_svg = ''
for i in range(1, len(finnish_days)):
x_position = i * (day_width + margin) + hour_number_width - margin / 2
lines_svg += f'<line x1="{x_position}" y1="60" x2="{x_position}" y2="{height}" stroke="black" stroke-width="2"/>'
# Ending SVG
svg_end = '</svg>'
# Complete SVG
svg_content = svg_start + week_number_svg + days_svg + hours_svg + lines_svg + svg_end
# Displaying or saving the SVG content
print(svg_content)