Swift核心数据NSFetchRequest谓词可获取日期时间

问题描述

我有一个名为 UVHour 数据库表,该表具有以下结构

UVHour

我的应用程序将通过如下所示的JSON填充UVHour表

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

当前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
    }

问题

如何编写一个谓词,以获取与当前日期和当前小时相匹配的UVHour?

示例

说当前日期是2020年9月4日上午04:10。

基于上述JSON,我将获取以下的UVHour

[
    {
        "ORDER": 1,"UV_VALUE": 0
    }
]

我该怎么做?

解决方法

我能够更新 uvIndexNowRequest 来找到我的解决方案。参见下面的代码

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
    }
,

一个简短的替代方法是扩展NSDate(!)以获取小时。好处是您可以将计算出的属性用作键路径。

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
}