This commit is contained in:
patrick-zippenfenig 2022-08-07 12:27:16 +02:00
parent 7638bf2235
commit 90d3a002fa
3 changed files with 57 additions and 10 deletions

View file

@ -1,5 +1,7 @@
# SwiftTimeZoneLookup
[![Test](https://github.com/patrick-zippenfenig/SwiftTimeZoneLookup/actions/workflows/test.yml/badge.svg)](https://github.com/patrick-zippenfenig/SwiftTimeZoneLookup/actions/workflows/test.yml)
A description of this package.

View file

@ -6,9 +6,21 @@ public enum SwiftTimeZoneLookupError: Error {
case couldNotOpenDatabase
}
public struct SwiftTimeZoneLookupResult {
/// Timezone identifier like `Europe/Berlin`
let timezone: String
/// Country name like `Germany`
let countryName: String?
/// 2 character country code like `DE` for Germany
let countryAlpha2: String?
}
public final class SwiftTimeZoneLookup {
private let database: OpaquePointer
/// Throws if the timezone database could not be opened
public init() throws {
guard let timezone21 = Bundle.module.url(forResource: "timezone21", withExtension: "bin") else {
throw SwiftTimeZoneLookupError.couldNotFindTimezone21bin
@ -21,13 +33,14 @@ public final class SwiftTimeZoneLookup {
self.database = database
}
public func lookup(latitude: Float, longitude: Float) -> String? {
/// Resolve timezone by coordinate and return timezone, country name and alpha2
public func lookup(latitude: Float, longitude: Float) -> SwiftTimeZoneLookupResult? {
guard let result = ZDLookup(database, latitude, longitude, nil) else {
return nil
}
defer { ZDFreeResults(result) }
/*var countryName: String? = nil
var countryAlpha2: String? = nil*/
var countryName: String? = nil
var countryAlpha2: String? = nil
var timezoneIdPrefix: UnsafeMutablePointer<CChar>? = nil
var timezoneId: UnsafeMutablePointer<CChar>? = nil
for i in 0..<result.pointee.numFields {
@ -37,12 +50,41 @@ public final class SwiftTimeZoneLookup {
guard let value = result.pointee.data.advanced(by: Int(i)).pointee else {
continue
}
/*if strcmp(field, "CountryAlpha2") == 0 {
if strcmp(field, "CountryAlpha2") == 0 {
countryAlpha2 = String(cString: value)
}
if strcmp(field, "CountryName") == 0 {
countryName = String(cString: value)
}*/
}
if strcmp(field, "TimezoneIdPrefix") == 0 {
timezoneIdPrefix = value
}
if strcmp(field, "TimezoneId") == 0 {
timezoneId = value
}
}
guard let timezoneIdPrefix = timezoneIdPrefix, let timezoneId = timezoneId else {
return nil
}
let timezone = String(cString: timezoneIdPrefix) + String(cString: timezoneId)
return SwiftTimeZoneLookupResult(timezone: timezone, countryName: countryName, countryAlpha2: countryAlpha2)
}
/// Resolve the timz
public func simple(latitude: Float, longitude: Float) -> String? {
guard let result = ZDLookup(database, latitude, longitude, nil) else {
return nil
}
defer { ZDFreeResults(result) }
var timezoneIdPrefix: UnsafeMutablePointer<CChar>? = nil
var timezoneId: UnsafeMutablePointer<CChar>? = nil
for i in 0..<result.pointee.numFields {
guard let field = result.pointee.fieldNames.advanced(by: Int(i)).pointee else {
continue
}
guard let value = result.pointee.data.advanced(by: Int(i)).pointee else {
continue
}
if strcmp(field, "TimezoneIdPrefix") == 0 {
timezoneIdPrefix = value
}

View file

@ -4,11 +4,14 @@ import XCTest
final class SwiftTimeZoneLookupTests: XCTestCase {
func testLookup() throws {
let database = try SwiftTimeZoneLookup()
XCTAssertEqual(database.lookup(latitude: 47.5, longitude: 8.6), "Europe/Zurich")
XCTAssertEqual(database.lookup(latitude: 47.5, longitude: -2.6), "Europe/Paris")
XCTAssertEqual(database.lookup(latitude: 47.5, longitude: -8.6), "Etc/GMT+1")
XCTAssertEqual(database.lookup(latitude: 42.5, longitude: -8.6), "Europe/Madrid")
XCTAssertEqual(database.simple(latitude: 47.5, longitude: 8.6), "Europe/Zurich")
XCTAssertEqual(database.simple(latitude: 47.5, longitude: -2.6), "Europe/Paris")
XCTAssertEqual(database.simple(latitude: 47.5, longitude: -8.6), "Etc/GMT+1")
XCTAssertEqual(database.simple(latitude: 42.5, longitude: -8.6), "Europe/Madrid")
XCTAssertEqual(database.lookup(latitude: 242.5, longitude: -8.6), nil)
XCTAssertEqual(database.simple(latitude: 242.5, longitude: -8.6), nil)
XCTAssertEqual(database.lookup(latitude: 42.5, longitude: -8.6)?.countryName, "Spain")
XCTAssertEqual(database.lookup(latitude: 42.5, longitude: -8.6)?.countryAlpha2, "ES")
}
}