Replacing current date with String containing time in Swift - ios

I'm making an app where i get time from Parse as String e.g. "13:24" i need to prepare it to save in CoreData as Date, but replacing the time with this String to use it later in fireDate notification. What's the best approach to do this ? I should get the currentDate(), change it into string and somehow replace it with my timeString from Parse ?

You can use this snippet to get todays date + custom time:
let time = "12:34"
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy/MM/dd HH:mm"
var todayDateString = dateFormatter.stringFromDate(NSDate())
todayDateString.replaceRange(Range<String.Index>(start: todayDateString.endIndex.advancedBy(-5), end: todayDateString.endIndex), with: time)
let newDate = dateFormatter.dateFromString(todayDateString)

Related

How to get only time from date in swift

This question is not asked for the first time, but no solution works for me. I am getting time in String from Api response in the following format "14:45".
I want to compare this time with the current time, for this purpose I need to convert this string in Time formate(swift sports)
I always get nil after conversion
I have tried multiple ways but none of them worked for me and one is given for reference, I don't know what am I missing here
Thanks for any response
func stringToTime(str:String) -> Date{ // 14:45 passed here in str
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "hh:mm a"
print(str)
//here time string prints
let date = dateFormatter.date(from: (str))
print(date)
//date is nil here, should be 02:45 pm
return date!
}
If the time you get from the API is in 24h format you can do a string comparison
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm"
let currentTime = formatter.string(from: Date())
let compare = currentTime.compare("14:45")
You might need to set the time zone for the DateFormatter to make sure it uses the same as the API
It seems like you want to transform a time string in one format to another format. Your method signature should look like this:
func changeFormat(str:String) -> String {
Note that you should not output a Date here, because Dates don't have formats. They will always be printed in the same way. What you need to do in this method is 2 things:
parse str to a Date using a DateFormatter, specifying the format HH:mm. You seem to assume that DateFormatter can automatically work this format out. It can't :(
format the Date object you just got using a DateFormatter, specifying the format hh:mm a. This produces a string, not a date.
(You could also consider having the method return a Date (then it would be called parseTime), and do the second step just before you show the date to the screen.)
func changeFormat(str:String) -> String {
let dateFormatter = DateFormatter()
// step 1
dateFormatter.dateFormat = "HH:mm" // input format
let date = dateFormatter.date(from: str)!
// step 2
dateFormatter.dateFormat = "hh:mm a" // output format
let string = dateFormatter.string(from: date)
return string
}

How to calculate time (minutes) between two dates in swift?

What do we got: Date+time (format yyyy-mm-dd hh:mm a)
What are we looking for: Time difference in minutes
What operation: NewDate - OldDate
So, I wonder how I could accomplish above goal? I would like to format the date and time to US, regardless from which locale the user has. How can I do that?
Then I will save the 'oldTime' into UserDefaults, and use it for later calculation. The goal is to put the user on delay for 5 minutes and the calculations will be performed to determine if user should be on delay or not.
Just make a function that takes two dates and compares them like this.
import UIKit
func minutesBetweenDates(_ oldDate: Date, _ newDate: Date) -> CGFloat {
//get both times sinces refrenced date and divide by 60 to get minutes
let newDateMinutes = newDate.timeIntervalSinceReferenceDate/60
let oldDateMinutes = oldDate.timeIntervalSinceReferenceDate/60
//then return the difference
return CGFloat(newDateMinutes - oldDateMinutes)
}
//Usage:
let myDateFormatter = DateFormatter()
myDateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
//You'll need both dates to compare, you can get them by just storing a Date object when you first start the timer.
//Then when you need to check it, compare it to Date()
let oldDate: Date = myDateFormatter.date(from: String("2019-06-22 11:25"))
func validateRefresh() {
//do the comparison between the old date and the now date like this.
if minutesBetweenDates(oldDate, Date()) > 5 {
//Do whatever
}
}
You can, of course, change the .dateFormat value on the date formatter to be whatever format you'd like. A great website for finding the right format is: https://nsdateformatter.com/.
You say:
I would like to format the date and time to US, regardless from which locale the user has. How can I do that?
Specify a Locale of en_US_POSIX:
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd hh:mm a"
formatter.locale = Locale(identifier: "en_US_POSIX")
The locale is not the only question.
There’s also a timezone question. For example, you're driving out of Chicago and go from Central to Eastern timezones; do you really want to consider that one hour has passed?
Do you really want to discard seconds? If you do that, the 59 seconds between going from 8:00:00pm to 8:00:59pm will be considered “zero minutes” but the one second between 8:00:59pm and 8:01:00pm will be considered “one minute”.
Frankly, if I wanted to save a locale and timezone invariant date string, I’d suggest using ISO8601DateFormatter.
Then I will save the 'oldTime' into UserDefaults, and use it for later calculation.
If that’s why you’re using this DateFormatter, I’d suggest saving the Date object directly.
UserDefaults.standard.set(oldTime, forKey: "oldTime")
And to retrieve it:
if let oldTime = UserDefaults.standard.object(forKey: "oldTime") as? Date {
...
}
In terms of calculating the number of minutes between two Date objects
let minutes = Calendar.current
.dateComponents([.minute], from: date1, to: date2)
.minute
If you want the number of seconds, you can also use timeIntervalSince:
let seconds = date2.timeIntervalSince(date1)
And if you wanted to show the amount of elapsed time as a nice localized string:
let intervalFormatter = DateComponentsFormatter()
intervalFormatter.allowedUnits = [.minute, .second]
intervalFormatter.unitsStyle = .full
let string = intervalFormatter.string(from: date1, to: date2)
I'm not convinced that your question is the best way to go about accomplishing your aim, but the code below will work.
let dateFormatterNow = DateFormatter()
dateFormatterNow.dateFormat = "yyyy-MM-dd hh:mm a"
dateFormatterNow.timeZone = TimeZone(abbreviation: "EST")
let oldDateString = "2019-06-23 12:44 p"
let oldDate = dateFormatterNow.date(from: oldDateString)
let newDateString = "2019-06-23 12:54 p"
let newDate = dateFormatterNow.date(from: newDateString)
if let oldDate = oldDate, let newDate = newDate {
let diffInMins = Calendar.current.dateComponents([.minute], from: oldDate, to: newDate).minute
print(diffInMins)
}

Formatting JSON date to Swift date doesn't work

I'm trying to format this date: 2018-01-10T11:57:21.153 to Swift Date object like this:
let dateSentString = jsonDict["date"] as! String
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
let date = dateFormatter.date(from: dateSentString)!
For some reason, the app crashes on the last line.
What am I doing wrong? Thanks!
change the milli seconds format use 'SSS' specifier (with number of S's equal to number of digits of milliseconds ). for more information you get here
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"
from
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
Full code
let dateSentString = "2018-01-10T11:57:21.153"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"
let date = dateFormatter.date(from: dateSentString)!
print(date)
You have to first set formatter for date you are getting from JSON and then another formatter for the date you want.
First convert string fro JSON to a date variable by setting same format coming in JSON object .
Then you have to re-format that date variable into format you want.
I can write code if you want but it is better to try yourself.
Happy Coding

Same Date... But Different? Maybe timezone confusion

My problem is that I save a date into a string and as a date in CoreData. Later, I need to pull the date out of the string, compare the two, and find that they're the same date. Right now, that equality check fails. The two dates are 7 hours apart but with the minutes correct. I think it's a timezone issue but I can't figure out how to solve it.
The Origin of the Dates
I have a date from a date picker that I save to CoreData like this:
task.setValue(dueDatePicker.date, forKey: "dueDate")
After that I format the date and insert that date into a message:
let dateFormatter = DateFormatter()
let dateFormat = DateFormatter.Style.medium
let timeFormat = DateFormatter.Style.short
dateFormatter.dateStyle = dateFormat
dateFormatter.timeStyle = timeFormat
let formattedDate = dateFormatter.string(from: date)
let message = ("Upcoming task on \(formattedDate)")
That message becomes part of a notification. Hours or days later (when the notification fires and the user selects an action) I get the CoreData date:
fetchRequest.predicate = NSPredicate(format: "dueDate = %#", dateOfTask)
Then I decompose the notification message and get the date:
let start = notifString.range(of: "on ")
let rawDate = notifString[(start.upperBound)!..<(notifString.endIndex)]
let dateFormatter = DateFormatter()
dateFormatter.timeZone =
dateFormatter.dateFormat = "MMM-d-yyyy, H:mm a"
let dateFromString = dateFormatter.date(from: rawDate)
Lastly, I compare them. Currently the times are clearly the same day and minute but the timezones differ by about 7 hours. However, I don't want to just force a timezone that matches (Maybe force UTC for example) because that may not work for a user in another location.
How do I retrieve both dates without getting this apparent timezone issue?
Blatantly obvious, use userInfo as #Paulw11 suggested:
newLocalNotif.fireDate = dueDateWarningTime
newLocalNotif.alertBody = message
newLocalNotif.timeZone = TimeZone.autoupdatingCurrent
newLocalNotif.soundName = UILocalNotificationDefaultSoundName
newLocalNotif.category = "DueDates"
newLocalNotif.userInfo = ["name": name, "desc": desc, "dueDate" : date]

Saving Date in NSUserDefault gives incorrect values

When I print the value that has been stored in NSUserDefaults, I get the following output.
let prefs = NSUserDefaults.standardUserDefaults()
prefs.setObject(NSDate(), forKey: "ST")
print ("Hey \(prefs.objectForKey("ST")) ")
Hey Optional(2016-10-24 08:29:20 +0000)
There's a text Optional( displayed and what I want is to display only the Date time.
In addition, the time given is incorrect. How can i solve this ?
Maybe you can save your date as a formatted String
let formatter: DateFormatter = DateFormatter()
formatter.dateFormat = "yyyy.MM.dd HH:mm:ss ZZZ"
// Save Date...
let hoy: Date = Date()
let formato_hoy = formatter.string(from: hoy)
print(formato_hoy)
// Recover Date...
let future_format: String = "2016.10.24 09:54:22 +0200"
if let future = formatter.date(from: future_format)
{
print(future)
}
The ZZZ value in mask is related to time zone.

Resources