Skip to content

Commit

Permalink
Tweak docs with gpt4
Browse files Browse the repository at this point in the history
  • Loading branch information
eonist committed Aug 3, 2024
1 parent ce6ad10 commit 517b143
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 22 deletions.
17 changes: 15 additions & 2 deletions Sources/NetTime/Date+NetTime.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import Foundation
import Logger
/**
* - Description: class which will provide the best estimate of the difference in time between the device's system clock and the time returned by a collection of time servers
* Class which will provide the best estimate of the difference in time between the device's system clock and the time returned by a collection of time servers
* - Description: This class estimates the time difference between the device's system clock and the time returned by a collection of time servers. It helps to synchronize the device's time with the server time, ensuring accurate timekeeping regardless of the user's local settings.
* - Note: This class has Unit-tests
* - Fixme: ⚠️️ If you want to sync your time to a specific server (e.g. your API server)
* - Fixme: ⚠️️ If for some reason the Date format your HTTP Server returns is different than the one specified
Expand All @@ -13,11 +14,18 @@ import Logger
*/
@available(macOS 10.15, *)
extension Date {
/**
* This typealias defines a closure type named OnComplete that takes no parameters and returns no value. It is used as a completion handler in various functions within this extension.
*/
public typealias OnComplete = () -> Void
/**
* This is the default completion handler for the updateTime function. It does nothing when called, and is used when no other completion handler is provided.
*/
public static let defaultOnComplete: OnComplete = {}
/**
* Subsequent date getter calls goes here
* - Description: Allows you to make sure your time is synced up to a remote server regardless of the User's local settings
* - Abstract: Allows you to make sure your time is synced up to a remote server regardless of the User's local settings
* - Description: This property provides the current server time, adjusted for any time difference between the device's system clock and the server's clock. It ensures that the time used in the app is in sync with the server time, regardless of the user's local settings.
* - Remark: It does this by performing a one-time-per-session HTTP HEAD Request to the supplied server, getting a "Base" date, and keep counting from there - Making sure you're in sync with the remote server even when the user's clock isn't.
*/
public static var serverTime: Date {
Expand All @@ -27,9 +35,11 @@ extension Date {
return possibleDate.advanced(by: timeGap) // Otherwise, offset `possibleDate` by `timeGap` and return the resulting date
}
/**
* - Description: This function updates the server time by making a network call to a specified URL and retrieving the date from the response headers. It then calculates the time difference between the server time and the device's system time, and stores this difference for future use. This ensures that the app's time is always in sync with the server time, regardless of the user's local settings.
* - Remark: Set this at the first opertunity when using the app
* - Remark: Call this on background queue
* - Remark: If this is not called e use system time
* - Fixme: ⚠️️ Add a way to add a custom server URL
* - Fixme: ⚠️️ Add error to `onComplete` closure, use Result maybe? 👈 This way we can log the error in the caller etc
* - Parameter onComplete: Callback when server has responded
*/
Expand Down Expand Up @@ -59,6 +69,7 @@ extension Date {
extension Date {
/**
* Date formatter
* - Description: This is a DateFormatter used to convert the "Date" header field from the server response into a Date object. It is configured to match the expected date format from the server, and uses the current time zone and US English locale.
*/
fileprivate static let formatter: DateFormatter = {
let formatter: DateFormatter = .init() // Create a new date formatter
Expand All @@ -71,6 +82,7 @@ extension Date {
}()
/**
* Time-gap between network call and network response
* - Description: This variable holds the time difference between the network call and the network response. It is used to adjust the local time to match the server time.
*/
fileprivate static var timeGap: TimeInterval = 0
/**
Expand All @@ -79,6 +91,7 @@ extension Date {
*/
fileprivate static var referenceDate: Date = .init() {
didSet {
// Calculate the time difference between the current date and the reference date, and assign it to timeGap
timeGap = Date().distance(to: referenceDate)
}
}
Expand Down
11 changes: 7 additions & 4 deletions Tests/NetTimeTests/NetTimeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import Logger

final class NetTimeTests: XCTestCase {
func testExample() throws {
Logger.setup(
Logger.setup( // Initialize the Logger with the specified configuration and mode, excluding the 'info' log level
config: .plain, // The logger configuration to use
mode: .init(
mode: .init( // Initialize the logger mode with specific tags and levels
tag: LogTag.allCases, // The log tags to include in the logger mode
level: LogLevel.allCases.filter({ $0 != .info }) // The log levels to include in the logger mode
),
type: .console // The logger output type to use
) // Config Logger, We only want erros and warnings not info (debug is okay)
)
do {
try Self.time(testCase: self) // Testing time (NTPTime, Reachability)
} catch {
Expand All @@ -22,14 +22,14 @@ final class NetTimeTests: XCTestCase {
}
}
}

/**
* - Note: More on network unit testing: https://nshipster.com/xctestcase/
* - Remark: can't be static because async?
*/
extension NetTimeTests {
/**
* Testing time
* - Description: This method validates the functionality of time-related features such as time zone conversion, server time synchronization, and network connectivity within the NetTime framework.
*/
fileprivate static func time(testCase: XCTestCase) throws {
try Self.testTimeZoneConversion() // Test time zone conversion functionality of the database
Expand All @@ -38,6 +38,7 @@ extension NetTimeTests {
}
/**
* timezone conversion
* - Description: This method tests the functionality of time zone conversion within the NetTime framework. It validates the conversion of local time to UTC and vice versa, ensuring the accuracy of these conversions.
* - Remark: This is less relevant, but explains how timezone works etc. As we always format to users timezone and save in UTC in DB
*/
static func testTimeZoneConversion() throws {
Expand All @@ -56,6 +57,7 @@ extension NetTimeTests {
}
/**
* Reachability test (makes sure unit test has network etc)
* - Description: This method tests the network connectivity of the device. It uses the Reachability utility class to check if the internet is reachable. This is important for unit tests that require network access.
* - Fixme: ⚠️️ Add a timer on the reachability, how long it takes etc
*/
static func testConnectivity(testCase: XCTestCase) throws {
Expand All @@ -72,6 +74,7 @@ extension NetTimeTests {
}
/**
* Server time
* - Description: This method tests the accuracy and reliability of the server time synchronization within the NetTime framework. It ensures that the time reported by the server is correctly retrieved and formatted, reflecting the precise current time according to the server's clock.
* - Fixme: ⚠️️⚠️️ Format time with milli / nano seconds etc -> See history date formater
* - Remark: Date is stored in Swift as UTC time, i.e. as at longitude 0.0 - which used to be called Greenwich Mean Time. It doesn't take into account your timezone, nor any Summertime adjustment. When you display the time to the user in your code, via UIKit or SwiftUI, you use a DateFormatter
*/
Expand Down
33 changes: 20 additions & 13 deletions Tests/NetTimeTests/util/Date+TimeZone.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,35 @@ import Foundation
extension TimeZone {
/**
* The Central European Time (CET) time zone.
* The CET time zone is used in countries such as Germany, France, Italy, and Spain, among others.
* - Description: The Central European Time (CET) is a time standard used in Central Europe. It is 1 hour ahead of Coordinated Universal Time (UTC+1) and is used in countries such as Germany, France, Italy, and Spain, among others.
* - Note: The CET time zone is used in countries such as Germany, France, Italy, and Spain, among others.
*/
internal static let cetTimeZone: TimeZone? = .init(abbreviation: "CET")
/**
* The Coordinated Universal Time (UTC) time zone.
* Same as GMT, the successor
* UTC is the primary time standard by which the world regulates clocks and time.
* It is also known as "Zulu time" or "Z time".
* UTC is the successor to Greenwich Mean Time (GMT)
* It is used as a standard time in aviation, military, and other contexts.
* - Description: The Coordinated Universal Time (UTC) is the primary time standard by which the world regulates clocks and time. It is not adjusted for daylight saving time and it is used in many internet and World Wide Web standards.
* - Note: Same as GMT, the successor
* - Note: UTC is the primary time standard by which the world regulates clocks and time.
* - Note: It is also known as "Zulu time" or "Z time".
* - Note: UTC is the successor to Greenwich Mean Time (GMT)
* - Note: It is used as a standard time in aviation, military, and other contexts.
*/
internal static let utcTimeZone: TimeZone? = .init(abbreviation: "UTC")
/**
* The Greenwich Mean Time (GMT) time zone.
* GMT is a time zone that is used in the United Kingdom and other countries in the winter.
* It is also known as "Zulu time" or "Z time".
* GMT is 0 hours ahead of Coordinated Universal Time (UTC+0)
* +0000
* - Description: Greenwich Mean Time (GMT) is a time standard originally referring to mean solar time at the Royal Observatory located in Greenwich, London. It is commonly used in timekeeping and is the time zone used by the prime meridian of the world.
* - Note: GMT is a time zone that is used in the United Kingdom and other countries in the winter.
* - Note: It is also known as "Zulu time" or "Z time".
* - Note: GMT is 0 hours ahead of Coordinated Universal Time (UTC+0)
* - Note: +0000
*/
internal static let gmtTimeZone: TimeZone? = .init(abbreviation: "GMT")
/**
* The Eastern Standard Time (EST) time zone.
* utc -5 nyc time
* The EST time zone is used in the eastern part of the United States, including cities such as New York, Washington D.C., and Miami, among others.
* The time zone is 5 hours behind Coordinated Universal Time (UTC-5).
* - Description: The Eastern Standard Time (EST) is a time zone that is used in the eastern part of the United States and Canada, and is 5 hours behind Coordinated Universal Time (UTC-5).
* - Note: utc -5 nyc time
* - Note: The EST time zone is used in the eastern part of the United States, including cities such as New York, Washington D.C., and Miami, among others.
* - Note: The time zone is 5 hours behind Coordinated Universal Time (UTC-5).
*/
internal static let estTimeZone: TimeZone? = .init(abbreviation: "EST")
}
Expand All @@ -40,13 +44,15 @@ extension TimeZone {
extension Date {
/**
* Returns current time in london gmt / utc +0000
* - Description: This function returns the current date and time adjusted to the Coordinated Universal Time (UTC) time zone. It is useful for converting the local date and time to a standardized format that is not affected by daylight saving time or local time zone differences.
*/
internal func getUTCTimeZoneDate() -> Date? {
// Calendar.current.dateBySetting(timeZone: .utcTimeZone, of: date)
guard let utcTimeZone: TimeZone = .utcTimeZone else { return nil } // Get UTC time zone
return self.convert(from: utcTimeZone, to: TimeZone.current) // Convert date from UTC to current time zone
}
/**
* - Description: This function returns a date adjusted to the current time zone from a date that represents a time in a different time zone.
* - Note: returns a time from another timezone represented in the current timezone
* - Parameter timeZone: the timezone self represent
* - Returns: adjusted date
Expand All @@ -59,6 +65,7 @@ extension Date {
}
/**
* Converts the date from one time zone to another
* - Description: This method is used to convert a date from one time zone to another. It takes the original time zone and the destination time zone as parameters, and returns the date converted to the destination time zone.
* - Parameters:
* - timeZone: The time zone of the original date.
* - destinationTimeZone: The time zone to convert the date to.
Expand Down
6 changes: 5 additions & 1 deletion Tests/NetTimeTests/util/Reachability.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import Foundation

/**
* Reachability is a utility class that provides methods to check the availability of internet connectivity.
* It performs a network request to a reliable host and determines if the internet is reachable based on the response.
*/
internal class Reachability {
/**
* Checks to see if internet is reachable
* - fixme: add description
* - Note: The reason why we do async: https://stackoverflow.com/a/40764725/5389500
* - Parameters:
* - completionHandler: The closure to call with the result of the network check.
Expand Down
13 changes: 11 additions & 2 deletions Tests/NetTimeTests/util/TimeMeasure.swift
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import Foundation

/**
* TimeMeasure is a utility class for measuring the execution time of code blocks.
* It provides static methods to measure the time taken for synchronous operations
* and return the duration in seconds. This can be useful for performance testing
* or ensuring that certain operations do not exceed a time budget.
*/
internal final class TimeMeasure {
/**
* The number of nano-seconds in a second
* - Description: This constant is used to convert nanoseconds to seconds for time measurement purposes.
*/
fileprivate static let nanoToSecond: Double = 1_000_000_000
/**
* A closure that takes no parameters and returns nothing
* - Description: This typealias defines a closure type named Operation that takes no parameters and throws an error if it fails. It is used in the timeElapsed methods to measure the execution time of a given operation.
*/
internal typealias Operation = () throws -> Void
/**
* Measures how long a closure takes to complete
* - Description: This method measures the execution time of a given closure in seconds. It takes a closure as a parameter, executes it, and returns the time taken for the closure to complete its execution.
* - Note: This method is great for UnitTesting
* - Note: it's also possible to use. `let startTime = CFAbsoluteTimeGetCurrent(); CFAbsoluteTimeGetCurrent() - startTime`
* - Fixme: ⚠️️ Add param comment
Expand All @@ -26,8 +34,9 @@ internal final class TimeMeasure {
}
/**
* A time-measure that prints the time used, and returns the value of payload etc
* - Description: This method measures the execution time of a given closure and returns the result of the closure along with the time taken. It is useful for performance testing and optimization by allowing developers to quantify the duration of code execution.
* - Note: so you can time individual times etc
* fix: add param comment
* - Parameter closure: The closure whose execution time is being measured. It returns a value of type T.
* timeElapsed { sleep(2.2) }.time // 2.20000
*/
internal static func timeElapsed<T>(_ closure: () throws -> T) rethrows -> (value: T, time: Double) {
Expand Down
3 changes: 3 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,6 @@ NetTime is released under the MIT License. See [LICENSE](LICENSE) for details.
## Todo:
- Do more exploration into side-effects
- Comb the competitors for ways to improve
- add Troubleshooting or FAQ section: If there are common issues users run into, addressing them in the README can save time for both you and the users.
- add Versioning: If you're planning on maintaining this project long-term, it might be helpful to include information about the versioning system you're using.
- add Screenshots or GIFs: If applicable, visual aids can help users understand how your package works or what it looks like when it's running.

0 comments on commit 517b143

Please sign in to comment.