2
votes

Comment interroger une propriété de date dans Realm?

J'ai une base de données Realm avec un objet "Events" avec un nom de propriété "occasion" de type string, un nom de propriété "venue" de type string et l'autre est "date" de type Date (). Ma question est de savoir comment interroger les occasions qui ont une date identique à celle d'aujourd'hui (jour actuel). J'ai essayé ce code pour récupérer les occasions en utilisant le filtre de date et cela fonctionne:

@IBAction func addNewEventButtonPressed(_ sender: UIButton) {



    let newDataEntry = Events()

    newDataEntry.occasion = occasionTextFile.text!


    let dateString =  dateTextField.text!
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "dd/MM/yyyy"
    let dateFromString = dateFormatter.date(from: dateString)

    newDataEntry.date = dateFromString!

    do {
        try realm.write {
            realm.add(newDataEntry)
        }
    } catch {
        print("Error saving data \(error)")
    }


}

La date dans la base de données Realm montre une date dans ce format "17 janvier 2019 à 12h00: 00 AM "même si la date a été enregistrée au format jj / MM / aaaa. J'ai essayé de changer le format de la date, mais cela ne fonctionnera toujours pas. Ou dois-je définir un format pour la propriété de date lorsque je la déclare en premier lieu? Si oui, comment puis-je faire cela dans un objet de classe Realm? J'ai essayé mais cela a donné une erreur. Je suis coincé ici maintenant. Veuillez aider

Voici comment j'ai enregistré les données dans la base de données Realm:

let date = Date()
let dateFormatter = DateFormatter()
// dateFormatter.dateFormat = "dd/MM/yyyy"
dateFormatter.dateFormat = "d MMM yyyy"
let stringDate = dateFormatter.string(from: date)        

todayEvent = realm.objects(Events.self).filter("date = '\(stringDate)'").sorted(byKeyPath: "venue", ascending: true)


7 commentaires

Je suis désolé mais je ne comprends pas quelle est votre question? Le problème est-il de sauvegarder la date dans votre format? ou comment le récupérer?


Veuillez nous montrer comment enregistrer la propriété de date de l'objet de domaine


Désolé si je ne suis pas assez clair. Le problème réside dans la récupération des données à l'aide de la requête. Et je ne sais pas pourquoi la date a changé de format lorsqu'elle est enregistrée dans le royaume, bien qu'elle soit enregistrée dans un format différent, par exemple jj / mm / aaaa.


D'accord. Veuillez mettre à jour votre question et nous montrer comment vous enregistrez un objet de domaine avec une propriété de date


J'ai montré le cas de l'enregistrement dans la base de données du royaume dans la question modifiée.


que contient dateString ?


dateString est une chaîne de date provenant d'un DatePicker. DatePicker est également défini au format jj / MM / aaaa.


3 Réponses :


1
votes

Vous utilisez l'objet Date qui est avec l'heure et les paramètres régionaux, donc à utiliser uniquement avec la date, vous pouvez utiliser la fonction ci-dessous pour supprimer l'heure et les paramètres régionaux de l'objet de date:

let today = self.reomveTimeFrom(date: Date())
let predicate = NSPredicate(format: "date ==  %@",today as NSDate)
let results = realm.objects(Events.self).filter(predicate)

Maintenant, utilisez cette fonction pour obtenir l'objet de date exacte et récupérer les données de la base de données realm .

   func reomveTimeFrom(date: Date) -> Date {
            let components = Calendar.current.dateComponents([.year, .month, .day], from: date)
            let date = Calendar.current.date(from: components)
            return date!
        }

Terminer code source sur github


7 commentaires

@ DávidPásztor- mise à jour de la syntaxe pour swift, la précédente était pour react-native.


Rocky et Dan Karbayev, j'ai essayé les deux codes et l'application s'est plantée avec le message suivant dans la console: Arrêt de l'application en raison d'une exception non interceptée 'valeur invalide', raison: 'Objet attendu de type date pour la propriété' date 'sur l'objet de type 'Evénements', mais reçu: 19/01/2019 '. Je n'ai même pas eu la chance de saisir une date à laquelle l'application s'est plantée. D'où vient ce «19/01/2019»?


@halim - partagez votre schéma pour la table Events .


La classe d'événements utilisant la base de données Realm a 3 propriétés. 1. occasions de type String 2. lieu de type String 3. date de type Date ().


@Rocky Merci, mais l'application plante toujours lorsque je l'exécute en utilisant les nouveaux codes. J'utilise la version de Dan Karbayev maintenant. Bien que l'application s'exécute, elle n'affiche toujours pas le résultat de la requête dans ma vue de table


@halim vous pouvez obtenir une copie woking du code source complet sur le lien Github.


J'ai trouvé la réponse ici: stackoverflow.com/a/35965216/10784781 Merci beaucoup pour vos efforts.



1
votes

Selon Realm docs (c'est moi qui souligne):

Les opérateurs de comparaison ==, =,>,! = et BETWEEN sont pris en charge pour Int, Int8, Int16, Int32, Int64, Float, Double et Date types de propriétés

Ainsi, ce qui suit devrait fonctionner:

let date = Date()
todayEvent = realm.objects(Events.self)
    .filter("date == %@", date)
    .sorted(byKeyPath: "venue") // sorted in ascending order by default


4 commentaires

J'ai de nouveau utilisé votre code. Maintenant, l'application a démarré normalement et ne s'est pas plantée. Cependant, je n'ai toujours pas obtenu le résultat de la requête affichée dans le tableau.


J'ai mis une instruction d'impression pour "todayEvent" pour savoir si le code a été appelé dans la fonction de chargement, la console indique "Facultatif (Résultats <0x7f9a1754d9f0>. Je ne sais pas si c'est une info utile mais j'espère que cela aiderait pour résoudre le problème.


Juste pour mettre à jour. Lorsque je fais juste une requête normale sans le filtre dans la syntaxe, le tableau affiche toutes les données disponibles, y compris les dates. Si je mets le filtre dans la syntaxe de requête afin que le résultat affiche uniquement l'événement qui a la même date que le jour actuel, la table retourne vide. Donc ça doit être la syntaxe. Au moins c'est ce que je pense.


stackoverflow.com/a/35965216/10784781 . J'ai trouvé la réponse ici. Essayez maintenant de définir la requête sur «demain». Merci beaucoup.



0
votes

Le problème est que vous stockez des objets Date mais que vous essayez de filtrer cette propriété sous forme de chaîne.

Cette ligne

let dateStringToFind = "20190120"
let yyyymmddFormatter = DateFormatter()
yyyymmddFormatter.dateFormat = "yyyyMMdd"
let dateObjectToFind = yyyymmddFormatter.date(from: dateStringToFind)
let results = realm.objects(MyObject.self).filter("date == %@", dateObjectToFind)
if results.count > 0 {
    for myObject in results {
        print(myObject)
    }
} else {
    print("no objects have that date")
}

crée un objet Date () à partir d'un chaîne et c'est ce qui est stocké dans votre propriété Realm.

Un objet de date Realm ressemble à ceci

let aDateString = "01/20/2019"
let mmddyyyyFormatter = DateFormatter()
mmddyyyyFormatter.dateFormat = "MM/dd/yyyy"
if let dateObjectToStore = mmddyyyyFormatter.date(from: aDateString) {
    newDataEntry.date = dateObjectToStore
} else {
    print("could not create date object")
}

Voici votre filtre:

Expected object of type date for property 'date' on object of type 'Event', but received: 18 Jan 2019

Ceci crée une chaîne à partir d'un objet date et Realm ne saura pas quoi en faire. Si vous voulez filtrer une propriété de date, utilisez un objet de date pour le faire.

Cependant, cette ligne devrait se bloquer avec l'erreur suivante

let stringDate = dateFormatter.string(from: date)
todayEvent = realm.objects(Events.self).filter("date = '\(stringDate)'")

La solution est que si la propriété sur laquelle vous recherchez est une Date, le filtre doit être un objet Date.

Donc, un exemple d'écriture d'un objet date commençant par une chaîne mm / jj / aaaa

2019-01-18T05:00:00.000Z

Supposons que nous voulions maintenant trouver cet objet avec une chaîne de "aaaammjj"

let dateFromString = dateFormatter.date(from: dateString)

comme vous pouvez le voir, nous stocké une date en tant qu'objet de date, puis lors du filtrage, filtré pour un objet de date.

Il y a quelques mises en garde au filtrage et quelques exceptions, mais vous avez l'idée générale.


0 commentaires