goofenhour
goofenhour

Reputation: 169

Swift core data NSFetchRequest predicate to fetch date time

I have a database table called UVHour that is the following structure

UVHour

My app will populate the UVHour table from a JSON that looks like the following

[
    {
        "ORDER": 1,
        "DATE_TIME": "SEP/04/2020 04 AM",
        "UV_VALUE": 0
    },
    {
        "ORDER": 2,
        "DATE_TIME": "SEP/04/2020 05 AM",
        "UV_VALUE": 0
    }
]

Current NSFetchRequest

static var uvIndexNowRequest: NSFetchRequest<UVHour>
    {
        let dateTimeNow = Date()
        let formatter = DateFormatter()
        formatter.dateFormat = "MMM/d/yyyy hh a"
        let dateHourStr = formatter.string(from: dateTimeNow)
        
        let request: NSFetchRequest = UVHour.fetchRequest()
        
        request.sortDescriptors = [NSSortDescriptor(key: "order", ascending: true)]

        // Below code will throw 'NSInvalidArgumentException', reason: 'Unable to parse the format string "date_time == Sep/4/2020 08 PM"
        // request.predicate = NSPredicate(format: "date_time == \(dateHourStr)")
        
        return request
    }

Question

How can I write a predicate that will fetch the UVHour with the current date and time matching the current hour?

Example

Say that the current date is September 4th, 2020 04:10 AM.

Based on the above JSON I would fetch a UVHour that is the following

[
    {
        "ORDER": 1,
        "DATE_TIME": "SEP/04/2020 04 AM",
        "UV_VALUE": 0
    }
]

How can I do this?

Upvotes: 1

Views: 475

Answers (2)

vadian
vadian

Reputation: 285079

A shorter alternative is an extension of NSDate(!) to get the hour. The benefit is you can use the computed property as a keypath.

extension NSDate {
    dynamic var isInCurrentHour : Bool {
        return Calendar.current.isDate(self as Date, equalTo: Date(), toGranularity: .hour)
    }

}


static var uvIndexNowRequest: NSFetchRequest<UVHour>
{
    let request: NSFetchRequest = UVHour.fetchRequest()
    request.sortDescriptors = [NSSortDescriptor(key: "order", ascending: true)]
    request.predicate = NSPredicate(format: "date_time.isInCurrentHour == TRUE")
    
    return request
}

Upvotes: 1

goofenhour
goofenhour

Reputation: 169

I was able to update uvIndexNowRequest to find my solution. See below code

static var uvIndexNowRequest: NSFetchRequest<UVHour>
    {
        let dateTimeNow = Date()
        
        let formatter = DateFormatter()
        formatter.timeZone = .current
        formatter.dateFormat = "MMM/d/yyyy hh a"
        
        // Find date String from 'formatter.dateFormat'
        let dateHourStr = formatter.string(from: dateTimeNow)
        
        // Get date from dateHourStr
        let someDateTimeOpt = formatter.date(from: dateHourStr)
        
        let request: NSFetchRequest = UVHour.fetchRequest()
        
        request.sortDescriptors = [NSSortDescriptor(key: "order", ascending: true)]
        
        if let someDate = someDateTimeOpt {
            request.predicate = NSPredicate(format: "date_time == %@", someDate as CVarArg)
        }
        
        return request
    }

Upvotes: 1

Related Questions