how to send hexadecimal values using gcdasyncsocket? - ios

I have an array with nsstring like:
<__NSArrayM 0x20860370>(
3a,
4d,
00,
03,
04,
00,
07,
00,
0d,
0a
)
how can i send this data as real hexadecimal values using GCDAsyncsocket? I need to send all this values for every time i call the function for write to socket (es: 3a,
4d,
00,
03,
04,
00,
07,
00,
0d,
0a
)
I try using a function like:
[socket writeData:[array dataUsingEncoding:NSUTF8StringEncoding] withTimeout:1 tag:0];
But in this way i send character, not hex values...
thanks for your help!

Related

How to use DateComponents to represent the extra 1 hour period at the end of day light saving?

Usually, during end of day light saving, we will be gaining extra 1 hours.
Take Tehran timezone as an example.
During 22 September 2021, Tehran will backward by 1 hour from 00:00
AM, to 11:00 PM.
I wrote the following code to demonstrate such.
import UIKit
func date(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int) -> Date {
var dateComponents = DateComponents()
dateComponents.year = year
dateComponents.month = month
dateComponents.day = day
dateComponents.hour = hour
dateComponents.minute = minute
dateComponents.second = second
let date = Calendar.current.date(from: dateComponents)!
return date
}
// During 22 September 2021, Tehran will backward by 1 hour from 00:00 AM, to 11:00 PM.
let tehranTimeZone = TimeZone(identifier: "Asia/Tehran")!
let oldDefault = NSTimeZone.default
NSTimeZone.default = tehranTimeZone
defer {
NSTimeZone.default = oldDefault
}
let date1 = date(year: 2021, month: 09, day: 21, hour: 23, minute: 59, second: 59)
let date2 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 00)
let date3 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 01)
// STEP 1: 2021 Sep 21 23:59:59 => 1632252599.0, Tuesday, September 21, 2021 at 11:59:59 PM Iran Daylight Time
print("STEP 1: 2021 Sep 21 23:59:59 => \(date1.timeIntervalSince1970), \(date1.description(with: .current))")
// STEP 2: 2021 Sep 22 00:00:00 => 1632256200.0, Wednesday, September 22, 2021 at 12:00:00 AM Iran Standard Time
print("STEP 2: 2021 Sep 22 00:00:00 => \(date2.timeIntervalSince1970), \(date2.description(with: .current))")
// STEP 3: 2021 Sep 22 00:00:01 => 1632256201.0, Wednesday, September 22, 2021 at 12:00:01 AM Iran Standard Time
print("STEP 3: 2021 Sep 22 00:00:01 => \(date3.timeIntervalSince1970), \(date3.description(with: .current))")
From STEP 1 transits to STEP 2, instead for their timeIntervalSince1970 different by +1 seconds, their difference are +3601 seconds, due to the extra 1 hour gain.
Now, my question is, how can we use DateComponents to represent the extra 1 hour period at the end of day light saving?
In another, how can I use DateComponents to generate a Date which is capable to print the following?
2021 Sep 21 23:00:00 => 1632252600.0, Tuesday, September 21, 2021 at 11:00:00 PM Iran Standard Time
Now, we understand that, in Tehran, during 2021 Sept 21, there are 2 type of 23:00:00 time
23:00:00 Iran Daylight time (Epoch is 1632249000)
23:00:00 Iran Standard time (Epoch is 1632252600)
23:00:00 Iran Daylight time (Epoch is 1632249000)
I can represent the above using
let date = date(year: 2021, month: 09, day: 21, hour: 23, minute: 00, second: 00)
23:00:00 Iran Standard time (Epoch is 1632252600)
I have no idea how to represent the above. As, I do not find a way in DateComponents, to enable us to specific whether the local time is belong to standard time, or daylight time.
DateComponents do not have a time zone. The time zone comes into it when you convert DateComponents to a Date, using the call Calendar.date(from:). It's the calendar's time zone that determines how those DateComponents are converted to a Date.
Instead of using Calendar.current, create a custom calendar and set it to the IRST time zone. (I couldn't figure out the time zone for Iran Daylight time. I would have expected it to have the abbreviation "IRDT", but that doesn't work.)
Let's say we have a calendar irstCalendar that's set to Iran Standard Time ("IRST").
If you use irstCalendar.date(from: dateComponents) you'll always get the Date based on standard time.
Consider this code:
func date(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int, calendar: Calendar = Calendar.current) -> Date {
var dateComponents = DateComponents()
dateComponents.year = year
dateComponents.month = month
dateComponents.day = day
dateComponents.hour = hour
dateComponents.minute = minute
dateComponents.second = second
let date = calendar.date(from: dateComponents)!
return date
}
guard let tehranStandardTimeZone = TimeZone(abbreviation: "IRST") else {
fatalError("Can't create time zones")
}
var tehranSTCalendar = Calendar(identifier: .gregorian)
tehranSTCalendar.timeZone = tehranStandardTimeZone
let tehranDateFormatter = DateFormatter()
tehranDateFormatter.dateStyle = .medium
tehranDateFormatter.timeStyle = .medium
tehranDateFormatter.timeZone = tehranStandardTimeZone
let date1 = date(year: 2021, month: 09, day: 21, hour: 23, minute: 59, second: 59, calendar: tehranSTCalendar)
let date2 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 00, calendar: tehranSTCalendar)
let date3 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 01, calendar: tehranSTCalendar)
print("STEP 1: 2021 Sep 21 23:59:59 => \(date1.timeIntervalSince1970), \(tehranDateFormatter.string(from:date1))")
print("STEP 2: 2021 Sep 22 00:00:00 => \(date2.timeIntervalSince1970), \(tehranDateFormatter.string(from:date2))")
print("STEP 3: 2021 Sep 22 00:00:01 => \(date3.timeIntervalSince1970), \(tehranDateFormatter.string(from:date3))")
That outputs:
STEP 1: 2021 Sep 21 23:59:59 => 1632252599.0, Sep 21, 2021 at 11:59:59 PM
STEP 2: 2021 Sep 22 00:00:00 => 1632256200.0, Sep 22, 2021 at 12:00:00 AM
STEP 3: 2021 Sep 22 00:00:01 => 1632256201.0, Sep 22, 2021 at 12:00:01 AM

Wrong date from components

So this is interesting:
po Calendar.default.date(from: DateComponents(year: 2022, month: 1, hour: 16, minute: 1, second: 1, weekday: 1, weekOfMonth: 1))
▿ Optional<Date>
▿ some : 2021-12-26 23:01:01 +0000
- timeIntervalSinceReferenceDate : 662252461.0
I'm expecting January 1st 2022, but I'm getting December 26th 2021? Why is it doing this? Am I doing something wrong?
It's because the date components you are providing are contradictory. You have weekDay 1 (which will probably be a Sunday or Monday, depending on your locale) but the 1 jan 2022 is a Saturday.
(you also used Calendar.default when I think you meant Calendar.current?)
If you take out the weekDay term you will get the correct answer:
Calendar.current.date(from: DateComponents(year: 2022, month: 1, hour: 16, minute: 1, second: 1, weekOfMonth: 1))
// "Jan 1, 2022 at 4:01 PM"
You could also remove the weekOfMonth term as it is superfluous when you are specifying the actual date.

Ruby Time object for midnight UTC

I need to be able to create UTC Time objects in Rails, but no matter what I try it ends up being a local Time object converted to UTC.
application.rb
config.time_zone = "UTC"
Examples
I try to create a Time object for midnight on New Years 2017:
Time.new(year, month, 1, 0, 0, 0)
=> 2017-03-01 00:00:00 -0500
Time.new(year, month, 1, 0, 0, 0).in_time_zone
=> Wed, 01 Mar 2017 05:00:00 UTC +00:00
Time.new(year, month, 1, 0, 0, 0).in_time_zone('UTC')
=> Wed, 01 Mar 2017 05:00:00 UTC +00:00
You should be able to use:
Time.utc(year, month, 1, 0, 0, 0)
or just
Time.utc(year, month, 1)
I think the following might do what you want:
Time.new(year, month, 1, 0, 0, 0, "+00:00")
See the documentation for more details.

error handling when reading from buffer

I have a tablet sending a 5 byte message to a device, the message i delivered ok but sometimes the data is written to the wrong part of the buffer.
the code i have for reading the buffer is as follows, buffer is an int[25]
if((tempByte != 0) && (tempByte != 0xEE)) // If 'ready' returned..
{
tempByte &= 0x3F;
if(tempByte > 0)
{
for(i = 0; i < tempByte; i++)
{
buffer[bufferWrite] = periph_irxdata() ;
bufferWrite++;
bufferContents++;
if(bufferWrite > 24)
{
bufferWrite = 0;
}
}
}
}
if(bufferContents >= 5)
{
for(i = 0; i < 5; i++)
{
readings[i] = buffer[bufferRead];
bufferRead++;
bufferContents--;
if(bufferRead > 24)
{
bufferRead = 0;
}
}
if(readings[0] == 0x18)
{
tabletValue = readings[2];
OnOff = readings[1];
}
}
The idea being that if you start at [0] and write 5 bytes each time a message of 18, 01, 02, 00, 00 would repeat starting at the values [0], [5], [10] [15] [20].
This would read 18, 01, 02, 00, 00 | 18, 01, 02, 00, 00 | 18, 01, 02, 00, 00 | 18, 01, 02, 00, 00 after 5 messages have been sent.
The problem is that occasionally an error occurs and the buffer ends up off bt one ot tow bytes and looks like this 02, 00, 00, 18, 01 | 02, 00, 00, 18, 01 | 02, 00, 00, 18, 01 02, 00, 00, 18, 01.
The messages are being sent find but the device ignores them as it see the messages as garbage as the do not line up with the reading blocks.
What can I do error handling wise to automatically fix this when it happens ?
I was thinking of moving the read to search for the next 18 and read 5 bytes or maybe try to find the next 18 and get the bytes written back into the correct blocks.

How to identify if the given day, month, and year, combine a legal date?

Given 3 numbers: DD, MM, YYYY, what is the easiest way to know if they combine a legal date ?
Examples:
14, 05, 2011 => Legal
29, 02, 2011 => Illegal
29, 02, 2012 => Legal
35, 11, 1989 => Illegal
14, 18, 2011 => Illegal
14, 00, 2011 => Illegal
00, 11, 1979 => Illegal
31, 11, 1979 => Illegal
You can use valid_date? But it's YYYY, MM, DD:
irb(main):015:0> require 'date'
=> true
irb(main):021:0> Date::valid_date?(2011,05,14)
=> true
irb(main):022:0> Date::valid_date?(2011,02,29)
=> false
irb(main):023:0> Date::valid_date?(2012,02,29)
=> true
Date has a method valid_civil? .
require 'date'
dates = DATA.readlines.map{|line| line.split(', ').map(&:to_i)}
dates.each do |date|
d, m, y = date
puts Date.valid_civil?(y, m, d)
end
__END__
14, 05, 2011
29, 02, 2011
29, 02, 2012
35, 11, 1989
14, 18, 2011
14, 00, 2011
00, 11, 1979
31, 11, 1979
One option is to use something like:
require 'time'
def valid(year,month,day)
Time.parse "#{year}#{month}#{day}" rescue return false
return true
end

Resources