Coverage Report

Created: 2025-07-04 06:57

/src/swift-protobuf/Sources/SwiftProtobuf/TimeUtils.swift
Line
Count
Source
1
// Sources/SwiftProtobuf/TimeUtils.swift - Generally useful time/calendar functions
2
//
3
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
4
// Licensed under Apache License v2.0 with Runtime Library Exception
5
//
6
// See LICENSE.txt for license information:
7
// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt
8
//
9
// -----------------------------------------------------------------------------
10
///
11
/// Generally useful time/calendar functions and constants
12
///
13
// -----------------------------------------------------------------------------
14
15
let minutesPerDay: Int32 = 1440
16
let minutesPerHour: Int32 = 60
17
let secondsPerDay: Int32 = 86400
18
let secondsPerHour: Int32 = 3600
19
let secondsPerMinute: Int32 = 60
20
let nanosPerSecond: Int32 = 1_000_000_000
21
let attosPerNanosecond: Int64 = 1_000_000_000
22
23
12.2k
internal func timeOfDayFromSecondsSince1970(seconds: Int64) -> (hh: Int32, mm: Int32, ss: Int32) {
24
12.2k
    let secondsSinceMidnight = Int32(mod(seconds, Int64(secondsPerDay)))
25
12.2k
    let ss = mod(secondsSinceMidnight, secondsPerMinute)
26
12.2k
    let mm = mod(div(secondsSinceMidnight, secondsPerMinute), minutesPerHour)
27
12.2k
    let hh = Int32(div(secondsSinceMidnight, secondsPerHour))
28
12.2k
29
12.2k
    return (hh: hh, mm: mm, ss: ss)
30
12.2k
}
31
32
12.2k
internal func julianDayNumberFromSecondsSince1970(seconds: Int64) -> Int64 {
33
12.2k
    // January 1, 1970 is Julian Day Number 2440588.
34
12.2k
    // See http://aa.usno.navy.mil/faq/docs/JD_Formula.php
35
12.2k
    div(seconds + 2_440_588 * Int64(secondsPerDay), Int64(secondsPerDay))
36
12.2k
}
37
38
12.2k
internal func gregorianDateFromSecondsSince1970(seconds: Int64) -> (YY: Int32, MM: Int32, DD: Int32) {
39
12.2k
    // The following implements Richards' algorithm (see the Wikipedia article
40
12.2k
    // for "Julian day").
41
12.2k
    // If you touch this code, please test it exhaustively by playing with
42
12.2k
    // Test_Timestamp.testJSON_range.
43
12.2k
44
12.2k
    let JJ = julianDayNumberFromSecondsSince1970(seconds: seconds)
45
12.2k
    let f = JJ + 1401 + div(div(4 * JJ + 274277, 146097) * 3, 4) - 38
46
12.2k
    let e = 4 * f + 3
47
12.2k
    let g = Int64(div(mod(e, 1461), 4))
48
12.2k
    let h = 5 * g + 2
49
12.2k
    let DD = div(mod(h, 153), 5) + 1
50
12.2k
    let MM = mod(div(h, 153) + 2, 12) + 1
51
12.2k
    let YY = div(e, 1461) - 4716 + div(12 + 2 - MM, 12)
52
12.2k
53
12.2k
    return (YY: Int32(YY), MM: Int32(MM), DD: Int32(DD))
54
12.2k
}
55
56
17.5k
internal func nanosToString(nanos: Int32) -> String {
57
17.5k
    if nanos == 0 {
58
15.5k
        return ""
59
15.5k
    } else if nanos % 1_000_000 == 0 {
60
834
        return ".\(threeDigit(abs(nanos) / 1_000_000))"
61
1.17k
    } else if nanos % 1000 == 0 {
62
234
        return ".\(sixDigit(abs(nanos) / 1000))"
63
939
    } else {
64
939
        return ".\(nineDigit(abs(nanos)))"
65
939
    }
66
939
}