71 lines
2.0 KiB
Swift
71 lines
2.0 KiB
Swift
//
|
|
// AbbreviatedTimeAgoFormatStyle.swift
|
|
//
|
|
//
|
|
// Created by Shadowfacts on 4/9/23.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
public struct AbbreviatedTimeAgoFormatStyle: FormatStyle {
|
|
public typealias FormatInput = Date
|
|
public typealias FormatOutput = String
|
|
|
|
public func format(_ value: Date) -> String {
|
|
let (amount, component) = timeAgo(value: value)
|
|
|
|
switch component {
|
|
case .year:
|
|
return "\(amount)y"
|
|
case .month:
|
|
return "\(amount)mo"
|
|
case .weekOfYear:
|
|
return "\(amount)w"
|
|
case .day:
|
|
return "\(amount)d"
|
|
case .hour:
|
|
return "\(amount)h"
|
|
case .minute:
|
|
return "\(amount)m"
|
|
case .second:
|
|
if amount >= 3 {
|
|
return "\(amount)s"
|
|
} else {
|
|
return "Now"
|
|
}
|
|
default:
|
|
fatalError("Unexpected component: \(component)")
|
|
}
|
|
}
|
|
|
|
private static let unitFlags = Set<Calendar.Component>([.second, .minute, .hour, .day, .weekOfYear, .month, .year])
|
|
|
|
private func timeAgo(value: Date) -> (Int, Calendar.Component) {
|
|
let calendar = NSCalendar.current
|
|
let components = calendar.dateComponents(Self.unitFlags, from: value, to: Date())
|
|
|
|
if components.year! >= 1 {
|
|
return (components.year!, .year)
|
|
} else if components.month! >= 1 {
|
|
return (components.month!, .month)
|
|
} else if components.weekOfYear! >= 1 {
|
|
return (components.weekOfYear!, .weekOfYear)
|
|
} else if components.day! >= 1 {
|
|
return (components.day!, .day)
|
|
} else if components.hour! >= 1 {
|
|
return (components.hour!, .hour)
|
|
} else if components.minute! >= 1 {
|
|
return (components.minute!, .minute)
|
|
} else {
|
|
return (components.second!, .second)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public extension FormatStyle where Self == AbbreviatedTimeAgoFormatStyle {
|
|
static var abbreviatedTimeAgo: Self {
|
|
Self()
|
|
}
|
|
}
|