Swift 3.0: Get the difference between server UTC time & Local time - swift

I want to get the difference between server UTC time and Local time.
I write some code here..
var localTime:String!
var timeString:String = "06:05:00" //This is server UTC time
let dateFormator = DateFormatter()
dateFormator.dateFormat = "H:mm:ss"
dateFormator.timeZone = TimeZone(abbreviation: "UTC")
let dt = dateFormator.date(from: timeString)
if dt != nil {
dateFormator.timeZone = TimeZone.current
dateFormator.dateFormat = "h:mm a"
localTime = dateFormator.string(from: dt!) //Converted current local time
}
let date = Date()
let dateFormatter2 = DateFormatter()
dateFormatter2.dateFormat = "h:mm a"
let timeStr = dateFormatter2.string(from: date)// Current time
let date1 = dt!
let date2 = dateFormatter2.date(from: timeStr)!
var _date1:String = localTime
var _date2:String = timeStr
//TODO: Remove the bellow two line and Comment *Line: 1 , Uncomment *Line: 2
//_date1 = "11:00"
//_date2 = "12:00"
let _dateFormatter = DateFormatter()
_dateFormatter.dateFormat = "HH:mm a" //*Line: 1
//_dateFormatter.dateFormat = "HH:mm" //*Line: 2
let date3 = _dateFormatter.date(from: _date1)
let date4 = _dateFormatter.date(from: _date2)
let _interval = date4!.timeIntervalSince(date3!)
let intervalInInt = Int(_interval)
let minutes3 = Int((_interval / 60).truncatingRemainder(dividingBy: 60))
let hours3 = Int((_interval / 3600))
String(format: "%02d:%02d", hours3, minutes3)
In this code time interval chunk of code works fine when time is in HH:mm formate, But I would like to check difference between "11:00 AM" & "1:00 PM" so it's fails. So please help me. Thanks in advance.

Use following to difference with local timestamp
let date = Date()
let timeZoneOffset = Double(TimeZone.current.secondsFromGMT(for: date))

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!)

Date format from url (JSON)

How would I be able to take the date format from a URL and turn It into 2 separate date values in SwiftUI. The format from JSON is 2019-11-06 18:30:00 and I'm trying to get it to show as Dec 5 and would also like it to separate the time and show 8:00PM, is this possible?
This is the code that references the start time:
let startTime: String
var startTime: String {
return self.post.startTime
}
Let's step around the fact that 2019-11-06 18:30:00 can't be represented as Dec 5 and 8:00PM and focus on the work flow you'd need.
The basic idea is to:
Convert the String to a Date, via a DateFormatter
Use a custom DateFormatter to format the Date to the required "date" value
Use a custom DateFormatter to format the Date to the required "time" value
This might look something like...
let startTime = "2019-11-06 18:30:00"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
if let date = formatter.date(from: startTime) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM d"
let dateString = dateFormatter.string(from: date)
let timeFormatter = DateFormatter()
timeFormatter.dateFormat = "h:ma"
let timeString = timeFormatter.string(from: date)
} else {
print("Bad date/format")
}
In my testing, this outputs Nov 6 and 6:30PM
you can pass your string date to date with this function
func stringToDate(date: String, format: String) -> Date
{
let date2 = date.count == 0 ? getCurrentDate(format: "dd-MM-yyyy") : date
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone.init(identifier: "América/Mexico_City")
dateFormatter.dateFormat = format
let dateDate = dateFormatter.date(from: date2)
return dateDate!
}
func getCurrentDate(format: String) -> String
{
let formD = DateFormatter()
formD.dateFormat = format
let str = formD.string(from:Date())
return str
}
let dateA = stringToDate(date: "2019-11-06 18:30:00", format: "yyyy-MM-dd HH:mm:ss")
if dateA < Date() //Date() always will be the current date, including the time
{
print("dateA is older")
}
else
{
print("dateA in newer")
}
play with the format examples formats

How to calculate the correct time interval between two times that span two days in swift?

I'm trying to get the correct time interval between two times that span two days (Overnight). Here is my code successfully printing out the difference between two times - however for my use case I need the ability to span overnight, how might I do this?
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
//This time represents (23:00, Aug 07) for example
let date1 = dateFormatter.date(from: "23:00")!
//This time represents (06:00, Aug 08) for example
let date2 = dateFormatter.date(from: "06:00")!
let elapsedTime = date2.timeIntervalSince(date1)
print(abs(elapsedTime)/60/60)
//prints 17.0
My desired result is a print out of 7, as that is the amount of hours between 23:00, Aug 7 and 06:00, Aug 8 - My current code is correctly showing me the interval between those two times (as if they were from the same day) but I am trying to work out how to account for when those times overlap two days. Any help would be much appreciated.
UPDATE:
To give a more complete picture I have an object that has a start and and end date represented by a string:
Activity(startTime: "23:00", endTime: "06:00")
I use some functions to turn those strings into dates:
func startDate(startTime: String) -> Date {
let currentDate = Date().string(format: "dd-MM-yyyy")
let myStartingDate = "\(currentDate) \(startTime)"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm"
let startDate = dateFormatter.date(from: myStartingDate)
return startDate!
}
func endDate(endTime: String) -> Date {
let currentDate = Date().string(format: "dd-MM-yyyy")
let myEndingDate = "\(currentDate) \(endTime)"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm"
let endDate = dateFormatter.date(from: myEndingDate)
return endDate!
}
So my more complete workings look more like this:
func calculateTimeInterval(activity: Activity) {
let startHourDate = self.startDate(startTime: activity.startTime)
let endHourDate = self.endDate(endTime: activity.endTime)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
//This time represents (23:00, Aug 07) for example
let date1 = startHourDate!
//This time represents (06:00, Aug 08) for example
let date2 = endHourDate!
let elapsedTime = date2.timeIntervalSince(date1)
print(abs(elapsedTime)/60/60)
}
//prints 17.0
Without a date part the only way to determine if the end time is past midnight is if the end time is less than the start time. If so your code can be changed to
var elapsedTime = date2.timeIntervalSince(date1)
if elapsedTime < 0 {
let date3 = date2 + 60 * 60 * 24
elapsedTime = date3.timeIntervalSince(date1)
}
print(elapsedTime/60/60)
You can write an Extension to Date like this:
extension Date {
func hours(from date: Date) -> Int {
return Calendar.current.dateComponents([.hour], from: date).hour ?? 0
}
}
And just use it on any Date directly. This way you don't need DateFormatter at all. Hope this helps!

Swift3 extracting a Date from a Custom Format String

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).

Comparing Time Strings

I have 2 times that create a time range that a map annotation is visible(a start time and an end time). Whenever the current time is greater than the end time, the annotation is removed. The user inputs the times as a string then I add that time string to the current date string, then I convert the date as "h:mm a, M/dd/yyyy" into an actual date. The problem I am having is that if someone says the event starts at night (PM) then ends in the early morning or something (AM) then the event annotation is instantly removed because it creates the end time as AM time of the day that is about to end instead of the new day. Here is my current method for getting the time strings in code:
let SpotStartTime = StartTimeTextField.text;
let SpotEndTime = EndTimeTextField.text;
let date = NSDate();
let formatter = NSDateFormatter();
formatter.dateFormat = "M/dd/yyyy";
let Date = formatter.stringFromDate(date)
let EndTime = SpotEndTime;
let RealEndTime = (EndTime! + ", " + Date);
print(RealEndTime);
then I convert this string into a date using this method:
let TimeStr = EndTime
let dateFormater : NSDateFormatter = NSDateFormatter()
dateFormater.dateFormat = "h:mm a, M/dd/yyyy
let EndDate = (dateFormater.dateFromString(TimeStr))
let realEnd = EndDate
How do I modify this so that I can compare the StartTimeTextField to the EndTimeTextField? I need something that basically compares the two and if the StartTimeTextField has "PM" in it and the EndTimeTextField has "AM" in it then the EndTime gets 24 hours added to it, but I don't know how to do this in code.
Can anyone help? Thanks
I hope that I understood what you want to do, I come up with this function:
func getTime(startTime:String, startM:String, endTiem: String, endM:String) {
let date = NSDate();
let formatter = NSDateFormatter();
formatter.dateFormat = "M/dd/yyyy";
let dateStrStart = formatter.stringFromDate(date)
var dateStrEnd = ""
if (startM == "PM" && endM == "AM") {
let dateEnd = NSDate(timeInterval: 86400, sinceDate: date)
let formatter = NSDateFormatter();
formatter.dateFormat = "M/dd/yyyy";
dateStrEnd = formatter.stringFromDate(dateEnd)
} else {
dateStrEnd = dateStrStart
}
let RealEndTime = (endTiem + ", " + dateStrEnd);
let RealStartTime = (startTime + ", " + dateStrStart);
}
you just have to grab the AM or PM part.
And if the startTime is PM and the endTime is AM then your dateEnd is the currentDate plus one day.