/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 | } |