初始提交,未完全测试
This commit is contained in:
206
kit/TypeKit.py
Normal file
206
kit/TypeKit.py
Normal file
@@ -0,0 +1,206 @@
|
||||
#!/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}")
|
||||
Reference in New Issue
Block a user