Skip to content

Instantly share code, notes, and snippets.

@khanlou
Created December 22, 2020 19:26
Show Gist options
  • Save khanlou/71a0e28d008c23bebdfe3668eb1f94ac to your computer and use it in GitHub Desktop.
Save khanlou/71a0e28d008c23bebdfe3668eb1f94ac to your computer and use it in GitHub Desktop.
//
// GregorianDate.swift
//
//
// Created by Soroush Khanlou on 12/22/20.
//
import Foundation
public struct GregorianDate: Equatable, Hashable, Comparable, Codable, CustomStringConvertible {
public let day: Int
public let month: Int
public let year: Int
public var components: DateComponents {
DateComponents(year: year, month: month, day: day)
}
public var description: String {
[year, month, day]
.map({ String(format: "%02d", $0) })
.joined(separator: "-")
}
public init?(string: String) {
guard !string.isEmpty else { return nil }
let parts = string.split(separator: "-", maxSplits: 3,
omittingEmptySubsequences: true)
assert(parts.count == 3)
guard parts.count == 3 else { return nil }
guard let year = Int(parts[0]),
let month = Int(parts[1]),
let day = Int(parts[2]),
month >= 1 && month <= 12, day >= 1 && day <= 31
else
{
return nil
}
self.year = year
self.month = month
self.day = day
}
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let string = try container.decode(String.self)
guard let date = GregorianDate(string: string) else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Malformed date")
}
self = date
}
public func encode(to encoder: Encoder) throws {
try self.description.encode(to: encoder)
}
public init(from date: Date = Date()) {
let calendar = Calendar(identifier: .gregorian)
let components = calendar.dateComponents([.day, .month, .year], from: date)
self.init(year: components.year!, month: components.month!, day: components.day!)
}
public init(year: Int, month: Int, day: Int) {
self.year = year
self.month = month
self.day = day
}
public static func < (lhs: GregorianDate, rhs: GregorianDate) -> Bool {
return (lhs.year, lhs.month, lhs.day) < (rhs.year, rhs.month, rhs.day)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment