Files
multi-simadmin/apps/ios/Sources/MultiSimAdmin/Support/TimestampText.swift
T
chick 3607eddc9f release(ios): 发布 0.2.1 并重构图标与界面细节
- 应用图标改用与 Web favicon 同源的扁平标记,金色 SIM 卡体加三格递增信号,29pt 下仍可读
- 标签统一为胶囊形状,提高深色主题下的描边权重,避免标签在暗色下消失
- 消息卡片与详情分区卡片收紧行距,单屏信息密度明显提升
- 详情头部指标精简为 4 行,数据模块改为单条读数
- 批量选择勾选框移出名称区域,工具栏控件统一为等高 34pt
- 分组编辑器改为点选即生效,移除说明文字与常驻禁用按钮
2026-09-14 16:30:39 +08:00

85 lines
3.2 KiB
Swift

import Foundation
/// 上游返回的时间戳格式并不统一(`yyyy-MM-dd HH:mm:ss`、ISO8601、秒/毫秒时间戳都出现过),
/// 列表里需要一个稳定的短读法,解析不出来时原样回退,避免出现"--"这种假结论。
public enum TimestampText {
private static let parsers: [DateFormatter] = {
let patterns = [
"yyyy-MM-dd HH:mm:ss",
"yyyy-MM-dd'T'HH:mm:ss",
"yyyy-MM-dd HH:mm",
"yyyy/MM/dd HH:mm:ss",
"yyyy-MM-dd",
]
return patterns.map { pattern in
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.calendar = Calendar(identifier: .gregorian)
formatter.timeZone = .current
formatter.dateFormat = pattern
return formatter
}
}()
private static let utcParser: DateFormatter = {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.calendar = Calendar(identifier: .gregorian)
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
return formatter
}()
private static let timeFormat: DateFormatter = {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "zh_CN")
formatter.dateFormat = "HH:mm"
return formatter
}()
private static let monthDayFormat: DateFormatter = {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "zh_CN")
formatter.dateFormat = "MM-dd HH:mm"
return formatter
}()
private static let fullFormat: DateFormatter = {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "zh_CN")
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
public static func date(from raw: String) -> Date? {
let text = raw.trimmingCharacters(in: .whitespacesAndNewlines)
guard text.isEmpty == false else { return nil }
if let number = Double(text), text.allSatisfy({ $0.isNumber }) {
// 13 位是毫秒,10 位是秒。
return Date(timeIntervalSince1970: text.count > 11 ? number / 1000 : number)
}
let head = text.hasSuffix("Z") ? String(text.dropLast()) : text
for parser in parsers {
if let parsed = parser.date(from: head) {
return text.hasSuffix("Z") ? utcParser.date(from: head) ?? parsed : parsed
}
}
return nil
}
/// 今天只看时分,今年看月日,跨年才写全年份。
public static func short(_ raw: String, now: Date = Date()) -> String {
guard let parsed = date(from: raw) else {
return raw.trimmingCharacters(in: .whitespacesAndNewlines)
}
let calendar = Calendar.current
if calendar.isDate(parsed, inSameDayAs: now) {
return timeFormat.string(from: parsed)
}
if calendar.isDate(parsed, equalTo: now, toGranularity: .year) {
return monthDayFormat.string(from: parsed)
}
return fullFormat.string(from: parsed)
}
}