TimeSpans
Some API requests need to represent a unit of time. This is refereed to as a TimeSpan. The JSON representation is a string in a format like "day.hour:minute:second.millisecond", where day and millisecond are optional parts.
public static let ticksPerMillisecond: Int64 = 10000
public static let ticksPerTenthSecond: Int64 = ticksPerMillisecond * 100
private static func parse(string: String) -> Int64
{
var days: Int64 = 0
var hours: Int64 = 0
var minutes: Int64 = 0
var seconds: Int64 = 0
var milliseconds: Int64 = 0
let colonParts = string.components(separatedBy: ":")
let hoursString = colonParts.first!
if hoursString.range(of: ".") != nil
{
let hourParts = hoursString.components(separatedBy: ".")
days = Int64(hourParts[0])!
hours = Int64(hourParts[1])!
}
else
{
hours = Int64(hoursString)!
}
minutes = Int64(colonParts[1])!
var millisecondsString: String? = nil
if colonParts.count == 3
{
let secondsString = colonParts.last!
if secondsString .range(of: ".") != nil
{
let secondParts = secondsString.components(separatedBy: ".")
seconds = Int64(secondParts[0])!
millisecondsString = secondParts[1]
milliseconds = Int64(millisecondsString!)!
}
else
{
seconds = Int64(secondsString)!
}
}
var time = abs(days) * 3600 * 24
time += abs(hours) * 3600
time += abs(minutes) * 60
time += abs(seconds)
time *= 1000
if milliseconds != 0
{
var lowerLimit = Time.ticksPerTenthSecond
if millisecondsString![0] == "0"
{
var i: Int = 0
var divisor: Int64 = 10
while millisecondsString![i] == "0"
{
divisor *= 10
i += 1
}
lowerLimit /= divisor
}
while milliseconds < lowerLimit
{
milliseconds *= 10
}
}
let result = milliseconds.addingReportingOverflow(time * Time.ticksPerMillisecond)
var ticks = result.partialValue
if string[0] == "-"
{
if result.overflow == false
{
ticks = -ticks
}
}
else
{
assert(result.overflow == false)
}
return ticks
}
public static let ticksPerSecond: Int64 = ticksPerMillisecond * 1000
public var description: String
{
let days = abs(self.days)
let hours = abs(self.hours)
let minutes = abs(self.minutes)
let seconds = abs(self.seconds)
let fraction = abs(ticks % Time.ticksPerSecond)
var result = "\(String(format: "%02d", hours)):\(String(format: "%02d", minutes)):\(String(format: "%02d", seconds))"
if days != 0
{
result = "\(days).\(result)"
}
if fraction != 0
{
result = "\(result).\(String(format: "%07d", fraction))"
}
return ticks < 0 ? "-\(result)" : result
}
See TimeSpan.swift for full implementation.
Updated almost 6 years ago