How to query data that has a timestamp that is less than n hours? - swift

Currently my method for determining wether data is older than n hours uses this code after getting a timestamp from a document:
let timestamp = i.get("timestamp") as! Timestamp
let lastUpdatedDate = timestamp.dateValue()
let currentDate = Date()
let cal = Calendar.current
let components = cal.dateComponents([.hour], from: lastUpdatedDate, to: currentDate)
let diff = components.hour!
Usually this code is executed in a for each loop per each document after getting the documents from firestore.
Is there a way to query data using the field timestamp and checking if it is less than n hours instead?
ref.collection("References").whereField("timestamp", isLessThanOrEqualTo: n hours)

If you want a value to compare it against, you can do:
let date = Date().addingTimeInterval(-4 * 60 * 60)
Or you can do:
let date = Calendar.current.date(byAdding: .hour, value: -4, to: Date())
You may have to convert those to a Timestamp from this Date object, e.g., presumably something like:
let timestamp = Timestamp(date)

Related

how to get time difference form formatted time string values

Hi how to get time difference for two sting value
startTime = "09:00 AM"
EndTime = "05:30 PM"
func timeDifferenceBetweenTwoTime(startTime: String, endTime:String) ->CGFloat{
let start = startTime
let end = endTime
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "hh:mm a"
if let startDate = dateFormatter.date(from: start),
let endDate = dateFormatter.date(from: end) {
let hours: CGFloat = CGFloat(Calendar.current.dateComponents([.hour], from: startDate, to: endDate < startDate ? Calendar.current.date(byAdding: .day, value: 1, to: endDate) ?? endDate : endDate).hour ?? 00 )
return hours
}
return 00.00
}
The expected result is 08.50, But for me its giving 8.0
You just need to get the minutes instead of hours and divide it by 60. Btw you should also set your dateFormatter's default date to today:
func timeDifferenceBetweenTwoTime(startTime: String, endTime: String) -> CGFloat {
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.defaultDate = Calendar(identifier: .iso8601).startOfDay(for: Date())
dateFormatter.dateFormat = "hh:mm a"
if let startDate = dateFormatter.date(from: startTime),
var endDate = dateFormatter.date(from: endTime) {
if startDate > endDate {
endDate = Calendar.current.date(byAdding: .day, value: 1, to: endDate)!
}
let minute = Calendar.current.dateComponents([.minute], from: startDate, to: endDate).minute!
return CGFloat(minute) / 60
}
return 0
}
let startTime = "09:00 AM"
let endTime = "05:30 PM"
timeDifferenceBetweenTwoTime(startTime: startTime, endTime: endTime) // 8.5
You asked for the difference in hours. The Calendar function dateComponents(_:from:to:) will give you the number of whole hours between your dates if that's what you ask it for. By not also asking for the number of minutes, that gets truncated.
If you want hours and whole minutes you could ask for hours and minutes and do some math to combine them, or just ask for minutes as Leo suggests and divide minutes by 60.
You could also use endDate.timeIntervalSinceReferenceDate-startDate.timeIntervalSinceReferenceDate)/3600.0. That will give you a Double representing the exact number of hours between the two dates, including seconds and fractions of a second. (Not relevant given that your source Dates only specify hours and minutes, but there are other cases where that might be useful.)

How can I filter a Realm List by Date Swift NSPredicates

I want to filter my Realm List by Date. The Filter should show me every listed Item by month. I select the month "June" and the app should show me everything that was sold in June.
this is the code I tried but it obviously doesnt worked out.
let date = Date()
let format = DateFormatter()
format.dateFormat = "yyyy-MM-dd"
let formattedDate = format.string(from: date)
print(formattedDate)
let current = Calendar.current
let componentDate = current.component(.month, from: date)
print(current.component(.month, from: date))
let articles = realm.objects(Article.self).filter("artSoldDate = \(componentDate)")
return articles
You would need to use a date range filter. You would need to start the range at a specific date and end it at a certain date. For example,
let predicate = NSPredicate(format: "artSoldDate >= %# AND artSoldDate <= %#", startDate, endDate)
let result = realm.objects(Art.self).filter(predicate)
Your example seems to try and check when the artSoldDate is exactly some date.

Core Data Predicate Filter By Today's Date

How can I filter Core Data Managed Objects by their Date attribute in Swift?
The goal is to filter fetched objects by today's date.
You can't simply use to compare your date to today's date:
let today = Date()
let datePredicate = NSPredicate(format: "%K == %#", #keyPath(ModelType.date), today)
It will show you nothing since it's unlikely that your date is the EXACT comparison date (it includes seconds & milliseconds too)
The solution is this:
// Get the current calendar with local time zone
var calendar = Calendar.current
calendar.timeZone = NSTimeZone.local
// Get today's beginning & end
let dateFrom = calendar.startOfDay(for: Date()) // eg. 2016-10-10 00:00:00
let dateTo = calendar.date(byAdding: .day, value: 1, to: dateFrom)
// Note: Times are printed in UTC. Depending on where you live it won't print 00:00:00 but it will work with UTC times which can be converted to local time
// Set predicate as date being today's date
let fromPredicate = NSPredicate(format: "%# >= %K", dateFrom as NSDate, #keyPath(ModelType.date))
let toPredicate = NSPredicate(format: "%K < %#", #keyPath(ModelType.date), dateTo as NSDate)
let datePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [fromPredicate, toPredicate])
fetchRequest.predicate = datePredicate
It's by far the easiest & shortest way of showing only objects which have today's date.
In swift4, Lawrence413's can be simplify a bit:
//Get today's beginning & end
let dateFrom = calendar.startOfDay(for: Date()) // eg. 2016-10-10 00:00:00
let dateTo = calendar.date(byAdding: .day, value: 1, to: dateFrom)
It get rid of the component part, makes the code have better readability.
Might be helpful to add to Lawrence413's answer that to filter a list of records with an attribute holding today's date, you could use:
let fromPredicate = NSPredicate(format: "datetime >= %#", dateFrom as NSDate)
let toPredicate = NSPredicate(format: "datetime < %#", dateToUnwrapped as NSDate)
...Where "datetime is the name of the attribute"

Swift NSDate get current date but strip Year, Month, and Day

I am trying to get the current date using swift. I have that taken care of but it gets the year month and day and I really only want the current hour and minute. The reason being is that I am trying to later on compare a created date that only has an hour and minute. I am currently just using this
let currentDate = NSDate()
Thank you
let calendar = Calendar.autoupdatingCurrent
let components = calendar.dateComponents([.hour, .minute], from: Date())
let hour = components.hour
let minute = components.minute

Extract entity from last seven days core data

I am currently working with core data to store meals. My entities are date (Date), foods (string) and drinks (string). Now I want to extract all the foods stored for the last seven days. How would I do this? I know i should somehow use NSPredicate, but I can't figure out how exactly.
Get the current calendar
let calendar = NSCalendar.currentCalendar()
Get the current date
let now = NSDate()
Subtract 7 days from current date
let sevenDaysAgo = calendar.dateByAddingUnit(.Day, value: -7, toDate: now, options: [])!
Get the start of the day 7 days ago
let startDate = calendar.startOfDayForDate(sevenDaysAgo)
Create the predicate, literal date is the Core Data attribute
let predicate = NSPredicate(format:"(date >= %#) AND (date < %#)", startDate, now)