如何根据 swift 中领域对象的特定日期进行过滤?

How can I filter by specific date from realm object in swift?

我有一个日期 属性 类型为 Date 的领域对象,我想获取具有特定日期的项目列表。

如果我点击日历中的特定日期,例如 2020-03-06 ,那么它将显示在 2020-03-06 中创建的项目列表。

:: 已编辑::

Here is my realm object named "Profile" and there are dates from 2020-03-05 to 2020-03-08 .

Here is my Profile object and ProfileManager Singleton.

class Profile: Object {
    @objc dynamic var date: Date!
    @objc dynamic var content: String!

    convenience init(_ content: String) {
        self.init()
        self.content = content
        self.date = Date()
    }
}


class ProfileManager {

    static let shared = ProfileManager()

    private var realm = try! Realm()

    var profileList: Results<Profile>?

    private init() {
        profileList = realm.objects(Profile.self)
    }

    func save(_ object: Profile) {
        do {
            try realm.write {
                realm.add(object)
            }
        } catch {
            print(error)
        }
    }

    func addNewProfile(_ content: String) {
        let newProfile = Profile(content)
        save(newProfile)
    }
}

And lastly, here is a viewController which has to buttons. One for adding new Profile, and one for printing filtered profile list.

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func addProfilePressed(_ sender: Any) {
        ProfileManager.shared.addNewProfile("profile content")
    }

    @IBAction func filterButtonPressed(_ sender: Any) {
        let stringDate = "2020-03-09"
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd"
        let searchDate:Date = dateFormatter.date(from: stringDate)!
        let results = ProfileManager.shared.profileList!.filter("date == %@", searchDate)
        print(searchDate)
        print(results)
        for profile in results {
            print(profile.content!)
        }
    }
}

the result on the console, when filterButtonPressed method called.

2020-03-08 15:00:00 +0000
Results<Profile> <0x7f9b36f160a0> (

)

我该如何解决这个问题? 这是另一个问题。 我设置为 'stringDate' 值“2020-03-09” 但是当我打印转换后的日期 'searchDate' 时,它会打印“2020-03-08” 为什么会这样?

希望现在我的问题更容易理解了。

我原来的答案在下面,经过大量研究后只是有些正确。

实际答案与日期的时间戳部分有关。

所以...如果我们使用以下代码创建一个日期对象并将其设置为已知日期,

let stringDate = "2020-03-08"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let searchDate:Date = dateFormatter.date(from: stringDate)!

实际对象看起来像这样

2020-03-08T05:00:00.000Z

然而,Profile 对象的创建方式是这样的

convenience init(_ content: String) {
   self.init()
   self.content = content
   self.date = Date()
}

那个日期对象看起来像这样

2020-03-08T16:10:25.123Z

如您所见,如果我们过滤特定日期,则这些日期不相等

2020-03-08T05:00:00.000Z != 2020-03-08T16:10:25.123Z

这就是为什么

let stringDate = "2020-03-08"
let searchDate:Date = dateFormatter.date(from: stringDate)!
let searchResults = realm.objects(Profile.self).filter("date == %@", searchDate)

找不到日期,因为它正在为此过滤

2020-03-08T05:00:00.000Z

要修复,请将配置文件 class 更改为带有默认时间戳的日期戳

class Profile: Object {

    @objc dynamic var date: Date!
    @objc dynamic var content: String!

    convenience init(_ content: String) {
        self.init()
        self.content = content

        let formatter = DateFormatter()
        formatter.timeStyle = .none
        formatter.dateFormat = "MM/dd/yy"

        let today = Date()
        let s = formatter.string(from: today)
        let d = formatter.date(from: s)

        self.date = d
    }
}

或者,将您的日期存储为字符串 yyyymmdd,这将完全消除歧义。

-- 下面是原始答案 ---

日期对象完全支持按日期过滤。这里有两个简单的例子。一种用于过滤特定日期(针对您的问题),另一种用于使用 BETWEEN 过滤日期范围。

请注意,我有一个函数 makeDate 可以将字符串转换为日期对象。此示例使用具有 dog_birthdate 日期 属性.

的 Realm DogClass 对象

这会过滤具有特定日期的对象

let searchDate = self.makeDate(fromString: "06/01/2019")
let specificDateResults = realm.objects(DogClass.self)
                               .filter("dog_birthdate == %@", searchDate)
for dog in specificDateResults {
    print(dog.dog_name)
}

这会过滤日期范围内的对象

let startDate = self.makeDate(fromString: "06/01/2019")
let endDate = self.makeDate(fromString: "06/20/2019")
let dateRangeResuls = realm.objects(DogClass.self)
                           .filter("dog_birthdate BETWEEN {%@,%@}", startDate, endDate)
for dog in dateRangeResuls {
    print(dog.dog_name)
}

编辑:使用OP评论中的代码进行测试

let stringDate = "2019-06-01"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let searchDate:Date = dateFormatter.date(from: stringDate)!
let result = realm.objects(DogClass.self).filter("dog_birthdate == %@", searchDate)
for dog in result {
    print(dog.dog_name)
}

效果很好。