diff --git a/DXFeedFramework.xcodeproj/project.pbxproj b/DXFeedFramework.xcodeproj/project.pbxproj index 2870e6913..e38579b47 100644 --- a/DXFeedFramework.xcodeproj/project.pbxproj +++ b/DXFeedFramework.xcodeproj/project.pbxproj @@ -233,6 +233,13 @@ 649F48882A615BED0016FDD1 /* CandleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649F48872A615BED0016FDD1 /* CandleType.swift */; }; 64A42F3B2B07A7A3001C3ACC /* SymbolParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A42F3A2B07A7A3001C3ACC /* SymbolParser.swift */; }; 64A42F3E2B07A807001C3ACC /* NativeSymbolParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A42F3D2B07A807001C3ACC /* NativeSymbolParser.swift */; }; + 64A42F452B0B933B001C3ACC /* NativeTimeUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A42F442B0B933B001C3ACC /* NativeTimeUtil.swift */; }; + 64A42F472B0B9368001C3ACC /* NativeTimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A42F462B0B9367001C3ACC /* NativeTimeZone.swift */; }; + 64A42F492B0B9683001C3ACC /* NativeTimeFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A42F482B0B9683001C3ACC /* NativeTimeFormat.swift */; }; + 64A42F4B2B0B96EF001C3ACC /* NativeTimePeriod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A42F4A2B0B96EF001C3ACC /* NativeTimePeriod.swift */; }; + 64A42F4E2B0B9FA4001C3ACC /* DXTimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A42F4D2B0B9FA4001C3ACC /* DXTimeZone.swift */; }; + 64A42F502B0BA668001C3ACC /* DXTimeFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A42F4F2B0BA668001C3ACC /* DXTimeFormat.swift */; }; + 64A42F522B0BBB6D001C3ACC /* DXTimePeriod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A42F512B0BBB6D001C3ACC /* DXTimePeriod.swift */; }; 64AAF0532A8113E800E8942B /* String+Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AAF0522A8113E800E8942B /* String+Range.swift */; }; 64AAF0552A82499A00E8942B /* ConcurrentDict.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AAF0542A82499A00E8942B /* ConcurrentDict.swift */; }; 64AAF0572A82A3FC00E8942B /* ICandleSymbolProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AAF0562A82A3FC00E8942B /* ICandleSymbolProperty.swift */; }; @@ -697,6 +704,13 @@ 649F48872A615BED0016FDD1 /* CandleType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CandleType.swift; sourceTree = ""; }; 64A42F3A2B07A7A3001C3ACC /* SymbolParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SymbolParser.swift; sourceTree = ""; }; 64A42F3D2B07A807001C3ACC /* NativeSymbolParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeSymbolParser.swift; sourceTree = ""; }; + 64A42F442B0B933B001C3ACC /* NativeTimeUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeTimeUtil.swift; sourceTree = ""; }; + 64A42F462B0B9367001C3ACC /* NativeTimeZone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeTimeZone.swift; sourceTree = ""; }; + 64A42F482B0B9683001C3ACC /* NativeTimeFormat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeTimeFormat.swift; sourceTree = ""; }; + 64A42F4A2B0B96EF001C3ACC /* NativeTimePeriod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeTimePeriod.swift; sourceTree = ""; }; + 64A42F4D2B0B9FA4001C3ACC /* DXTimeZone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DXTimeZone.swift; sourceTree = ""; }; + 64A42F4F2B0BA668001C3ACC /* DXTimeFormat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DXTimeFormat.swift; sourceTree = ""; }; + 64A42F512B0BBB6D001C3ACC /* DXTimePeriod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DXTimePeriod.swift; sourceTree = ""; }; 64AAF0522A8113E800E8942B /* String+Range.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Range.swift"; sourceTree = ""; }; 64AAF0542A82499A00E8942B /* ConcurrentDict.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConcurrentDict.swift; sourceTree = ""; }; 64AAF0562A82A3FC00E8942B /* ICandleSymbolProperty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICandleSymbolProperty.swift; sourceTree = ""; }; @@ -1118,6 +1132,7 @@ 64656F552A1B6A07006A0B19 /* Utils */ = { isa = PBXGroup; children = ( + 64A42F4C2B0B9F95001C3ACC /* DateTime */, 641AC1A82A61AE4000EF6D6C /* DXAliases.swift */, 64656F5F2A1B9EC2006A0B19 /* EnumUtil.swift */, 64656F642A1CAFC5006A0B19 /* String+Pointee.swift */, @@ -1257,6 +1272,27 @@ path = QDS; sourceTree = ""; }; + 64A42F432B0B9320001C3ACC /* Utils */ = { + isa = PBXGroup; + children = ( + 64A42F442B0B933B001C3ACC /* NativeTimeUtil.swift */, + 64A42F462B0B9367001C3ACC /* NativeTimeZone.swift */, + 64A42F482B0B9683001C3ACC /* NativeTimeFormat.swift */, + 64A42F4A2B0B96EF001C3ACC /* NativeTimePeriod.swift */, + ); + path = Utils; + sourceTree = ""; + }; + 64A42F4C2B0B9F95001C3ACC /* DateTime */ = { + isa = PBXGroup; + children = ( + 64A42F4D2B0B9FA4001C3ACC /* DXTimeZone.swift */, + 64A42F4F2B0BA668001C3ACC /* DXTimeFormat.swift */, + 64A42F512B0BBB6D001C3ACC /* DXTimePeriod.swift */, + ); + path = DateTime; + sourceTree = ""; + }; 64ACBCDB2A28974900032C53 /* Osub */ = { isa = PBXGroup; children = ( @@ -1493,6 +1529,7 @@ 64437A902A9DF1C4005929B2 /* Ipf */, 6498E6B32AB1D43A0093A065 /* Schedule */, 64ACBCE42A28AEE200032C53 /* SymbolMappers */, + 64A42F432B0B9320001C3ACC /* Utils */, ); path = Native; sourceTree = ""; @@ -2143,6 +2180,7 @@ 64BDDB322AD7E5A600694210 /* SpreadOrderMapper.swift in Sources */, 64ACBCE32A289A0700032C53 /* TimeSeriesSubscriptionSymbol.swift in Sources */, 645A34952A937C7200709F29 /* BinaryInteger+Ext.swift in Sources */, + 64A42F502B0BA668001C3ACC /* DXTimeFormat.swift in Sources */, 64BA92652A306E0200BE26A0 /* Trade.swift in Sources */, 6486B9752AD0493F00D8D5FA /* TheoPrice+Ext.swift in Sources */, 6464074B2A9DFAF7006FF769 /* InstrumentProfile+Ext.swift in Sources */, @@ -2161,6 +2199,7 @@ 64ECD6852A9DDF6200B36935 /* DXInstrumentProfileCollector.swift in Sources */, 6486B96F2AD0445400D8D5FA /* Underlying+Ext.swift in Sources */, 64656F5B2A1B9784006A0B19 /* DXFeed.swift in Sources */, + 64A42F472B0B9368001C3ACC /* NativeTimeZone.swift in Sources */, 6486B96B2AD03DC900D8D5FA /* Underlying.swift in Sources */, 6447A5EF2A8FD1CD00739CCF /* DayUtil.swift in Sources */, 64B436462AB985AE0003919E /* NativeBox.swift in Sources */, @@ -2226,7 +2265,9 @@ 6486B9632AD0333B00D8D5FA /* Greeks.swift in Sources */, 64E342522AAB29CF00457994 /* InstrumentProfileType.swift in Sources */, 648E98AA2AAF625800BFD219 /* IIndexedEvent+Ext.swift in Sources */, + 64A42F452B0B933B001C3ACC /* NativeTimeUtil.swift in Sources */, 6447A5E32A8F611700739CCF /* IObservableSubscription.swift in Sources */, + 64A42F4E2B0B9FA4001C3ACC /* DXTimeZone.swift in Sources */, 64104FC92A26298D00D1FC41 /* DXFeedSubcription.swift in Sources */, 64ABC1032AD9294D00904D78 /* OptionSaleMapper.swift in Sources */, 64104FD32A277B2D00D1FC41 /* ListNative.swift in Sources */, @@ -2289,6 +2330,7 @@ 648BD5712AC583AC004A3A95 /* TimeFormat.swift in Sources */, 642BE4C42A2E1AFF0052340A /* Quote.swift in Sources */, 64656F602A1B9EC2006A0B19 /* EnumUtil.swift in Sources */, + 64A42F492B0B9683001C3ACC /* NativeTimeFormat.swift in Sources */, 642BE4CA2A2E1C640052340A /* MarketEvent.swift in Sources */, 6486B95B2AD015B400D8D5FA /* PriceType.swift in Sources */, 64BDDB202AD6CC8300694210 /* AnalyticOrder.swift in Sources */, @@ -2299,6 +2341,8 @@ 64AAF0592A83EA0000E8942B /* Double+Ext.swift in Sources */, 64BDDB2A2AD7D9C700694210 /* SpreadOrder+Ext.swift in Sources */, 8088D77529C3A61000F240CB /* ErrorCheck.swift in Sources */, + 64A42F4B2B0B96EF001C3ACC /* NativeTimePeriod.swift in Sources */, + 64A42F522B0BBB6D001C3ACC /* DXTimePeriod.swift in Sources */, 6486B9672AD0390800D8D5FA /* GreeksMapper.swift in Sources */, 64AAF0572A82A3FC00E8942B /* ICandleSymbolProperty.swift in Sources */, 64437A922A9DF1DE005929B2 /* NativeInstrumentProfileReader.swift in Sources */, diff --git a/DXFeedFramework/Native/Utils/NativeTimeFormat.swift b/DXFeedFramework/Native/Utils/NativeTimeFormat.swift new file mode 100644 index 000000000..2b6b3548f --- /dev/null +++ b/DXFeedFramework/Native/Utils/NativeTimeFormat.swift @@ -0,0 +1,58 @@ +// +// NativeTimeFormat.swift +// DXFeedFramework +// +// Created by Aleksey Kosylo on 20.11.23. +// + +import Foundation +@_implementationOnly import graal_api + +class NativeTimeFormat: NativeBox { + deinit { + let thread = currentThread() + _ = try? ErrorCheck.nativeCall(thread, dxfg_JavaObjectHandler_release(thread, &(native.pointee.handler))) + } + + static func defaultTimeFormat() -> NativeTimeFormat? { + let thread = currentThread() + if let native = try? ErrorCheck.nativeCall(thread, dxfg_TimeFormat_DEFAULT(thread)) { + return NativeTimeFormat(native: native) + } else { + return nil + } + } + + static func gmtTimeFormat() -> NativeTimeFormat? { + let thread = currentThread() + if let native = try? ErrorCheck.nativeCall(thread, dxfg_TimeFormat_GMT(thread)) { + return NativeTimeFormat(native: native) + } else { + return nil + } + } + + convenience init(timeZone: NativeTimeZone) throws { + let thread = currentThread() + let timeFormat = try ErrorCheck.nativeCall(thread, dxfg_TimeFormat_getInstance(thread, timeZone.native)) + self.init(native: timeFormat) + } + + convenience init(withTimeZone timeFormat: NativeTimeFormat) throws { + let thread = currentThread() + let timeFormat = try ErrorCheck.nativeCall(thread, dxfg_TimeFormat_withTimeZone(thread, timeFormat.native)) + self.init(native: timeFormat) + } + + convenience init(withMillis timeFormat: NativeTimeFormat) throws { + let thread = currentThread() + let timeFormat = try ErrorCheck.nativeCall(thread, dxfg_TimeFormat_withMillis(thread, timeFormat.native)) + self.init(native: timeFormat) + } + + convenience init(fullIso timeFormat: NativeTimeFormat) throws { + let thread = currentThread() + let timeFormat = try ErrorCheck.nativeCall(thread, dxfg_TimeFormat_asFullIso(thread, timeFormat.native)) + self.init(native: timeFormat) + } +} diff --git a/DXFeedFramework/Native/Utils/NativeTimePeriod.swift b/DXFeedFramework/Native/Utils/NativeTimePeriod.swift new file mode 100644 index 000000000..d98db6fed --- /dev/null +++ b/DXFeedFramework/Native/Utils/NativeTimePeriod.swift @@ -0,0 +1,46 @@ +// +// NativeTimePeriod.swift +// DXFeedFramework +// +// Created by Aleksey Kosylo on 20.11.23. +// + +import Foundation +@_implementationOnly import graal_api + +class NativeTimePeriod: NativeBox { + deinit { + let thread = currentThread() + _ = try? ErrorCheck.nativeCall(thread, dxfg_JavaObjectHandler_release(thread, &(native.pointee.handler))) + } + + static func zero() -> NativeTimePeriod? { + let thread = currentThread() + if let native = try? ErrorCheck.nativeCall(thread, dxfg_TimePeriod_ZERO(thread)) { + return NativeTimePeriod(native: native) + } else { + return nil + } + } + + static func unlimited() -> NativeTimePeriod? { + let thread = currentThread() + if let native = try? ErrorCheck.nativeCall(thread, dxfg_TimePeriod_UNLIMITED(thread)) { + return NativeTimePeriod(native: native) + } else { + return nil + } + } + + convenience init(value: Int64) throws { + let thread = currentThread() + let timePeriod = try ErrorCheck.nativeCall(thread, dxfg_TimePeriod_valueOf(thread, value)) + self.init(native: timePeriod) + } + + convenience init(value: String) throws { + let thread = currentThread() + let timePeriod = try ErrorCheck.nativeCall(thread, dxfg_TimePeriod_valueOf2(thread, value.toCStringRef())) + self.init(native: timePeriod) + } +} diff --git a/DXFeedFramework/Native/Utils/NativeTimeUtil.swift b/DXFeedFramework/Native/Utils/NativeTimeUtil.swift new file mode 100644 index 000000000..beef86c5b --- /dev/null +++ b/DXFeedFramework/Native/Utils/NativeTimeUtil.swift @@ -0,0 +1,13 @@ +// +// NativeTimeUtil.swift +// DXFeedFramework +// +// Created by Aleksey Kosylo on 20.11.23. +// + +import Foundation +@_implementationOnly import graal_api + +class NativeTimeUtil { + +} diff --git a/DXFeedFramework/Native/Utils/NativeTimeZone.swift b/DXFeedFramework/Native/Utils/NativeTimeZone.swift new file mode 100644 index 000000000..052b2e6db --- /dev/null +++ b/DXFeedFramework/Native/Utils/NativeTimeZone.swift @@ -0,0 +1,31 @@ +// +// NativeTimeZone.swift +// DXFeedFramework +// +// Created by Aleksey Kosylo on 20.11.23. +// + +import Foundation +@_implementationOnly import graal_api + +class NativeTimeZone: NativeBox { + deinit { + let thread = currentThread() + _ = try? ErrorCheck.nativeCall(thread, dxfg_JavaObjectHandler_release(thread, &(native.pointee.handler))) + } + + static func defaultTimeZone() -> NativeTimeZone? { + let thread = currentThread() + if let native = try? ErrorCheck.nativeCall(thread, dxfg_TimeZone_getDefault(thread)) { + return NativeTimeZone(native: native) + } else { + return nil + } + } + + convenience init(timeZoneID: String) throws { + let thread = currentThread() + let native = try ErrorCheck.nativeCall(thread, dxfg_TimeZone_getTimeZone(thread, timeZoneID.toCStringRef())) + self.init(native: native) + } +} diff --git a/DXFeedFramework/Utils/DateTime/DXTimeFormat.swift b/DXFeedFramework/Utils/DateTime/DXTimeFormat.swift new file mode 100644 index 000000000..de06dda8f --- /dev/null +++ b/DXFeedFramework/Utils/DateTime/DXTimeFormat.swift @@ -0,0 +1,52 @@ +// +// DXTimeFormat.swift +// DXFeedFramework +// +// Created by Aleksey Kosylo on 20.11.23. +// + +import Foundation + +public class DXTimeFormat { + public static let defaultTimeFormat: DXTimeFormat? = { + if let timeFormat = NativeTimeFormat.defaultTimeFormat() { + return DXTimeFormat(timeFormat: timeFormat) + } else { + return nil + } + }() + + public static let gmtTimeFormat: DXTimeFormat? = { + if let timeFormat = NativeTimeFormat.gmtTimeFormat() { + return DXTimeFormat(timeFormat: timeFormat) + } else { + return nil + } + }() + + private var timeFormat: NativeTimeFormat + + private init(timeFormat: NativeTimeFormat) { + self.timeFormat = timeFormat + } + + public convenience init(timeZone: DXTimeZone) throws { + let timeFormat = try NativeTimeFormat(timeZone: timeZone.timeZone) + self.init(timeFormat: timeFormat) + } + + public convenience init(withTimeZone timeFormat: DXTimeFormat) throws { + let timeFormat = try NativeTimeFormat(withTimeZone: timeFormat.timeFormat) + self.init(timeFormat: timeFormat) + } + + public convenience init(withMillis timeFormat: DXTimeFormat) throws { + let timeFormat = try NativeTimeFormat(withMillis: timeFormat.timeFormat) + self.init(timeFormat: timeFormat) + } + + public convenience init(fullIso timeFormat: DXTimeFormat) throws { + let timeFormat = try NativeTimeFormat(fullIso: timeFormat.timeFormat) + self.init(timeFormat: timeFormat) + } +} diff --git a/DXFeedFramework/Utils/DateTime/DXTimePeriod.swift b/DXFeedFramework/Utils/DateTime/DXTimePeriod.swift new file mode 100644 index 000000000..b4f6aad9d --- /dev/null +++ b/DXFeedFramework/Utils/DateTime/DXTimePeriod.swift @@ -0,0 +1,42 @@ +// +// DXTimePeriod.swift +// DXFeedFramework +// +// Created by Aleksey Kosylo on 20.11.23. +// + +import Foundation + +public class DXTimePeriod { + public static let zero: DXTimePeriod? = { + if let timePeriod = NativeTimePeriod.zero() { + return DXTimePeriod(timePeriod: timePeriod) + } else { + return nil + } + }() + + public static let unlimited: DXTimePeriod? = { + if let timePeriod = NativeTimePeriod.unlimited() { + return DXTimePeriod(timePeriod: timePeriod) + } else { + return nil + } + }() + + private var timePeriod: NativeTimePeriod + + private init(timePeriod: NativeTimePeriod) { + self.timePeriod = timePeriod + } + + convenience init(value: Int64) throws { + let timePeriod = try NativeTimePeriod(value: value) + self.init(timePeriod: timePeriod) + } + + convenience init(value: String) throws { + let timePeriod = try NativeTimePeriod(value: value) + self.init(timePeriod: timePeriod) + } +} diff --git a/DXFeedFramework/Utils/DateTime/DXTimeZone.swift b/DXFeedFramework/Utils/DateTime/DXTimeZone.swift new file mode 100644 index 000000000..c1437b25f --- /dev/null +++ b/DXFeedFramework/Utils/DateTime/DXTimeZone.swift @@ -0,0 +1,28 @@ +// +// DXTimeZone.swift +// DXFeedFramework +// +// Created by Aleksey Kosylo on 20.11.23. +// + +import Foundation + +public class DXTimeZone { + public static let defaultTimeZone: DXTimeZone? = { + if let timeZone = NativeTimeZone.defaultTimeZone() { + return DXTimeZone(timeZone: timeZone) + } else { + return nil + } + }() + + internal var timeZone: NativeTimeZone + + private init(timeZone: NativeTimeZone) { + self.timeZone = timeZone + } + + public convenience init(timeZoneID: String) throws { + self.init(timeZone: try NativeTimeZone(timeZoneID: timeZoneID)) + } +} diff --git a/DXFeedFrameworkTests/DateTimeParserTest.swift b/DXFeedFrameworkTests/DateTimeParserTest.swift index 8c45686f1..24986c8a7 100644 --- a/DXFeedFrameworkTests/DateTimeParserTest.swift +++ b/DXFeedFrameworkTests/DateTimeParserTest.swift @@ -112,5 +112,5 @@ final class DateTimeParserTest: XCTestCase { minute: 0, second: 0)) } - + }