中文 | English | 自动选择语言(GitHub Pages)
Swift 常用转换工具库(默认中文语境):
- 默认日期上下文:
zh_CN + Asia/Shanghai + Gregorian - 覆盖:单位换算、日期时间、金额、百分比、颜色、字符串校验与格式化、设备与应用信息
说明:通过 Swift Package Manager 引入 SDK。
https://github.com/snoux/SwiftUtilityKitimport SwiftUtilityKit // 在代码文件中导入 SDK说明:以下示例全部使用默认上下文(不传 in: cn)。
let out = try "2026-03-10 08:00:00".dateString(to: .dateMinuteSlash) // 自动识别输入并输出为 yyyy/MM/dd HH:mmlet ref = try "2026-03-10 12:00:00".date(.dateTime) // 解析参考时间
let ok = try "2026-03-09 12:00:00".isYesterday(ref: ref) // 判断目标时间是否是参考时间的昨天let ref = try "2026-03-10 12:00:00".date(.dateTime) // 解析参考时间
let target = try "2026-03-09 12:00:00".date(.dateTime) // 解析目标时间
let ok = target.isYesterday(ref: ref) // 直接通过 Date 扩展判断昨天let ref = try "2026-03-10 12:00:00".date(.dateTime) // 参考时间
let in7 = try "2026-03-05 12:00:00".relative(to: ref).withinPast(7, .day) // 目标时间是否在参考时间向前 7 天范围内let inRange = try "2026-03-10 08:00:00".isBetween("2026-03-10 07:00:00", and: "2026-03-10 09:00:00", format: "yyyy-MM-dd HH:mm:ss") // 判断字符串时间是否在区间内let ts = try "2026-03-10 08:00:00".timestamp(.dateTime) // 日期字符串转秒级时间戳
let text = try "1704067200".dateStringFromTimestamp(unit: .second, format: "yyyy-MM-dd HH:mm:ss") // 秒级时间戳转日期字符串let fen = try "12.34".convertMoney(from: .major, to: .minor, currency: .cny) // 人民币元转分 -> 1234
let text = try "1234567.8".formattedMoney(scale: 2, useGrouping: true) // 金额千分位格式化 -> 1,234,567.80let ratio = try "12.5".percentToRatio() // 百分数 12.5 转比率 0.125let hex = try "rgba(255,102,0,0.5)".normalizedColorHex(includeAlpha: true) // 颜色字符串标准化为 hexlet phoneOK = "13800138000".isValidChineseMobile // 校验是否中国大陆手机号
let emailOK = "[email protected]".isValidEmail // 校验邮箱格式let blank = " \n ".isBlank // 判断是否空白字符串
let encoded = "a b&c=1".urlEncoded() // URL 编码
let decoded = "a%20b%26c%3D1".urlDecoded() // URL 解码
let b64 = "SwiftUtilityKit".base64Encoded() // Base64 编码
let raw = "U3dpZnRVdGlsaXR5S2l0".base64Decoded() // Base64 解码let d = try "2026-03-10 12:34:56".date(.dateTime) // 解析 Date
let start = d.startOfDay() // 当天开始时间 00:00:00
let end = d.endOfDay() // 当天结束时间 23:59:59
let plus7 = d.adding(7, .day) // 日期加 7 天
let sameDay = d.isSameDay(as: Date()) // 是否同一天let sys = DeviceInfo.systemVersion // 获取系统版本号
let model = DeviceInfo.modelName // 获取设备机型名称
let app = DeviceInfo.appVersionWithBuild // 获取当前 App 版本号 + 构建号
let px = DeviceInfo.pixelResolutionText // 获取屏幕物理分辨率(像素)
let battery = DeviceInfo.batteryPercentageText // 获取当前电池百分比文本
let total = DeviceInfo.totalDiskSpaceText // 获取设备总容量文本
let free = DeviceInfo.freeDiskSpaceText // 获取设备剩余容量文本
let used = DeviceInfo.usedDiskSpaceText // 获取设备已用容量文本let c = try "31.2304,121.4737".coordinate() // 字符串转坐标(默认纬度,经度)
let text = c.string(order: .longitudeLatitude, fractionDigits: 6) // 坐标转字符串(经度,纬度)
let dict = c.dictionary() // 坐标转字典:["latitude":..., "longitude":...]说明:DateKit 统一管理“解析/格式化的语言、时区、日历”和“日期格式模式”。
| API | 说明 |
|---|---|
DateKit.defaultContext |
默认上下文(zh_CN + Asia/Shanghai + Gregorian) |
DateKit.Context.cn |
中文预设上下文 |
DateKit.Context(locale:timeZone:calendar:) |
自定义上下文 |
| case | 格式 | 说明 |
|---|---|---|
dateTime |
yyyy-MM-dd HH:mm:ss |
常用秒级日期时间 |
dateTimeSlash |
yyyy/MM/dd HH:mm:ss |
斜杠版秒级日期时间 |
dateMinute |
yyyy-MM-dd HH:mm |
分钟级日期时间 |
dateMinuteSlash |
yyyy/MM/dd HH:mm |
斜杠版分钟级日期时间 |
date |
yyyy-MM-dd |
横杠日期 |
dateSlash |
yyyy/MM/dd |
斜杠日期 |
compactDateTime |
yyyyMMddHHmmss |
紧凑日期时间 |
compactDate |
yyyyMMdd |
紧凑日期 |
iso8601 |
yyyy-MM-dd'T'HH:mm:ssZ |
ISO8601 秒级 |
iso8601Millis |
yyyy-MM-dd'T'HH:mm:ss.SSSZ |
ISO8601 毫秒级 |
辅助集合:
DateKit.commonDatePatterns:自动识别输入模式列表(顺序即尝试顺序)DateKit.commonDateFormats:自动识别输入格式字符串列表
说明:当原始输入是字符串时,使用这组 API 最方便。
| API | 说明 |
|---|---|
convertLength(from:to:) |
长度换算 |
convertWeight(from:to:) |
重量换算 |
convertArea(from:to:) |
面积换算 |
convertVolume(from:to:) |
体积换算 |
convertTime(from:to:) |
时间换算 |
compareTime(with:selfUnit:otherUnit:) |
比较两个时间值 |
timeDifference(to:selfUnit:otherUnit:resultUnit:) |
计算两个时间值差值(other - self) |
convertTemperature(from:to:) |
温度换算 |
convertSpeed(from:to:) |
速度换算 |
convertRadix(from:to:uppercase:) |
字符串进制换算(2...36) |
toChineseUppercaseNumber() |
数字转中文大写数字 |
toChineseUppercaseCurrency() |
数字转中文金额大写 |
chineseUppercaseToDecimal() |
中文大写转十进制 |
toColorRGBA() |
颜色字符串转 RGBA |
normalizedColorHex(includeAlpha:prefixHash:) |
颜色字符串转标准 hex |
colorToPackedInt(includeAlpha:) |
颜色字符串转整数颜色值 |
说明:这是日期处理的主入口,支持“明确格式”和“自动识别”两种调用风格。
| API | 说明 |
|---|---|
date(_ format: String) |
按格式解析 |
date(_ pattern: DateKit.Pattern) |
按内置模式解析 |
date(_ formats: [String]) |
按多个格式依次尝试 |
date(_ patterns: [DateKit.Pattern]) |
按多个模式依次尝试 |
date(patterns:) |
自动识别解析 |
| API | 说明 |
|---|---|
dateString(from:to:)(String) |
输入格式 -> 输出格式 |
dateString(from:to:)(Pattern) |
输入模式 -> 输出模式 |
dateString(to:inputFormats:) |
自动识别输入格式后输出 |
dateString(to:inputPatterns:) |
自动识别输入模式后输出 |
| API | 说明 |
|---|---|
dateCompare(with:format:) |
比较两个日期字符串 |
dateDistance(to:format:unit:) |
计算日期差值(other - self) |
| API | 说明 |
|---|---|
timestamp(_ format: String, unit:) |
按格式转时间戳 |
timestamp(_ pattern: DateKit.Pattern, unit:) |
按模式转时间戳 |
timestamp(unit:patterns:) |
自动识别后转时间戳 |
timestampString(_ format: String, unit:scale:) |
转时间戳字符串 |
dateStringFromTimestamp(unit:format:) |
时间戳字符串转日期字符串 |
convertTimestamp(from:to:scale:) |
时间戳单位互转 |
说明:relative(...) 返回 DateRelativeProxy(中间对象),它保存 target + reference,用于继续做 .isYesterday/.isToday/... 等判断。
| API | 说明 |
|---|---|
relative(_ format: String, to:) |
按格式返回相对时间判断对象 |
relative(_ pattern: DateKit.Pattern, to:) |
按模式返回相对时间判断对象 |
relative(to:patterns:) |
自动识别后返回相对时间判断对象 |
isBetween(_:and:format:inclusive:) |
判断字符串时间是否在区间内 |
isYesterday(_ format:ref:) |
显式格式判断昨天 |
isYesterday(ref:patterns:) |
自动识别判断昨天 |
isToday(_ format:ref:) |
显式格式判断今天 |
isToday(ref:patterns:) |
自动识别判断今天 |
isTomorrow(_ format:ref:) |
显式格式判断明天 |
isTomorrow(ref:patterns:) |
自动识别判断明天 |
isDayBeforeYesterday(_ format:ref:) |
判断前天 |
isLastWeek(_ format:ref:) |
判断上周 |
isNextWeek(_ format:ref:) |
判断下周 |
isLastYear(_ format:ref:) |
判断去年 |
isNextYear(_ format:ref:) |
判断明年 |
| API | 说明 |
|---|---|
trimmed() |
去首尾空白和换行 |
removingWhitespacesAndNewlines() |
去全部空白和换行 |
isIntegerNumber |
是否整数文本 |
isDecimalNumber |
是否十进制数字文本 |
digitsOnly() |
仅保留数字字符 |
formattedWithGrouping(maximumFractionDigits:minimumFractionDigits:) |
数字千分位格式化 |
safeSubstring(start:length:) |
安全截取子串 |
isBlank |
是否空白字符串 |
nilIfBlank() |
空白转 nil,否则返回 trim 后内容 |
urlEncoded() |
URL 编码 |
urlDecoded() |
URL 解码 |
base64Encoded() |
Base64 编码(UTF-8) |
base64Decoded() |
Base64 解码(UTF-8) |
coordinate(separator:order:) |
字符串转 CLLocationCoordinate2D(CoreLocation) |
说明:业务逻辑层推荐直接用 Date 扩展,调用更自然。
| API | 说明 |
|---|---|
formatted(_:) |
Date 格式化输出 |
timestamp(unit:) |
Date 转时间戳 |
relative(to:) |
返回 DateRelativeProxy |
startOfDay() |
获取当天开始时间 |
endOfDay() |
获取当天结束时间 |
startOfWeek() |
获取当周开始时间 |
endOfWeek() |
获取当周结束时间 |
startOfMonth() |
获取当月开始时间 |
endOfMonth() |
获取当月结束时间 |
adding(_:_:) |
日期加减(如加 7 天) |
isSameDay(as:) |
判断是否同一天 |
isWeekend() |
判断是否周末 |
days(to:) |
计算相差自然日天数 |
isInRange(from:to:inclusive:) |
区间判断 |
isBetween(_:and:inclusive:) |
区间判断别名 |
isDayBeforeYesterday(ref:) |
判断前天 |
isYesterday(ref:) |
判断昨天 |
isToday(ref:) |
判断今天 |
isTomorrow(ref:) |
判断明天 |
isLastWeek(ref:) |
判断上周 |
isNextWeek(ref:) |
判断下周 |
isLastYear(ref:) |
判断去年 |
isNextYear(ref:) |
判断明年 |
isWithinPast(_:_:,ref:inclusive:) |
判断是否在参考时间向前范围内 |
Date.fromTimestamp(_:unit:) |
时间戳转 Date |
DateRelativeProxy 说明:
- 是什么:相对时间判断对象,内部绑定
target与reference - 何时用:需要连续判断多个相对条件时,减少重复传参
- 属性:
isDayBeforeYesterday / isYesterday / isToday / isTomorrow / isLastWeek / isNextWeek / isLastYear / isNextYear - 方法:
matches(_:)(按标签通用判断) - 方法:
withinPast(_:_:,inclusive:)(范围判断)
说明:当时间戳本来就是数值类型时,无需先转字符串。
适用于 BinaryInteger / BinaryFloatingPoint / Decimal:
convertTimestamp(from:to:):时间戳单位换算toDate(unit:):时间戳转Date
说明:仅做同币种单位换算(不涉及汇率),内部使用 Decimal 确保精度。
cny:人民币usd:美元eur:欧元gbp:英镑jpy:日元
major:主单位(如元/美元)tenth:十分位单位(如角)minor:百分位单位(如分/美分)
yuan:元jiao:角fen:分
MoneyConversion.convert(_:from:to:currency:)MoneyConversion.splitCNY(_:)MoneyConversion.mergeCNY(yuan:jiao:fen:)MoneyConversion.format(_:scale:useGrouping:locale:)
String / BinaryInteger / BinaryFloatingPoint / Decimal:
convertMoney(from:to:currency:)convertMoneyString(from:to:currency:scale:useGrouping:)formattedMoney(scale:useGrouping:)
Decimal:
splitCNY()
CNYParts:
toDecimalYuan()
说明:支持“百分数 <-> 比率”双向转换。
PercentageConversion.percentToRatio(_:)PercentageConversion.ratioToPercent(_:)
- String:
percentToRatio / ratioToPercent / percentToRatioString / ratioToPercentString - BinaryInteger:
percentToRatio / ratioToPercent - BinaryFloatingPoint:
percentToRatio / ratioToPercent - Decimal:
percentToRatio / ratioToPercent / asPercentString
说明:支持颜色字符串、整数、十六进制与系统颜色对象互转。
init(red:green:blue:alpha:)parse(_:)fromRGBString(_:)fromPackedInt(_:hasAlpha:)hexString(includeAlpha:prefixHash:)packedInt(includeAlpha:)
- String:
toColorRGBA / normalizedColorHex / colorToPackedInt / toCGColor / toUIColor / toSwiftUIColor - BinaryInteger:
toColorRGBA(hasAlpha:) / toColorHex(hasAlpha:prefixHash:)
colorRGBA(_:):字符串直接创建ColorRGBAcgColor(_:) / cgcolor(_:):字符串直接创建CGColoruiColor(_:) / uicolor(_:):字符串直接创建UIColor(UIKit)swiftUIColor(_:):字符串直接创建SwiftUI.Color
ColorRGBA:
init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)fromHex(_:)cgColorinit(cgColor:)uiColor(UIKit)init(uiColor:)(UIKit)swiftUIColor(SwiftUI)
UIColor(UIKit):
init(_ color: ColorRGBA)init(hex:)init(rgbString:)init(colorString:)toColorRGBA()
Color(SwiftUI + UIKit 桥接):
toColorRGBA()
说明:用于获取系统版本、设备机型、App 版本和屏幕分辨率等信息(UIKit 平台可用)。
DeviceInfo.systemName:系统名称(如 iOS)DeviceInfo.systemVersion:系统版本号DeviceInfo.modelIdentifier:设备机型标识(如iPhone16,2)DeviceInfo.modelName:设备机型名称(如iPhone 15 Pro Max)DeviceInfo.appVersion:App 版本号(CFBundleShortVersionString)DeviceInfo.appBuild:App 构建号(CFBundleVersion)DeviceInfo.appVersionWithBuild:版本号 + 构建号(如1.2.3(45))DeviceInfo.logicalResolution:逻辑分辨率(point)DeviceInfo.pixelResolution:物理分辨率(pixel)DeviceInfo.logicalResolutionText:逻辑分辨率文本(如393x852 pt)DeviceInfo.pixelResolutionText:物理分辨率文本(如1179x2556 px)DeviceInfo.screenScale:屏幕缩放倍数DeviceInfo.nativeScale:原生缩放倍数DeviceInfo.batteryLevel:电池电量(0...1,不可用时为nil)DeviceInfo.batteryPercentage:电池百分比(0...100,不可用时为nil)DeviceInfo.batteryPercentageText:电池百分比文本(如80%,不可用时为未知)DeviceInfo.batteryState:电池状态(UIDevice.BatteryState)DeviceInfo.batteryStateText:电池状态文本(未知 / 未充电 / 充电中 / 已充满)DeviceInfo.totalDiskSpace:设备总容量(字节)DeviceInfo.freeDiskSpace:设备剩余容量(字节)DeviceInfo.usedDiskSpace:设备已用容量(字节)DeviceInfo.totalDiskSpaceText:设备总容量文本(如256 GB)DeviceInfo.freeDiskSpaceText:设备剩余容量文本(如120 GB)DeviceInfo.usedDiskSpaceText:设备已用容量文本(如136 GB)
UIDevice.utilityModelIdentifier:设备机型标识UIDevice.utilityModelName:设备机型名称UIScreen.utilityPixelResolution:屏幕像素分辨率
- 机型映射独立维护在:
Sources/SwiftUtilityKit/Resources/AppleDeviceList.txt - 文件格式:
identifier|name(一行一条,#开头为注释) - 未命中映射时会自动回退为原始机型标识
说明:用于输入合法性校验和展示脱敏。
最简示例:
let phoneOK = "13800138000".isValidChineseMobile // 校验大陆手机号
let emailOK = "[email protected]".isValidEmail // 校验邮箱
let urlOK = "https://example.com/path?a=1".isValidURL // 校验 URL
let ipv6OK = "2408:8400:9800:31d3:4ff7:f6d2:69f8:77b3".isValidIPv6 // 校验 IPv6
let cardOK = "4111111111111111".isValidBankCardNumber // 校验银行卡号(Luhn)
let idOK = "11010519491231002X".isValidChineseIDCard // 校验身份证号(含校验码)
let cardText = "6222021234567890123".formattedBankCardNumber() // 银行卡分组格式化
let phoneText = "13800138000".formattedChineseMobile() // 手机号格式化为 XXX-XXXX-XXXX
let phoneMask = "13800138000".maskedChineseMobile() // 手机号脱敏为 XXX****XXXX
let idMask = "11010519491231002X".maskedChineseIDCard() // 身份证脱敏为 前6 + **** + 后4isValidChineseMobileisValidURLisValidEmailisValidIPv6isValidBankCardNumberisValidChineseIDCard
formattedBankCardNumber(separator:)formattedChineseMobile(separator:)maskedChineseMobile(mask:)maskedChineseIDCard(mask:)
说明:在可导入 CoreLocation 的平台,支持 CLLocationCoordinate2D 与字符串、元组、字典互转。
CoordinateOrder.latitudeLongitude:纬度,经度CoordinateOrder.longitudeLatitude:经度,纬度
CLLocationCoordinate2D.parse(_:separator:order:)CLLocationCoordinate2D.make(_:order:)CLLocationCoordinate2D.make(from:)isValidCoordinatestring(order:separator:fractionDigits:)tuple(order:)dictionary()swappedLatLon()
coordinate(separator:order:)
说明:当数据已是数值类型时,直接调用数值扩展更高效。
- 单位:
convertLength / convertWeight / convertArea / convertVolume / convertTime / convertTemperature / convertSpeed - 时间关系:
compareTime / timeDifference - 进制:
convertRadix(to:uppercase:) - 中文大写:
toChineseUppercaseNumber / toChineseUppercaseCurrency - 颜色:
toColorRGBA / toColorHex
- 单位:
convertLength / convertWeight / convertArea / convertVolume / convertTime / convertTemperature / convertSpeed - 时间关系:
compareTime / timeDifference - 中文大写:
toChineseUppercaseNumber / toChineseUppercaseCurrency
- 单位:
convertLength / convertWeight / convertArea / convertVolume / convertTime / convertTemperature / convertSpeed - 时间关系:
compareTime / timeDifference - 中文大写:
toChineseUppercaseNumber / toChineseUppercaseCurrency
picometer:皮米nanometer:纳米micrometer:微米millimeter:毫米centimeter:厘米decimeter:分米meter:米kilometer:千米nauticalMile:海里mile:英里furlong:弗隆yard:码foot:英尺inch:英寸li:里zhang:丈chi:尺cun:寸fen:分liSmall:厘hao:毫lightYear:光年
microgram:微克milligram:毫克gram:克kilogram:千克ton:吨ounce:盎司pound:磅stone:英石jin:斤liang:两qian:钱
squareMillimeter:平方毫米squareCentimeter:平方厘米squareDecimeter:平方分米squareMeter:平方米squareKilometer:平方千米hectare:公顷acre:英亩squareFoot:平方英尺squareInch:平方英寸mu:亩
milliliter:毫升liter:升cubicMeter:立方米teaspoon:茶匙tablespoon:汤匙cup:杯pint:品脱gallon:加仑cubicCentimeter:立方厘米cubicInch:立方英寸
nanosecond:纳秒microsecond:微秒millisecond:毫秒second:秒minute:分钟hour:小时day:天week:周
celsius:摄氏度fahrenheit:华氏度kelvin:开尔文
meterPerSecond:米每秒kilometerPerHour:千米每小时milePerHour:英里每小时knot:节footPerSecond:英尺每秒
second:秒级时间戳(如1704067200)millisecond:毫秒级时间戳(如1704067200000)
second:按秒输出差值minute:按分钟输出差值hour:按小时输出差值day:按天输出差值(24 小时)
dayBeforeYesterday:前天yesterday:昨天today:今天tomorrow:明天lastWeek:上周nextWeek:下周lastYear:去年nextYear:明年
invalidNumber:无效数字invalidBase:无效进制范围invalidRadixValue:进制值不合法overflow:溢出invalidChineseNumeral:中文数字不合法invalidColor:颜色不合法invalidDate:日期不合法invalidCoordinate:坐标不合法invalidMoneyUnit:币种与金额单位不匹配
- 单位名称本地化:
localizedName(locale:) - 错误信息本地化:
ConversionError.errorDescription