Swift3 extracting a Date from a Custom Format String - swift

Using the following overly complex code a date can almost be extracted from a string:
let dateStringArray:[String] = ["29-01-2017 10:41:18:825325012","29-01-2017 10:41:18:894631028"]
let formatString = "dd-MM-yyyy HH:mm:ss:nnnnnnnnn"
let dayRange = formatString.range(of: "dd")
let monthRange = formatString.range(of: "MM")
let yearRange = formatString.range(of: "yyyy")
let hourRange = formatString.range(of: "HH")
let minuteRange = formatString.range(of: "mm")
let secondRange = formatString.range(of: "ss")
let nanoRange = formatString.range(of:"nnnnnnnnn")
let dateString = dateStringArray[0]
let dateComponents = DateComponents( year:Int(dateString.substring(with: yearRange!)),
month:Int(dateString.substring(with: monthRange!)),
day:Int(dateString.substring(with: dayRange!)),
hour:Int(dateString.substring(with: hourRange!)),
minute:Int(dateString.substring(with: minuteRange!)),
second:Int(dateString.substring(with: secondRange!)),
nanosecond:Int(dateString.substring(with: nanoRange!)))
let nano = Int(dateString.substring(with: nanoRange!))
let currentCalendar = Calendar.current
let dateExtracted = currentCalendar.date(from: dateComponents)
print("\(dateExtracted!)")
The output from the final print is: "2017-01-29 10:41:18 +0000\n"
There are issues with this (1) there must be an easier way. (2) & more important, why is the nanosecond component apparently not appearing?

(1) there must be an easier way
Use a date formatter:
let dateString = "29-01-2017 10:41:18:825325012"
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm:ss:SSSSSSSS"
let dateExtracted = dateFormatter.date(from: dateString)!
(2) why is the nanosecond component apparently not appearing?
The description method of Date does not show fractional seconds, but
you can extract it again with
currentCalendar.component(.nanosecond, from: dateExtracted!)
The result may be slightly different from the original nanosecond value
in the string due to rounding errors, because Date stores internally
a floating point number (number of seconds since the reference date
Jan 1, 2001). If you use a date formatter as suggested above then
the resolution is limited to milliseconds (compare NSDateFormatter milliseconds bug).

Related

Does dateFromServer return the current Timezone of the person?

When I am running the code below the date and time returned are in correct format but just not from what's coming from the API which in this case is the currentVehicle.LastCommunicationDate!
Instead of coming the time from the currentVehicle.LastCommunicationDate! it's just returning a random timezone I think that is getting from the Server or something like that.
The output of the code I have right now is: 2022-01-21 02:04:15 when it should have been the live time in my local timezone but it's getting a different timezone.
The LastCommunicationDate coming from postman is in json format: "LastCommunicationDate": "2022-01-21T10:58:21.367",
The time i want to be is the one from Postman just converted from json to normal time like: yyyy-MM-dd HH:mm:ss
let timeinterval : TimeInterval = (currentVechicle.LastCommunicationDate! as NSString).doubleValue
let dateFromServer = NSDate(timeIntervalSinceNow:timeinterval)
let outFormatter = DateFormatter()
outFormatter.locale = Locale(identifier: "en_Al")
print(dateFromServer)
let dateFormater = outFormatter
outFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
print(dateFormater.string(from: dateFromServer as Date))
let dateFromServers = dateFormater.string(from: dateFromServer as Date)
LastCommunicationDate is a string, but you are converting it to a Double. Try this instead:
let lastCommunicationDate = "2022-01-21T10:58:21.367"
//Create dateformatter to convert string to Date
let isoDateFormatter = ISO8601DateFormatter()
isoDateFormatter.formatOptions = [
.withFullDate,
.withTime,
.withColonSeparatorInTime,
.withFractionalSeconds
]
let isoDateFormatter2 = ISO8601DateFormatter()
isoDateFormatter2.formatOptions = [
.withFullDate,
.withTime,
.withColonSeparatorInTime
]
let date = isoDateFormatter.date(from: lastCommunicationDate) ?? isoDateFormatter2.date(from: lastCommunicationDate)
//Create dateformatter to format date for output
let outFormatter = DateFormatter()
outFormatter.locale = Locale(identifier: "en_Al")
outFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let dateFromServers = outFormatter.string(from: date!)

Swift - Find Difference Between Upcoming Time and Current Time

I have a date/time returning from an API that is formatted in RFC 3339. RFC3399 looks like the following: "2021-07-24T22:36:39-04:00"
To be even more clear, it can be generated directly in swift doing something like the following:
let RFC3339DateFormatter = DateFormatter()
RFC3339DateFormatter.locale = Locale(identifier: "en_US_POSIX")
RFC3339DateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
RFC3339DateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
/* 39 minutes and 57 seconds after the 16th hour of December 19th, 1996 with an offset of -08:00 from UTC (Pacific Standard Time) */
let string = "1996-12-19T16:39:57-08:00"
let date = RFC3339DateFormatter.date(from: string)
My question is, how can I find the difference between times stored in RFC 3339 format in String variables.
For example, I have one variable titled currentTime that returns the current date/time in RFC 3339 format, and I have data from my API that returns a future time in RFC 3339 format. How can I subtract the time returned in each of these to determine the difference between the two?
Also, the date returned is not a concern to me. Only need to find the difference in time.
once you have your dates from the strings, you coud do something like this using component:
EDIT, using Alexander suggestion:
struct ContentView: View {
#State var timediff = ""
var body: some View {
Text(timediff)
.onAppear {
let RFC3339DateFormatter = DateFormatter()
RFC3339DateFormatter.locale = Locale(identifier: "en_US_POSIX")
RFC3339DateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
RFC3339DateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
let string1 = "1996-12-19T16:39:57-08:00"
let date1 = RFC3339DateFormatter.date(from: string1)
let string2 = "1996-12-19T13:19:27-08:00"
let date2 = RFC3339DateFormatter.date(from: string2)
if let d1 = date1, let d2 = date2 {
let result = Calendar.current.dateComponents([.hour, .minute], from: d1, to: d2)
timediff = result.description
}
}
}

dateformat spelling format swift

I am removing the current time from the current time and trying to find the minute difference. But it says 10/09/2019 13:13 and there is an error in the extraction process (I want to print as 1313) .1313 I can perform the extraction process. How do I print this data the way I want? I want to print dateFormat = "HHmm". In timertext2New.text, dateFormat = "dd / MM / yyyy HH: mm" like this. But I want to save it in HHmm format.
save12 output: 05/09/2019 10:48 but I want it to be "1048" . To perform extraction.
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy HH:mm"
timertext2New.text = formatter.string(from: datePicker.date)
let timehafıza2 = String(self.timertext2New.text!)
let df2 = DateFormatter()
df2.dateFormat = "HHmm"
var str2 = df2.string(from: Date())
str2 = timehafıza2
UserDefaults.standard.setValue(str2, forKey: "timertext2")
override func viewDidLoad() {
super.viewDidLoad()
let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HHmm"
let hour = dateFormatter.string(from: date)
var save12 = UserDefaults.standard.integer(forKey: "timertext2")
var fark : Int = (Int(hour)! - Int(save12))
}
Your code is pretty confusing and cannot work
You convert a date from a date picker with format "dd/MM/yyyy HH:mm"
Then you create a string with format "HHmm" from the current date which will be destroyed immediately because
You overwrite this string with the dd/MM/yyyy HH:mm string and save it to UserDefaults
Later you read the value from UserDefaults as integer which returns 0 because the "dd/MM/yyyy HH:mm" format is not representable by an integer.
My suggestion is to save all dates as Date and perform the date math with the dedicated methods of Calendar

Converting String to Date assigns wrong values

I am trying to construct a date from a string. The date is in .islamic calendar. I am using the following code
let StringValue = "1439/01/02"
//constructing the Hijri Date
let HijriFormatter = DateFormatter ()
HijriFormatter.calendar = Calendar(identifier: .islamic)
HijriFormatter.dateFormat="yyyy/MM/dd"
HijriFormatter.timeZone = TimeZone(abbreviation: "GMT+0:00")
let hijriDate = HijriFormatter.date(from: StringValue)
print (hijriDate!)
The output should be similar to the string. However, for some reason I am getting the following output:
2017-09-22 00:00:00 +0000
Any idea of why the code is behaving this way
You can get date components from hijri date using calendar:
let calenadr = Calendar(identifier: .islamicUmmAlQura)
let unitFlags: Set<Calendar.Component> = [.day, .month, .year]
let comps = calenadr.dateComponents(unitFlags, from: hijriDate!)
print(comps.day , comps.month, comps.year)

Why does Date formatter returns date correctly but time is showing as 00:00:00 when converting string to NSDate

I have a function where i have to retrieve a date from my own sqlite db of app. I have saved it using the formatter
My work flow
1..Save a date to db on Application did enter background(Saved as String)
2..When application become foreground again i make a date instance at that point of time too. Now i have two date's.
3..Convert both dates to correct format and get the seconds difference.
Convert from date to String-->
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.Z"
let myString = formatter.stringFromDate(NSDate()) // i get value"2017-05-18 16:49:38.+0530"
But when i reconvert it to NSDate(I Mean when i convert this to string again)-->
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.Z"
let lastloginDate=formatter.dateFromString(lastLogin) // i get value(Converting back to string \n for checking as the time difference was zero ) 2017-05-18 00:00:00.+0530
I want to compare two dates like a session out service , I do this by getting the calendar components difference of minute. However since its coming like this, the difference his always zero .
let myString1 = formatter.stringFromDate(date1)
let myString2 = formatter.stringFromDate(date2)
print("DATE 1\(myString1) DATE 2 \(myString2)")
let components = calendar.components(flags, fromDate: date2, toDate: date1, options: [])
let diff = components.second
print("Diffrence is \(diff)") // Always zero 😱
Why is this?
Try this one.
let myString1 = formatter.stringFromDate(date1)
let myString2 = formatter.stringFromDate(date2)
print("DATE 1\(myString1) DATE 2 \(myString2)")
let components = NSCalendar.currentCalendar().components([.Month, .Day, .Hour, .Minute, .Second], fromDate: myString1, toDate: myString2, options: [])
let diff = components.second
print("Difference is \(diff)")