#!/usr/bin/env python3.9 # -*- coding: utf-8 -*- """ JFinal TypeKit - Type Conversion Utilities """ from datetime import datetime, date, time, timedelta from decimal import Decimal, InvalidOperation import re class TypeKit: """Type conversion utility class""" _date_pattern = "yyyy-MM-dd" _date_len = len(_date_pattern) _date_time_without_second_pattern = "yyyy-MM-dd HH:mm" _date_time_without_second_len = len(_date_time_without_second_pattern) _date_time_pattern = "yyyy-MM-dd HH:mm:ss" @staticmethod def to_str(s) -> str: """Convert to string""" return str(s) if s is not None else None @staticmethod def to_int(n) -> int: """Convert to integer""" if n is None: return None if isinstance(n, int): return n if isinstance(n, float): return int(n) try: return int(str(n)) except (ValueError, TypeError): return None @staticmethod def to_long(n) -> int: """Convert to long integer""" return TypeKit.to_int(n) @staticmethod def to_float(n) -> float: """Convert to float""" if n is None: return None if isinstance(n, (int, float)): return float(n) try: return float(str(n)) except (ValueError, TypeError): return None @staticmethod def to_double(n) -> float: """Convert to double""" return TypeKit.to_float(n) @staticmethod def to_decimal(n) -> Decimal: """Convert to Decimal""" if n is None: return None if isinstance(n, Decimal): return n try: return Decimal(str(n)) except (InvalidOperation, ValueError): return None @staticmethod def to_big_decimal(n) -> Decimal: """Convert to BigDecimal""" return TypeKit.to_decimal(n) @staticmethod def to_short(n) -> int: """Convert to short integer""" result = TypeKit.to_int(n) return result if result is None else max(-32768, min(32767, result)) @staticmethod def to_byte(n) -> int: """Convert to byte integer""" result = TypeKit.to_int(n) return result if result is None else max(-128, min(127, result)) @staticmethod def to_boolean(b) -> bool: """Convert to boolean""" if b is None: return None if isinstance(b, bool): return b if isinstance(b, (int, float)): if b == 1: return True elif b == 0: return False return bool(b) if isinstance(b, str): s = str(b).lower().strip() if s in ("true", "1"): return True elif s in ("false", "0"): return False return bool(b) @staticmethod def to_number(n) -> float: """Convert to number""" if n is None: return None if isinstance(n, (int, float)): return float(n) s = str(n) if '.' in s: return float(s) else: try: return int(s) except ValueError: return float(s) @staticmethod def to_date(d): """Convert to datetime""" if d is None: return None if isinstance(d, (datetime, date)): if isinstance(d, datetime): return d else: return datetime.combine(d, time.min) if isinstance(d, str): s = str(d).strip() s_len = len(s) if s_len <= TypeKit._date_len: return TypeKit._parse_date(s, TypeKit._date_pattern) elif s_len > TypeKit._date_time_without_second_len: return TypeKit._parse_date(s, TypeKit._date_time_pattern) else: colon_count = s.count(':') if colon_count == 2: return TypeKit._parse_date(s, TypeKit._date_time_pattern) elif colon_count == 1: return TypeKit._parse_date(s, TypeKit._date_time_without_second_pattern) raise ValueError(f"Cannot convert to date: {d}") @staticmethod def _parse_date(date_string: str, pattern: str) -> datetime: """Parse date string with pattern""" try: # Simplified date parsing - supports common formats if pattern == "yyyy-MM-dd": parts = date_string.split('-') if len(parts) == 3: return datetime(int(parts[0]), int(parts[1]), int(parts[2])) elif pattern == "yyyy-MM-dd HH:mm:ss": date_part, time_part = date_string.split(' ') date_parts = date_part.split('-') time_parts = time_part.split(':') if len(date_parts) == 3 and len(time_parts) == 3: return datetime( int(date_parts[0]), int(date_parts[1]), int(date_parts[2]), int(time_parts[0]), int(time_parts[1]), int(time_parts[2]) ) elif pattern == "yyyy-MM-dd HH:mm": date_part, time_part = date_string.split(' ') date_parts = date_part.split('-') time_parts = time_part.split(':') if len(date_parts) == 3 and len(time_parts) == 2: return datetime( int(date_parts[0]), int(date_parts[1]), int(date_parts[2]), int(time_parts[0]), int(time_parts[1]) ) except (ValueError, IndexError): pass # Fallback to try parsing with dateutil or regex raise ValueError(f"Cannot parse date: {date_string}") @staticmethod def to_local_date_time(ldt): """Convert to LocalDateTime""" if ldt is None: return None if isinstance(ldt, datetime): return ldt d = TypeKit.to_date(ldt) if d: return d raise ValueError(f"Cannot convert to LocalDateTime: {ldt}")