Files
ccn/Services/Website/Sources/Library/Internal/Extensions/Date+Stamps.swift
T

74 lines
2.1 KiB
Swift

import Foundation
extension Date {
// MARK: Methods
/// How long until the date, in a few words: `47 h left`, `2 days left`, `under an hour left`.
/// - Parameter now: the moment counted from.
func countdown(
from now: Date
) -> String {
let hours = Int(timeIntervalSince(now) / 3_600)
switch hours {
case ..<1: return "under an hour left"
case ..<48: return "\(hours) h left"
default: return "\(hours / 24) days left"
}
}
/// The date as a stamp on a record: `today, 09:14`, `yesterday, 21:38`, `20 Sep, 14:05`, or with the year once it differs.
///
/// Read on Amsterdam's clock: the marketplace is NL-first.
/// - Parameter now: the moment "today" is judged from.
func stamp(
relativeTo now: Date
) -> String {
let time = formatted(Self.style.hour(.twoDigits(amPM: .omitted)).minute(.twoDigits))
if Self.calendar.isDate(self, inSameDayAs: now) {
return "today, \(time)"
}
if
let yesterday = Self.calendar.date(byAdding: .day, value: -1, to: now),
Self.calendar.isDate(self, inSameDayAs: yesterday)
{
return "yesterday, \(time)"
}
let isSameYear = Self.calendar.isDate(self, equalTo: now, toGranularity: .year)
let day = formatted(isSameYear ? Self.style.day().month(.abbreviated) : Self.style.day().month(.abbreviated).year())
return "\(day), \(time)"
}
}
// MARK: - Helpers
private extension Date {
// MARK: Constants
/// The calendar days are told apart by, on Amsterdam's clock.
static let calendar: Calendar = {
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = timeZone
return calendar
}()
/// The base format style: British English, on Amsterdam's clock.
static let style = Date.FormatStyle(
locale: .init(identifier: "en_GB"),
calendar: calendar,
timeZone: timeZone
)
static let timeZone = TimeZone(identifier: "Europe/Amsterdam") ?? .gmt
}