119 lines
4.5 KiB
Swift
119 lines
4.5 KiB
Swift
//
|
|
// Date.swift
|
|
// Mastodon
|
|
//
|
|
// Created by MainasuK Cirno on 2021-6-1.
|
|
//
|
|
|
|
import Foundation
|
|
import MastodonAsset
|
|
import MastodonLocalization
|
|
|
|
extension Date {
|
|
|
|
static let calendar = Calendar(identifier: .gregorian)
|
|
|
|
public static let relativeTimestampFormatter: RelativeDateTimeFormatter = {
|
|
let formatter = RelativeDateTimeFormatter()
|
|
formatter.dateTimeStyle = .numeric
|
|
formatter.unitsStyle = .full
|
|
return formatter
|
|
}()
|
|
|
|
public static let abbreviatedDateFormatter: DateFormatter = {
|
|
let formatter = DateFormatter()
|
|
formatter.dateStyle = .medium // e.g. Nov 23, 1937
|
|
formatter.timeStyle = .none // none
|
|
return formatter
|
|
}()
|
|
|
|
public var localizedSlowedTimeAgoSinceNow: String {
|
|
return self.localizedTimeAgo(since: Date(), isSlowed: true, isAbbreviated: false)
|
|
}
|
|
|
|
public var localizedTimeAgoSinceNow: String {
|
|
return self.localizedTimeAgo(since: Date(), isSlowed: false, isAbbreviated: false)
|
|
}
|
|
|
|
public func localizedTimeAgo(since date: Date, isSlowed: Bool, isAbbreviated: Bool) -> String {
|
|
let earlierDate = date < self ? date : self
|
|
let latestDate = earlierDate == date ? self : date
|
|
|
|
if isSlowed, earlierDate.timeIntervalSince(latestDate) >= -60 {
|
|
return L10n.Common.Controls.Timeline.Timestamp.now
|
|
} else {
|
|
if isAbbreviated {
|
|
return latestDate.localizedShortTimeAgo(since: earlierDate)
|
|
} else {
|
|
if earlierDate.timeIntervalSince(latestDate) < -(7 * 24 * 60 * 60) {
|
|
let currentYear = Date.calendar.dateComponents([.year], from: Date())
|
|
let earlierDateYear = Date.calendar.dateComponents([.year], from: earlierDate)
|
|
if #available(iOS 15.0, *) {
|
|
if currentYear.year! > earlierDateYear.year! {
|
|
return earlierDate.formatted(.dateTime.year().month(.abbreviated).day())
|
|
} else {
|
|
return earlierDate.formatted(.dateTime.month(.abbreviated).day())
|
|
}
|
|
} else {
|
|
return Date.abbreviatedDateFormatter.string(from: earlierDate)
|
|
}
|
|
} else {
|
|
return Date.relativeTimestampFormatter.localizedString(for: earlierDate, relativeTo: latestDate)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
extension Date {
|
|
|
|
public func localizedShortTimeAgo(since date: Date) -> String {
|
|
let earlierDate = date < self ? date : self
|
|
let latestDate = earlierDate == date ? self : date
|
|
|
|
let components = Date.calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: earlierDate, to: latestDate)
|
|
|
|
if components.year! > 0 {
|
|
return L10n.Date.Year.Ago.abbr(components.year!)
|
|
} else if components.month! > 0 {
|
|
return L10n.Date.Month.Ago.abbr(components.month!)
|
|
} else if components.day! > 0 {
|
|
return L10n.Date.Day.Ago.abbr(components.day!)
|
|
} else if components.hour! > 0 {
|
|
return L10n.Date.Hour.Ago.abbr(components.hour!)
|
|
} else if components.minute! > 0 {
|
|
return L10n.Date.Minute.Ago.abbr(components.minute!)
|
|
} else if components.second! > 0 {
|
|
return L10n.Date.Year.Ago.abbr(components.second!)
|
|
} else {
|
|
return ""
|
|
}
|
|
}
|
|
|
|
public func localizedTimeLeft() -> String {
|
|
let date = Date()
|
|
let earlierDate = date < self ? date : self
|
|
let latestDate = earlierDate == date ? self : date
|
|
|
|
let components = Calendar(identifier: .gregorian).dateComponents([.year, .month, .day, .hour, .minute, .second], from: earlierDate, to: latestDate)
|
|
|
|
if components.year! > 0 {
|
|
return L10n.Date.Year.left(components.year!)
|
|
} else if components.month! > 0 {
|
|
return L10n.Date.Month.left(components.month!)
|
|
} else if components.day! > 0 {
|
|
return L10n.Date.Day.left(components.day!)
|
|
} else if components.hour! > 0 {
|
|
return L10n.Date.Hour.left(components.hour!)
|
|
} else if components.minute! > 0 {
|
|
return L10n.Date.Minute.left(components.minute!)
|
|
} else if components.second! > 0 {
|
|
return L10n.Date.Year.left(components.second!)
|
|
} else {
|
|
return ""
|
|
}
|
|
}
|
|
|
|
}
|