summaryrefslogtreecommitdiff
path: root/date_service.py
diff options
context:
space:
mode:
authormatin <matin.kaufmann@gmail.com>2025-09-12 20:45:28 +0200
committermatin <matin.kaufmann@gmail.com>2025-09-12 20:45:28 +0200
commit95d784fb414c6270e560fc0cf7ed289765ddd3ab (patch)
tree31f66d2c230634d9325beb82f1125876a3a63e30 /date_service.py
parent315bdeffd7b8c7c1a1792cb91d25ff0ac17fecda (diff)
AI refactoring (see architecture analysis and refactoring_summary)
Diffstat (limited to 'date_service.py')
-rw-r--r--date_service.py105
1 files changed, 105 insertions, 0 deletions
diff --git a/date_service.py b/date_service.py
new file mode 100644
index 0000000..4a0706a
--- /dev/null
+++ b/date_service.py
@@ -0,0 +1,105 @@
+# date_service.py
+from datetime import datetime, timedelta
+from dateutil.relativedelta import relativedelta
+from PyQt5.QtCore import QDate
+from config import EventConfig
+
+class DateService:
+ """Centralized date operations and utilities"""
+
+ @staticmethod
+ def format_date_for_display(date, format_string=None):
+ """Format a datetime object for display"""
+ if format_string is None:
+ format_string = EventConfig.DATE_FORMAT
+
+ if isinstance(date, datetime):
+ return date.strftime(format_string.replace('dd', '%d').replace('MM', '%m').replace('yyyy', '%Y'))
+ elif isinstance(date, QDate):
+ return date.toString(format_string)
+ return str(date)
+
+ @staticmethod
+ def parse_date_from_string(date_string):
+ """Parse a date string to datetime object"""
+ try:
+ return datetime.fromisoformat(date_string)
+ except ValueError:
+ # Try alternative formats
+ try:
+ return datetime.strptime(date_string, "%d.%m.%Y")
+ except ValueError:
+ raise ValueError(f"Unable to parse date string: {date_string}")
+
+ @staticmethod
+ def qdate_to_datetime(qdate):
+ """Convert QDate to datetime"""
+ if isinstance(qdate, QDate):
+ return datetime(qdate.year(), qdate.month(), qdate.day())
+ return qdate
+
+ @staticmethod
+ def datetime_to_qdate(dt):
+ """Convert datetime to QDate"""
+ if isinstance(dt, datetime):
+ return QDate(dt.year, dt.month, dt.day)
+ return dt
+
+ @staticmethod
+ def validate_date_range(start_date, end_date):
+ """Validate that start_date is not after end_date"""
+ if isinstance(start_date, str):
+ start_date = DateService.parse_date_from_string(start_date)
+ if isinstance(end_date, str):
+ end_date = DateService.parse_date_from_string(end_date)
+
+ return start_date <= end_date
+
+ @staticmethod
+ def calculate_days_between(start_date, end_date):
+ """Calculate number of days between two dates"""
+ if isinstance(start_date, str):
+ start_date = DateService.parse_date_from_string(start_date)
+ if isinstance(end_date, str):
+ end_date = DateService.parse_date_from_string(end_date)
+
+ return (end_date.date() - start_date.date()).days + 1
+
+ @staticmethod
+ def calculate_months_between(start_date, end_date):
+ """Calculate number of months between two dates using relativedelta"""
+ if isinstance(start_date, str):
+ start_date = DateService.parse_date_from_string(start_date)
+ if isinstance(end_date, str):
+ end_date = DateService.parse_date_from_string(end_date)
+
+ rd = relativedelta(end_date.date(), start_date.date())
+ return rd.years * 12 + rd.months + 1
+
+ @staticmethod
+ def format_date_for_iso(date):
+ """Format date for ISO string (yyyy-MM-dd)"""
+ if isinstance(date, datetime):
+ return date.strftime("%Y-%m-%d")
+ elif isinstance(date, QDate):
+ return date.toString("yyyy-MM-dd")
+ return str(date)
+
+ @staticmethod
+ def get_current_date():
+ """Get current date as datetime"""
+ return datetime.now()
+
+ @staticmethod
+ def add_days_to_date(date, days):
+ """Add days to a date"""
+ if isinstance(date, str):
+ date = DateService.parse_date_from_string(date)
+ return date + timedelta(days=days)
+
+ @staticmethod
+ def add_months_to_date(date, months):
+ """Add months to a date using relativedelta"""
+ if isinstance(date, str):
+ date = DateService.parse_date_from_string(date)
+ return date + relativedelta(months=months)