Convert BLE current time to date
To convert from data/bytes to numeric types you can check this post
extension Numeric {
init<D: DataProtocol>(_ data: D) {
var value: Self = .zero
let size = withUnsafeMutableBytes(of: &value, { data.copyBytes(to: $0)} )
assert(size == MemoryLayout.size(ofValue: value))
self = value
}
}
extension DataProtocol {
func value<N: Numeric>() -> N { .init(self) }
var uint16: UInt16 { value() }
}
Now you can easily convert from bytes to any numeric type:
let timeData: [UInt8] = [224, 7, 1, 3, 4, 36, 5, 0, 0, 1]
let timeDate = DateComponents(calendar: .current,
timeZone: .current,
year: Int(timeData[0..<2].uint16),
month: Int(timeData[2]),
day: Int(timeData[3]),
hour: Int(timeData[4]),
minute: Int(timeData[5]),
second: Int(timeData[6])).date!
timeDate // "Jan 3, 2016 at 4:36 AM"
Convert Date to Hex String using Swift (BLE)
That is what I was looking for:
let dateInt = Int(Date().timeIntervalSince1970)
let dateHex = String(dateInt, radix: 16, uppercase: true)
print(dateHex)
Now dateHex could be devided on bites and sent to BLE device
How to convert Swift Date into Byte Array?
You can create a method to convert FixedWidthInteger to bytes (big or little endian) for the year component, convert the other date componentes to bytes and append them to the result:
enum Endianness {
case big, little
}
extension FixedWidthInteger {
func data<D: DataProtocol & RangeReplaceableCollection>(
using endianness: Endianness = .big
) -> D {
withUnsafeBytes(of: endianness == .big ? bigEndian : littleEndian, D.init)
}
}
extension Calendar {
static let iso8601 = Self(identifier: .iso8601)
}
extension Date {
func component(_ component: Calendar.Component, using calendar: Calendar = .iso8601) -> Int {
calendar.component(component, from: self)
}
func data<D: DataProtocol & RangeReplaceableCollection>() -> D {
var dataProtocol: D = .init()
dataProtocol += UInt16(component(.year)).data() as D
dataProtocol.append(UInt8(component(.month)))
dataProtocol.append(UInt8(component(.day)))
dataProtocol.append(UInt8(component(.hour)))
dataProtocol.append(UInt8(component(.minute)))
dataProtocol.append(UInt8(component(.second)))
return dataProtocol
}
}
Usage:
let data: Data = Date().data()
print(Array(data))
This will print
[7, 230, 6, 17, 2, 10, 46]
Convert Hex code to Date (BLE) - Algorithm
The data is the big-endian representation of the date offset to the
“reference date” (00:00:00 UTC on 1 January 2001):
let data = Data(bytes: [0xBA, 0x36, 0x8E, 0x7F])
let offset = UInt32(bigEndian: data.withUnsafeBytes { $0.pointee })
let date = Date(timeIntervalSinceReferenceDate: TimeInterval(offset))
print(date) // 2099-12-31 23:59:59 +0000
If the input is really given as a hex string, not as Data
:
let hex = "BA368E7F"
if let offset = UInt32(hex, radix: 16) {
let date = Date(timeIntervalSinceReferenceDate: TimeInterval(offset))
print(date) // 2099-12-31 23:59:59 +0000
}
Convert DATA to Date
The necessary information can be found in Data to different types ? in the Apple Developer Forum.
First note that it is unsafe to rely on undocumented extended attributes. A better way to get the same result is to retrieve the NSMetadataItemLastUsedDateKey
from an NSMetadataItem
:
if let date = NSMetadataItem(url: url)?.value(forAttribute: NSMetadataItemLastUsedDateKey) as? Date {
print(date)
}
But to answer your actual question: That extended attribute holds a
UNIX struct timespec
(compare <time.h>
) value. That is the type used for st_atimespec
and other members of struct stat
(which in turn is the type used with fstat()
and similar system calls).
You have to copy the data into a timespec
value, compute the seconds from the tv_sec
and tv_nsec
members, and then create a Date
from the seconds since the Unix epoch.
func dataToDate(data: Data) -> Date {
var ts = timespec()
precondition(data.count >= MemoryLayout.size(ofValue: ts))
_ = withUnsafeMutableBytes(of: &ts, { lastuseddata.copyBytes(to: $0)} )
let seconds = TimeInterval(ts.tv_sec) + TimeInterval(ts.tv_nsec)/TimeInterval(NSEC_PER_SEC)
return Date(timeIntervalSince1970: seconds)
}
Example (your data):
let lastuseddata = Data([0xb9, 0xb6, 0xc3, 0x5e, 0x00, 0x00, 0x00, 0x00,
0xab, 0xd7, 0x32, 0x25, 0x00, 0x00, 0x00, 0x00])
print(dataToDate(data: lastuseddata))
// 2020-05-19 10:36:41 +0000
reverse engineer hex values to time date format
thx for your answer.
I discovered how the date and time is decoded.
Grp 3 and Grp 2 is in little endian the unix time but starting strangely from year 2010 and not from 1970.
So I have to add 40 years to get the correct year.
For example:
00:fe:a6:11:f5:0d:c7:19:00:ff:01:09:00:00:00:00 --> 03.06.2017 - 07:44:06
unix time decoded:
0d:f5:11:a6 --> 234164646 -> unix time stamp 1977-06-03T05:44:06+00:00 in ISO 8601
adding 40 years to this unix time stamp I get the correct date and time.
Android BLE: Convert ScanResult timestampNanos to System nanoTime
Use the following code to convert the getTimestampNanos() to system millis by using SystemClock.elapsedRealtime():
long rxTimestampMillis = System.currentTimeMillis() -
SystemClock.elapsedRealtime() +
scanResult.getTimestampNanos() / 1000000;
This can be converted easily to a Date object:
Date rxDate = new Date(rxTimestampMillis);
Then you then get the time as a string:
String sDate = new SimpleDateFormat("HH:mm:ss.SSS").format(rxDate);
Related Topics
Working with Nested Async Firebase Calls Swiftui
Swiftui App Crashes Every Time When Trying to Add Item to Grouped Items
How to Constrain 'self' to a Generic Type
Cannot Convert Value of Type 'Foo!' to Expected Argument Type 'Foo!'
Invalid Redeclaration of Typealias
How to Get Address in English Language Only Using Gmsgeocoder
Firebase Data Structure Best Practice for User Interaction
Cannot Divide and Assign Int64 Value
How to Cache Cells and Also Reuse Cells in a Collectionview That Has Avplayers Embedded in Each Cell
Biometric Authentication Evaluation with Swiftui
Swift Package: Ld: Warning: Dylib Was Built for Newer Macos Version (11.0) Than Being Linked (10.15)
Swift Video to Document Directory
How to Do Imageview.Startanimating() with Completion in Swift
Why Is Swift Giving Me Inaccurate Floating Point Arithmetic Results