// Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause import Foundation extension Date { var isGoZeroTime: Bool { return self == GoZeroTime } } // GoZeroTime is a Date instance that matches Go's time.Time zero value. It's // explicitly created using Go's zero value (0001-01-01, 00:00:00 UTC), since // using an offset from the Unix epoch (1970-01-01, 00:00:00 UTC) does not work // as expected on macOS 10.13. let GoZeroTimeString = "0001-01-01T00:00:00Z" let GoZeroTime = ISO8601DateFormatter().date(from: GoZeroTimeString)! extension String { func iso8601Date() -> Date? { let iso8601DateFormatter = { ISO8601DateFormatter() }() let iso8601DateFormatterFractionalSeconds: ISO8601DateFormatter = { let dateFormatter = ISO8601DateFormatter() dateFormatter.formatOptions.insert(.withFractionalSeconds) return dateFormatter }() // Fractional seconds are optional in RFC3339 as generated by Go/control, // but Foundation date formatters do not parse dates with and without // fractional seconds without specifying the option to look for them. if let date = iso8601DateFormatterFractionalSeconds.date(from: self) { return date } if let date = iso8601DateFormatter.date(from: self) { return date } return nil } }