Skip to content

Instantly share code, notes, and snippets.

@YOCKOW
Last active March 25, 2024 17:41
Show Gist options
  • Select an option

  • Save YOCKOW/12d9607cb30f40b79fb2 to your computer and use it in GitHub Desktop.

Select an option

Save YOCKOW/12d9607cb30f40b79fb2 to your computer and use it in GitHub Desktop.
Get `timespec` in Swift. It is no longer necessary to implement clock_gettime() even on OS X.
/*
TimeSpec.swift
© 2016 YOCKOW.
*/
// <Usage>
// let now:TimeSpec? = Clock.Calendar.timespec
// if now != nil {
// /* ... */
// }
#if os(Linux)
import Glibc
public typealias TimeSpec = timespec
#elseif os(OSX) || os(iOS) || os(watchOS) || (tvOS)
import Darwin
private let mach_task_self:()->mach_port_t = { return mach_task_self_ }
public typealias TimeSpec = mach_timespec_t
#endif
extension Double {
public init(_ ts: TimeSpec) {
self = Double(ts.tv_nsec) * 1.0E-9 + Double(ts.tv_sec)
}
}
extension TimeSpec {
public var double:Double {
return Double(self)
}
}
public func + (left:TimeSpec, right:TimeSpec) -> TimeSpec {
var result = left
result.tv_sec += right.tv_sec
result.tv_nsec += right.tv_nsec
if (result.tv_nsec >= 1_000_000_000) {
result.tv_sec += 1
result.tv_nsec -= 1_000_000_000
}
return result
}
public func - (left:TimeSpec, right:TimeSpec) -> TimeSpec {
var result = left
result.tv_sec -= right.tv_sec
result.tv_nsec -= right.tv_nsec
if (result.tv_nsec < 0) {
result.tv_sec -= 1
result.tv_nsec += 1_000_000_000
}
return result
}
public enum Clock {
case Calendar
case System
public var timespec:TimeSpec? {
var result:TimeSpec = TimeSpec(tv_sec:0, tv_nsec:0)
let clock_id:Int32
var return_value:Int32 = -1
#if os(Linux)
clock_id = (self == .Calendar) ? CLOCK_REALTIME : CLOCK_MONOTONIC
return_value = clock_gettime(clock_id, &result)
#elseif os(OSX) || os(iOS) || os(watchOS) || (tvOS)
clock_id = (self == .Calendar) ? CALENDAR_CLOCK : SYSTEM_CLOCK
var clock_name: clock_serv_t = 0
return_value = host_get_clock_service(mach_host_self(), clock_id, &clock_name)
if return_value != 0 { return nil }
return_value = clock_get_time(clock_name, &result)
_ = mach_port_deallocate(mach_task_self(), clock_name)
#endif
return (return_value == 0) ? result : nil
}
}
@maximveksler
Copy link

very well said!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment