import 'package:intl/intl.dart'; class DateTimeUtils { static final DateFormat _dateFormat = DateFormat('yyyy-MM-dd'); static final DateFormat _timeFormat = DateFormat('HH:mm'); static final DateFormat _dateTimeFormat = DateFormat('yyyy-MM-dd HH:mm'); static final DateFormat _monthFormat = DateFormat('yyyy-MM'); static String formatDate(DateTime date) { return _dateFormat.format(date); } static String formatTime(DateTime date) { return _timeFormat.format(date); } static String formatDateTime(DateTime date) { return _dateTimeFormat.format(date); } static String formatMonth(DateTime date) { return _monthFormat.format(date); } static String formatRelative(DateTime date) { final now = DateTime.now(); final diff = now.difference(date); if (diff.inMinutes < 1) { return '刚刚'; } else if (diff.inMinutes < 60) { return '${diff.inMinutes}分钟前'; } else if (diff.inHours < 24) { return '${diff.inHours}小时前'; } else if (diff.inDays < 7) { return '${diff.inDays}天前'; } else if (diff.inDays < 30) { return '${(diff.inDays / 7).floor()}周前'; } else if (diff.inDays < 365) { return '${(diff.inDays / 30).floor()}个月前'; } else { return formatDate(date); } } static String formatSmart(DateTime date) { final now = DateTime.now(); final today = DateTime(now.year, now.month, now.day); final yesterday = today.subtract(const Duration(days: 1)); final dateDay = DateTime(date.year, date.month, date.day); if (dateDay == today) { return '今天 ${formatTime(date)}'; } else if (dateDay == yesterday) { return '昨天 ${formatTime(date)}'; } else if (now.difference(date).inDays < 7) { return formatRelative(date); } else { return formatDateTime(date); } } } class NumberUtils { static String formatCompact(int number) { if (number >= 100000000) { return '${(number / 100000000).toStringAsFixed(1)}亿'; } else if (number >= 10000) { return '${(number / 10000).toStringAsFixed(1)}万'; } else if (number >= 1000) { return '${(number / 1000).toStringAsFixed(1)}k'; } return number.toString(); } static String formatPercent(double value, {int decimals = 1}) { return '${(value * 100).toStringAsFixed(decimals)}%'; } static String formatCurrency(double value, {String symbol = '¥'}) { return '$symbol${value.toStringAsFixed(2)}'; } } class Validators { static String? required(String? value, [String? fieldName]) { if (value == null || value.trim().isEmpty) { return '请输入${fieldName ?? '内容'}'; } return null; } static String? phone(String? value) { if (value == null || value.isEmpty) { return '请输入手机号'; } if (!RegExp(r'^1[3-9]\d{9}$').hasMatch(value)) { return '请输入有效的手机号'; } return null; } static String? email(String? value) { if (value == null || value.isEmpty) { return '请输入邮箱'; } if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value)) { return '请输入有效的邮箱'; } return null; } static String? password(String? value) { if (value == null || value.isEmpty) { return '请输入密码'; } if (value.length < 6) { return '密码至少6位'; } if (value.length > 20) { return '密码最多20位'; } return null; } static String? minLength(String? value, int length, [String? fieldName]) { if (value == null || value.length < length) { return '${fieldName ?? '内容'}至少$length个字符'; } return null; } static String? maxLength(String? value, int length, [String? fieldName]) { if (value != null && value.length > length) { return '${fieldName ?? '内容'}最多$length个字符'; } return null; } }