From 350ecbf867acfddd14004f5d5f9a524c4fee00fb Mon Sep 17 00:00:00 2001 From: shokollm <270575765+shokollm@users.noreply.github.com> Date: Sat, 4 Apr 2026 20:36:38 +0700 Subject: [PATCH] feat: human-readable date format with timezone awareness Add format_due_date() for human-readable dates like "4 April 2026". Update cmd_add to use timezone-aware date formatting. Fixes #54 --- apps/telegram-bot/commands.py | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/apps/telegram-bot/commands.py b/apps/telegram-bot/commands.py index ae66faa..efeafda 100644 --- a/apps/telegram-bot/commands.py +++ b/apps/telegram-bot/commands.py @@ -1,6 +1,8 @@ """Telegram command handlers for JIGAIDO - Thin wrappers around core services.""" import time +from datetime import datetime, timezone +from zoneinfo import ZoneInfo, ZoneInfoNotFoundError from functools import wraps from typing import Optional from zoneinfo import ZoneInfo, ZoneInfoNotFoundError @@ -20,6 +22,36 @@ TRACKING_SERVICE = TrackingService(TRACKING_STORAGE, ROOM_STORAGE) TELEGRAM_BOT_USERNAME = "your_bot_username" +def format_due_date(due_date_ts: int | None, timezone_str: str) -> str: + """Format due date as human-readable with timezone. + + Examples: + No due date: (none shown) + Date only: 4 April 2026 + Date + time: 4 April 2026 14:30 + With timezone: 4 April 2026 14:30 (Asia/Jakarta) + """ + if not due_date_ts: + return "" + + try: + tz = ZoneInfo(timezone_str) + except (KeyError, ZoneInfoNotFoundError): + tz = ZoneInfo("UTC") + + dt = datetime.fromtimestamp(due_date_ts, tz=tz) + + date_str = dt.strftime("%-d %B %Y") + + if dt.hour != 0 or dt.minute != 0: + date_str += f" {dt.strftime('%H:%M')}" + date_str += f" ({timezone_str})" + + return date_str + + + + def extract_args(text: str) -> list[str]: if not text: return [] @@ -239,7 +271,8 @@ async def cmd_add(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None: due_str = "" if due_date_ts: - due_str = f" | Due: {time.strftime('%Y-%m-%d', time.localtime(due_date_ts))}" + timezone_str = BOUNTY_SERVICE.get_timezone(room_id) + due_str = f" | Due: {format_due_date(due_date_ts, timezone_str)}" await update.message.reply_text( f"✅ Bounty added (#{bounty.id}){due_str}", disable_web_page_preview=True,