I am try to compare two date-
dateArrayForCompare, is the date which i get from NSDate and, dateArrayServer, is the date which i get from json response.
var dateArrayServer = NSMutableArray()
var dateArrayCalendar = NSMutableArray()
var dateArrayForCompare = NSMutableArray()
let dateHomework:NSArray = allAsign.valueForKey("date") as! NSArray
let homeWork = allAsign.valueForKey("assignmenttype") as! NSArray
for date in dateHomework{
self.dateArrayServer.addObject(date as! String)
}
let sys_date = NSDate()
print("System Date: \(sys_date)")
let df = NSDateFormatter()
df.dateFormat = "dd-MM-yyyy"
let currentDate = df.stringFromDate(sys_date)
print("String Date: \(currentDate)")
for dt in 0...self.dateArrayServer.count-1
{
if(self.dateArrayServer.objectAtIndex(dt) .isEqualToString("\(self.dateArrayForCompare)"))
{
print("Assignment on date: \(self.dateArrayServer.objectAtIndex(dt)) are:\n\(allAsign.objectAtIndex(dt))")
}else
{
print("\(self.dateArrayServer.objectAtIndex(dt)) doesn't match with \(self.dateArrayForCompare) ")
}
}
But get this result-
Something like this (swift 2.2)
for dt in 0 ... dateArrayServer.count-1
{
let date1 = dateArrayServer.objectAtIndex(dt) as! String
for value in dateArrayForCompare.enumerate() {
if date1 == value.element as! String {
print(date1)
}
}
}
Related
As I am new to swift, I stuck here from very longer,I am trying to get date from array between start date and end date,.
I have tried these code which refered from [https://stackoverflow.com/questions/10216991/fetching-dates-which-comes-between-startdate-and-enddate], But I am getting the error as "Value of type '[Date]' has no member 'filtered'".
In swift
var predicate = NSPredicate(format: "(SELF > %#) AND (SELF < %#)", startdate!, enddate!)
var result = arrayWithDates.filtered(using: predicate)
Expected output:
dateArray = ["12/01/1996","13/01/1996","15/01/1996","17/01/1996"]
startdate = "13/01/1996"
enddate = "17/01/1996"
output = ["13/01/1996","15/01/1996","17/01/1996"]
please help me to acheive this, thanks in advance
You can do it this way:
import Foundation
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT")
let dateArray = ["12/01/1996","13/01/1996","15/01/1996","17/01/1996"]
let startdate = dateFormatter.date(from: "13/01/1996")!
let enddate = dateFormatter.date(from: "17/01/1996")!
let output = dateArray
// Map your strings to Date objects excluding nils.
.compactMap { dateFormatter.date(from: $0) }
// Filter the mapped array by your condition.
.filter { $0 >= startdate && $0 <= enddate }
You can try below code, it works for me:
class ViewController: UIViewController {
var arrDates = NSArray()
var arrResultDates = NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
arrDates = ["12/01/1996","13/01/1996","15/01/1996","17/01/1996"]
let strStartDate = "\(arrDates.firstObject!)"
let strEndDate = "\(arrDates.lastObject!)"
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
//Get start date
var startDate = formatter.date(from: strStartDate)
let endDate = formatter.date(from: strEndDate) // last date
// Formatter for printing the date, adjust it according to your needs:
let fmt = DateFormatter()
fmt.dateFormat = "dd/MM/yyyy"
let calendar = NSCalendar.current
while startDate! <= endDate! {
startDate = calendar.date(byAdding: .day, value: 1, to: startDate!)!
let strDate = fmt.string(from: startDate!)
if arrDates.contains(strDate)
{
arrResultDates.add(strDate)
}
}
print(arrResultDates)
}
Hope it will helps you :)
If you really need to use NSPredicate you have to bridge the array to NSArray which responds to filtered(using:
let predicate = NSPredicate(format: "(SELF > %#) AND (SELF < %#)", startdate!, enddate!)
let result = (arrayWithDates as NSArray).filtered(using: predicate)
However in the world of Swift this is not recommended. Just use the filter function with a closure
let result = arrayWithDates.filter { $0 >= startdate! && $0 <= enddate! }
How Can I convert dates into string format?
I am getting dates between two dates ( From to end date). and I was using this below method
class Dates {
static func printDatesBetweenInterval(_ startDate: Date, _ endDate: Date) {
var startDate = startDate
let calendar = Calendar.current
let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd"
while startDate <= endDate {
print(fmt.string(from: startDate))
startDate = calendar.date(byAdding: .day, value: 1, to: startDate)!
}
}
static func dateFromString(_ dateString: String) -> Date {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
return dateFormatter.date(from: dateString)!
}}
and printing dates here
Dates.printDatesBetweenInterval(Dates.dateFromString("2017-10-02"), Dates.dateFromString("2017-10-9"))
result:
2017-10-02 2017-10-03 2017-10-04 2017-10-05 2017-10-06 2017-10-07 2017-10-08 2017-10-09
Now, I want pass this dates to String format to calendar (I am using FSCalendar lib into app). I want this format
example:
["2017-10-02", "2017-10-03", "2017-10-04", "2017-10-05", "2017-10-06", "2017-10-07", "2017-10-08", "2017-10-09"]
Can anyone guide me . Thanks
static func getDatesStringBetweenInterval(_ startDate: Date, _ endDate: Date)-> String {
var retval = "["
var startDate = startDate
let calendar = Calendar.current
let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd"
while startDate <= endDate {
if startDate < endDate {
retval.append("\"\(fmt.string(from: startDate))\", ")
} else {
retval.append("\"\(fmt.string(from: startDate))\"")
}
startDate = calendar.date(byAdding: .day, value: 1, to: startDate)!
}
retval.append("]")
return retval
}
Usage:
let aDate = Dates.dateFromString("2017-01-01")
let bDate = Dates.dateFromString("2017-01-05")
let datesString = Dates.getDatesStringBetweenInterval(aDate, bDate)
print(datesString)
Return date string array from your function, like this:
class Dates {
static func printDatesBetweenInterval(_ startDate: Date, _ endDate: Date) -> [String] {
var startDate = startDate
let calendar = Calendar.current
let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd"
var arrayDateString = [String]()
while startDate <= endDate {
let stringDate = fmt.string(from: startDate)
print("stringDate - \(stringDate)")
arrayDateString.append(stringDate)
startDate = calendar.date(byAdding: .day, value: 1, to: startDate)!
}
return arrayDateString
}
static func dateFromString(_ dateString: String) -> Date {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
return dateFormatter.date(from: dateString)!
}}
Now, print string array
let dateStringArray = Dates.printDatesBetweenInterval(Dates.dateFromString("2017-10-02"), Dates.dateFromString("2017-10-9"))
print("dateStringArray - \(dateStringArray)")
Edit:
Now, as you said, you've data in following format:
let dataArray = [
{ "hlddate": "07-Aug", "frmdt": "07-Aug-2017", "todt": "07-Aug-2017" },
{ "hlddate": "15-Aug", "frmdt": "15-Aug-2017", "todt": "15-Aug-2017" },
{ "hlddate": "10-Oct", "frmdt": "10-Oct-2017","todt": "31-Oct-2017" }
]
Try with following solution (Copy-paste, dataAray and class structure and see result):
class Dates {
static func dateFromString(dateString: String, webResponseDateFormat: String = "yyyy-MM-dd") -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = webResponseDateFormat
return dateFormatter.date(from: dateString)
}}
static func printDatesBetweenInterval(startDate: Date, endDate: Date, requiredDateFormat: String = "yyyy-MM-dd") -> [String] {
var startDate = startDate
let calendar = Calendar.current
let fmt = DateFormatter()
fmt.dateFormat = requiredDateFormat
var arrayDateString = [String]()
while startDate <= endDate {
let stringDate = fmt.string(from: startDate)
print("stringDate - \(stringDate)")
arrayDateString.append(stringDate)
startDate = calendar.date(byAdding: .day, value: 1, to: startDate)!
}
return arrayDateString
}
if let stringDateArray = dataArray as? [[String : String]] {
for arrayElement in stringDateArray {
if let startDateString = arrayElement["frmdt"], let startDate = Dates.dateFromString(dateString: startDateString, webResponseDateFormat: "dd-MMM-yyyy"), let endDateString = arrayElement["todt"], let endDate = Dates.dateFromString(dateString: endDateString, webResponseDateFormat: "dd-MMM-yyyy") {
let dateStringArray = Dates.printDatesBetweenInterval(startDate: startDate, endDate: endDate, )
print("\n\n**\ndateStringArray - \(dateStringArray)")
}
}
}
Final Update
// Actual data structure
let dataArray = ["07-8-2017","08-08-2017","10-09-2017","20-10-2017",21-10-2017","23-10-2017", etc..]
Use above method and change data in server response section and getting result.
if let Streams = jsonDict["data"] as! [AnyObject]? {
for arrayElement in Streams {
if let startDateString = arrayElement["frmdt"] {
self.somedateFromString = self.convertStringToDate(string: startDateString as! String)
if let endDateString = arrayElement["todt"] {
self.somedateEndString = self.convertStringToDate(string: endDateString as! String)
}
self.presentdays = Dates.printDatesBetweenInterval(Dates.dateFromString(self.somedateFromString), Dates.dateFromString(self.somedateEndString))
self.totalHolidays.append(contentsOf: self.presentdays)
}
}
}
I can get it to work fine using just Strings but if I try to use Doubles or NSDates then I get an error:
"Cannot assign value of type "NSDate?" to type "String?"
"Cannot assign value of type "Double?" to type "String?"
#IBAction func save(_ sender: Any) {
if item != nil {
item?.startdate = startDate.text
item?.pickup = pickup.text
item?.miles = miles.text
item?.company = company.text
item?.destination = destination.text
item?.enddate = endDate.text
} else {
let entitydescription = NSEntityDescription.entity(forEntityName: "Entity", in: pc)
let item = Entity(entity: entitydescription!, insertInto: pc)
item.startdate = startDate.text
item.pickup = pickup.text
item.miles = miles.text
item.company = company.text
item.destination = destination.text
item.enddate = endDate.text
}
do {
try pc.save()
} catch {
print(error)
return
}
navigationController!.popViewController(animated: true)
}
Here is what type each field is:
#NSManaged public var startdate: NSDate?
#NSManaged public var pickup: String?
#NSManaged public var miles: Double
#NSManaged public var company: String?
#NSManaged public var destination: String?
#NSManaged public var enddate: NSDate?
You need to convert miles.text, startdate.text and enddate.text to Double, NSDate and NSDate, respectively.
For startdate.text / enddate.text:
I'm not sure how what limit you have set for these values when the item is saved, but you should use a default value just incase the conversion fails. For this example, assume the dates are formatted "5/15/17" which takes the format M/d/y
let defaultDate = NSDate() //current date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "M/d/y"
if let startDateText = startdate.text, let startDate = dateFormatter.string(from: startDateText) as? NSDate {
item?.startdate = startDate
} else {
item?.startdate = defaultDate
}
if let endDateText = startdate.text, let endDate = dateFormatter.string(from: endDateText) as? NSDate {
item?.startdate = endDate
} else {
item?.startdate = defaultDate
}
For miles.text:
Same idea, use a default value incase the conversion failed based on what the text will be for item.miles
if let milesText = miles.text {
item?.miles = Double(miles.text) ?? 0.0 //default is 0.0
} else {
item?.miles = 0.0
}
or an easy one-liner—
item?.miles = Double(miles.text ?? "0.0")
if there's a specific default value you have in mind, just declare it before you assign the item's property,
let defaultMilesStr = "0.432"
item?.miles = Double(miles.text ?? defaultMiles)
Also, just a tip, it's good practice to not leave optionals wrapped when assigning values. So even though there was check to make sure item != nil, it's overall better to safely unwrap item with a "guard" or "if-let". Since you are creating a new item if one doesn't exist, id go with if-let in this case:
if let item = item {
// assign values to item's prop's
// item.startdate = .....
} else if let entityDescription = NSEntityDescription.entity(forEntityName: "Entity", in: pc), let item = Entity(entity: entityDescription, insertInto: pc) {
// assign values to item's prop's
// item.startdate = .....
}
//further execution
Convert your date string to NSdate then you are able to save that
Try this code i have provide my date string you mat change with your format
let dateString = "Thu, 22 Oct 2015 07:45:17 +0000"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEE, dd MMM yyyy hh:mm:ss +zzzz"
dateFormatter.locale = Locale.init(identifier: "en_GB")
let dateObj = dateFormatter.date(from: dateString)
dateFormatter.dateFormat = "MM-dd-yyyy"
Try this :
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = /* date_format_you_want_in_string from
* http://userguide.icu-project.org/formatparse/datetime
*/
let date = dateFormatter.date(from: /* your_date_string */)
and set it as :
item?.date = date
For miles you can use :
if let dMiles = Double(miles.text!) {
item?.miles.text = dMiles
} else {
print("Not a valid Double: \(textField.text!)")
}
Hope it Helps!!
How can I compare the values from data Base to my current date ? A date is saved in the data base when some action is performed, I need to compare that date with my current date and do some action. How can I do that ?
The date is saved my date base in this format:
var tasksin2 : Task?
dateFormatter.dateFormat = "dd/MM/yyyy hh:mm"
let mydate="\(dateFormatter.string(from: datePicker.date))"
tasksin2?.time=mydate
(UIApplication.shared.delegate as! AppDelegate).saveContext()
Here ya go:
extension String {
func toDate() -> Date? {
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy hh:mm"
return formatter.date(from: self)
}
}
class MyViewController: UIViewController {
var dateString1: String!
var dateString2: String!
override func viewDidLoad() {
super.viewDidLoad()
// set dateStrings
printDateTypes()
}
func printDateTypes() {
guard let date1 = dateString1.toDate() else {
print("dateString1: \(dateString1) | Failed to cast to \"dd/MM/yyyy hh:mm\"")
return
}
guard let date2 = dateString2.toDate() else {
print("dateString2: \(dateString2) | Failed to cast to \"dd/MM/yyyy hh:mm\"")
return
}
let isDescending = date1.compare(date2) == ComparisonResult.orderedDescending
print("orderedDescending: \(isDescending)")
let isAscending = date1.compare(date2) == ComparisonResult.orderedAscending
print("orderedAscending: \(isAscending)")
let isSame = date1.compare(date2) == ComparisonResult.orderedSame
print("orderedSame: \(isSame)")
}
}
I want to create a project where:
I create a task to do.
I create a stoping date for this task
I create three reminders using date picker
This I've done already. But now, I want the label to return for me the hour of the closest reminder (but I want the label to do this until the stoping date)
What I accomplish already is a playground project:
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
let currentDate = dateFormatter.dateFromString("2016-01-03 16:30")
var firstDate = dateFormatter.dateFromString("2016-01-03 13:00")
var secondDate = dateFormatter.dateFromString("2016-01-03 16:00")
var thirdDate = dateFormatter.dateFromString("2016-01-03 17:00")
var datesArray = [firstDate, secondDate, thirdDate]
let firstInterval = firstDate?.timeIntervalSinceDate(currentDate!)
let secondInterval = secondDate?.timeIntervalSinceDate(currentDate!)
let thirdInterval = thirdDate?.timeIntervalSinceDate(currentDate!)
let intervalArray = [firstInterval, secondInterval, thirdInterval]
var aboveZeroIntervals = [NSTimeInterval]()
for interval in intervalArray {
if interval > 0 {
aboveZeroIntervals.append(interval!)
}
}
//print(aboveZeroIntervals)
for date in datesArray {
if date?.timeIntervalSinceDate(currentDate!) == aboveZeroIntervals.minElement() {
print(dateFormatter.stringFromDate(date!))
}
}
How to get only hours from first/second/thirdDate and display the hour from those three dates that is the closest to currentDate hour? And perfectly finish displaying it after currentDate exceeds stopDoingDate...
I came up with something like this (code below). Can anyone look at it and tell me if there is some way I can simplify this?
extension NSDate
{
func isGreaterThanDate(dateToCompare : NSDate) -> Bool
{
//Declare Variables
var isGreater = false
//Compare Values
if self.compare(dateToCompare) == NSComparisonResult.OrderedDescending
{
isGreater = true
}
//Return Result
return isGreater
}
}
let calendar = NSCalendar.currentCalendar()
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
let currentDate = dateFormatter.dateFromString("2016-01-04 16:30")
let stopDoingDate = dateFormatter.dateFromString("2016-01-06 15:00")
if stopDoingDate!.isGreaterThanDate(currentDate!) {
let currentDateComponents = calendar.components([.Year, .Month, .Day, .Hour, .Minute], fromDate: currentDate!)
currentDateComponents.hour
currentDateComponents.minute
let dateTimeFormatter = NSDateFormatter()
dateTimeFormatter.dateFormat = "HH:mm"
let currentOnlyTime = dateTimeFormatter.dateFromString("\(currentDateComponents.hour):\(currentDateComponents.minute)")
var firstDate = dateFormatter.dateFromString("2016-01-03 13:00")
var firstDateComponents = calendar.components([.Hour, .Minute], fromDate: firstDate!)
var firstDateTime = dateTimeFormatter.dateFromString("\(firstDateComponents.hour):\(firstDateComponents.minute)")
var secondDate = dateFormatter.dateFromString("2016-01-03 16:00")
var secondDateComponents = calendar.components([.Hour, .Minute], fromDate: secondDate!)
var secondDateTime = dateTimeFormatter.dateFromString("\(secondDateComponents.hour):\(secondDateComponents.minute)")
var thirdDate = dateFormatter.dateFromString("2016-01-03 17:00")
var thirdDateComponents = calendar.components([.Hour, .Minute], fromDate: thirdDate!)
var thirdDateTime = dateTimeFormatter.dateFromString("\(thirdDateComponents.hour):\(thirdDateComponents.minute)")
var datesArray = [firstDateTime, secondDateTime, thirdDateTime]
let firstInterval = firstDateTime?.timeIntervalSinceDate(currentOnlyTime!)
let secondInterval = secondDateTime?.timeIntervalSinceDate(currentOnlyTime!)
let thirdInterval = thirdDateTime?.timeIntervalSinceDate(currentOnlyTime!)
let intervalArray = [firstInterval, secondInterval, thirdInterval]
var aboveZeroIntervals = [NSTimeInterval]()
for interval in intervalArray {
if interval > 0 {
aboveZeroIntervals.append(interval!)
}
}
//print(aboveZeroIntervals)
for date in datesArray {
if date?.timeIntervalSinceDate(currentOnlyTime!) == aboveZeroIntervals.minElement() {
let dateTime = calendar.components([.Hour, .Minute], fromDate: date!)
print(dateFormatter.dateFromString("\(currentDateComponents.year)-\(currentDateComponents.month)-\(currentDateComponents.day) \(dateTime.hour):\(dateTime.minute)")!)
print("Next todo hour is: \(dateTime.hour): \(dateTime.minute)")
}
}
} else {
print("Todo DONE")
}
I came up with this:
The only problem is to generate array of dates from currentDate to stopDoingDate but I will handle this alone (and probably post a solution here as well)
I used one of this forum post to generate extension to NSDate:
extension NSDate
{
func isGreaterThanDate(dateToCompare : NSDate) -> Bool
{
//Declare Variables
var isGreater = false
//Compare Values
if self.compare(dateToCompare) == NSComparisonResult.OrderedDescending
{
isGreater = true
}
//Return Result
return isGreater
}
}
//let calendar = NSCalendar.currentCalendar()
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
let currentDate = dateFormatter.dateFromString("2016-01-04 14:00")!
let stopDoingDate = dateFormatter.dateFromString("2016-01-06 16:00")!
let date1 = dateFormatter.dateFromString("2016-01-04 09:00")
let date2 = dateFormatter.dateFromString("2016-01-04 15:00")
let date3 = dateFormatter.dateFromString("2016-01-05 09:00")
let date4 = dateFormatter.dateFromString("2016-01-05 15:00")
let date5 = dateFormatter.dateFromString("2016-01-06 09:00")
let date6 = dateFormatter.dateFromString("2016-01-06 15:00")
var dates: [NSDate] = [date1!, date2!, date3!, date6!, date5!, date4!]
if stopDoingDate.isGreaterThanDate(currentDate) {
var datesAfterCurrentDate = [NSDate]()
for date in dates {
if date.isGreaterThanDate(currentDate) {
datesAfterCurrentDate.append(date)
}
}
let sortedDatesAfterCurrentDate = datesAfterCurrentDate.sort({ $0.timeIntervalSince1970 < $1.timeIntervalSince1970 })
let dateToDisplay = sortedDatesAfterCurrentDate.first!
let timeFormatter = NSDateFormatter()
timeFormatter.timeStyle = .ShortStyle
print(timeFormatter.stringFromDate(dateToDisplay)) } else {
print("We are done here")
}
This forum is truly awesome! Thanks Leo Dabus for the simple idea!