Task[edit]
A particular activity of bats occurs at these times of the day:

23:00:17, 23:40:20, 00:12:45, 00:17:19
Using the idea that there are twenty-four hours in a day,
which is analogous to there being 360 degrees in a circle,
map times of day to and from angles;
and using the ideas of Averages/Mean angle
compute and show the average time of the nocturnal activity
to an accuracy of one second of time.

See also
Tasks for calculating statistical measures



in one go
moving (sliding window)
moving (cumulative)

Mean
Arithmetic

Statistics/Basic
Averages/Arithmetic mean
Averages/Pythagorean means


Averages/Simple moving average




Geometric

Averages/Pythagorean means




Harmonic

Averages/Pythagorean means




Quadratic

Averages/Root mean square




Circular

Averages/Mean angle
Averages/Mean time of day




Median

Averages/Median




Mode

Averages/Mode




Standard deviation

Statistics/Basic



Cumulative standard deviation




import Foundation
 
@inlinable public func d2r<T: FloatingPoint>(_ f: T) -> T { f * .pi / 180 }
@inlinable public func r2d<T: FloatingPoint>(_ f: T) -> T { f * 180 / .pi }
 
public func meanOfAngles(_ angles: [Double]) -> Double {
  let cInv = 1 / Double(angles.count)
  let (y, x) =
    angles.lazy
      .map(d2r)
      .map({ (sin($0), cos($0)) })
      .reduce(into: (0.0, 0.0), { $0.0 += $1.0; $0.1 += $1.1 })
 
  return r2d(atan2(cInv * y, cInv * x))
}
 
struct DigitTime {
  var hour: Int
  var minute: Int
  var second: Int
 
  init?(fromString str: String) {
    let split = str.components(separatedBy: ":").compactMap(Int.init)
 
    guard split.count == 3 else {
      return nil
    }
 
    (hour, minute, second) = (split[0], split[1], split[2])
  }
 
  init(fromDegrees angle: Double) {
    let totalSeconds = 24 * 60 * 60 * angle / 360
 
    second = Int(totalSeconds.truncatingRemainder(dividingBy: 60))
    minute = Int((totalSeconds.truncatingRemainder(dividingBy: 3600) - Double(second)) / 60)
    hour = Int(totalSeconds / 3600)
  }
 
  func toDegrees() -> Double {
    return 360 * Double(hour) / 24.0 + 360 * Double(minute) / (24 * 60.0) + 360 * Double(second) / (24 * 3600.0)
  }
}
 
extension DigitTime: CustomStringConvertible {
  var description: String { String(format: "%02i:%02i:%02i", hour, minute, second) }
}
 
let times = ["23:00:17", "23:40:20", "00:12:45", "00:17:19"].compactMap(DigitTime.init(fromString:))
 
guard times.count == 4 else {
  fatalError()
}
 
let meanTime = DigitTime(fromDegrees: 360 + meanOfAngles(times.map({ $0.toDegrees() })))
 
print("Given times \(times), the mean time is \(meanTime)")