初始化
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
extension DateTimeNullableX on DateTime? {
|
||||
String yyyyMMDDFormat({String gap = "-"}) {
|
||||
if (this == null) return "";
|
||||
return DateFormat("yyyy${gap}MM${gap}dd HH:mm:ss").format(this!);
|
||||
}
|
||||
|
||||
String ymdSMFormat({String gap = "-"}) {
|
||||
if (this == null) return "";
|
||||
return DateFormat("yyyy${gap}MM${gap}dd HH:mm").format(this!);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/// 可空 double 扩展
|
||||
extension DoubleNullableX on double? {
|
||||
/// 防止字段为空报错
|
||||
double em() => this ?? 0.0;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/// 通用基础类型扩展统一入口
|
||||
export 'datetime_extension.dart';
|
||||
export 'double_extension.dart';
|
||||
export 'int_extension.dart';
|
||||
export 'list_extension.dart';
|
||||
export 'map_extension.dart';
|
||||
export 'num_extension.dart';
|
||||
export 'string_extension.dart';
|
||||
@@ -0,0 +1,19 @@
|
||||
import '../hj_utils/date_time_util.dart';
|
||||
|
||||
/// 可空 int 扩展
|
||||
extension IntNullableX on int? {
|
||||
/// 人性化数量:1234 / 1.2w / 1.3亿;0、负数、null 一律 '0'
|
||||
String get countStr {
|
||||
final v = this ?? 0;
|
||||
if (v <= 0) return '0';
|
||||
if (v < 10000) return '$v';
|
||||
if (v < 100000000) return '${(v / 10000).toStringAsFixed(1)}w';
|
||||
return '${(v / 100000000).toStringAsFixed(1)}亿';
|
||||
}
|
||||
|
||||
/// 同 [countStr],但 0/null 返回 [def](按钮上显示「点赞」而不是「0」)
|
||||
String countOr(String? def) => (this ?? 0) <= 0 ? (def ?? '0') : countStr;
|
||||
|
||||
/// 秒数 → mm:ss 或 HH:mm:ss
|
||||
String get hmsStr => DateTimeUtil.formatHMS(this ?? 0);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/// 可空 List 扩展
|
||||
extension ListNullableX on List? {
|
||||
/// 长度,null 视为 0
|
||||
int em() => this?.length ?? 0;
|
||||
|
||||
/// 是否为空(null 也视为空)
|
||||
bool empty() => this == null || this!.isEmpty;
|
||||
|
||||
/// 是否非空
|
||||
bool notEmpty() => this != null && this!.isNotEmpty;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/// 可空 Map 扩展
|
||||
extension MapNullableX on Map? {
|
||||
/// 长度,null 视为 0
|
||||
int em() => this?.length ?? 0;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/// 可空 num 扩展
|
||||
extension NumNullableX on num? {
|
||||
/// 防止字段为空报错
|
||||
num em() => this ?? 0;
|
||||
|
||||
/// 数字转金额保留两位小数
|
||||
String toAmount() => em().toStringAsFixed(2);
|
||||
}
|
||||
|
||||
/// 非空 num 扩展
|
||||
extension NumX on num {
|
||||
/// 小数点截取 [fractionDigits] 位(直接截断,不四舍五入)
|
||||
String fixed(int fractionDigits) {
|
||||
final fixString = toStringAsFixed(fractionDigits + 1);
|
||||
return fixString.substring(0, fixString.length - 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import 'datetime_extension.dart';
|
||||
|
||||
/// DateFormat 构造要解析 pattern,列表里高频调用,按 pattern 缓存
|
||||
final _formatters = <String, DateFormat>{};
|
||||
|
||||
DateFormat _formatterOf(String pattern) => _formatters.putIfAbsent(pattern, () => DateFormat(pattern));
|
||||
|
||||
/// 可空字符串扩展
|
||||
extension StringNullableX on String? {
|
||||
DateTime? get _localDateTime {
|
||||
final value = this?.trim();
|
||||
if (value == null || value.isEmpty) return null;
|
||||
return DateTime.tryParse(value)?.toLocal();
|
||||
}
|
||||
|
||||
String _format(String pattern) {
|
||||
final date = _localDateTime;
|
||||
return date == null ? '' : _formatterOf(pattern).format(date);
|
||||
}
|
||||
|
||||
// ============= utc 字符串 → 各种本地格式 =============
|
||||
|
||||
/// yyyy-MM-dd HH:mm:ss
|
||||
String utcToYMDHMS() => _format('yyyy-MM-dd HH:mm:ss');
|
||||
|
||||
/// yyyy-MM-dd HH:mm
|
||||
String utcToYMDHM({String gap = '-'}) => _format('yyyy${gap}MM${gap}dd HH:mm');
|
||||
|
||||
/// yyyy-MM-dd
|
||||
String utcToYMD({String gap = '-'}) => _format('yyyy${gap}MM${gap}dd');
|
||||
|
||||
/// MM月dd日
|
||||
String utcToCnMD() {
|
||||
final date = _localDateTime;
|
||||
return date == null ? '' : '${date.month}月${date.day}日';
|
||||
}
|
||||
|
||||
/// 相对时间:"刚刚 / N分钟前 / N小时前 / N天前 / yyyy-MM-dd HH:mm"
|
||||
String utcToAgo({String gap = '-'}) {
|
||||
final date = _localDateTime;
|
||||
//解析不出:本来就是空值兜底“近期”,脏数据给空串
|
||||
if (date == null) return this?.trim().isNotEmpty == true ? '' : '近期';
|
||||
|
||||
final diff = DateTime.now().difference(date);
|
||||
final s = diff.inSeconds;
|
||||
if (s >= 0 && s < 60) return '刚刚';
|
||||
final m = diff.inMinutes;
|
||||
if (m > 0 && m < 60) return '${m + 1}分钟前';
|
||||
final h = diff.inHours;
|
||||
if (h > 0 && h < 24) return '${h + 1}小时前';
|
||||
final d = diff.inDays;
|
||||
if (d > 0 && d < 3) return '${d + 1}天前';
|
||||
return date.ymdSMFormat(gap: gap);
|
||||
}
|
||||
}
|
||||
|
||||
/// 非空字符串扩展
|
||||
extension StringX on String {
|
||||
/// 截断到最大长度
|
||||
String limit(int max) {
|
||||
if (max <= 0) return '';
|
||||
return length <= max ? this : substring(0, max);
|
||||
}
|
||||
|
||||
/// 是否含 16 个以上的 0,用于识别全零设备号(如全零 UUID)
|
||||
bool hasManyZeros() {
|
||||
const zero = 0x30; //'0'
|
||||
var count = 0;
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (codeUnitAt(i) == zero && ++count >= 16) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user