Parse query where key contains A or B - Swift - ios

I am trying to run a parse query where a certain field contains either todays date or tomorrows date. Here is the code I have so far:
var date = Date() // first date
let calendar = Calendar.current
let date2 = (calendar as NSCalendar).date(byAdding: .day, value: 7, to: date, options: [])!
let dateFormatter:DateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let todaysString:String = dateFormatter.string(from: date)
let tomorrowString:String = dateFormatter.string(from: date2)
let query = PFQuery(className: "Events")
query.whereKey("dateString", contains: todaysString || tomorrowString)
But this will not run because it cannot convert the value. Does anyone know how I am suppose to write this line to show that dateString needs to contain either todaysString or tomorrowString? Thanks in advance.

You need to create separate queries, and join them with PFQuery.orQueryWithSubqueries(todayQuery, tomorrowQuery).

You need to create two separate query, Q1for todaysString and Q2 for tomorrowString. Now add both queries in an Array. And use PFQuery's function "orQueryWithSubqueries" to merge them in 3rd query Q3 and then execute the 3rd query Q3. I have used this in objective c and worked for me, I can post objective c code if you want

Related

In the calendar function "date(byAdding: .day, value: , to: )", does the date we give to the function include the current date or not?

I have an app that uses Core Data. I have a function
func showHistory(for days:Int)->Int {
var historyForXDaysInt = Int()
var calendar = Calendar.current
calendar.locale = .current
calendar.timeZone = .current
var startDate:Date?
var endDate = Date()
switch days{
case 1:
startDate = Date()
startDate = calendar.startOfDay(for: startDate!)
default:
startDate = calendar.date(byAdding: .day, value: -days+1, to: Date())
startDate = calendar.startOfDay(for: startDate!)
}
//There is more to this function, where I make the request but I just included the relevant part for my question
}
My question: I am trying to get relevant data from Core Data between two dates via the predicate let predicate = NSPredicate(format: "(completedDate >= %#) AND (completedDate <= %#)", startDate! as NSDate, endDate as NSDate).There is a completedDate property in my core data model. When I make the request I get data for 1 more day than I asked for. I tried solving it with adding 1 to the days variable. For example, if I am asking for 2 days of data (meaning days = 2) I get data for 3 days. What might be the cause? Why does it not work as intended without the +1 ?

How to calculate time (minutes) between two dates in swift?

What do we got: Date+time (format yyyy-mm-dd hh:mm a)
What are we looking for: Time difference in minutes
What operation: NewDate - OldDate
So, I wonder how I could accomplish above goal? I would like to format the date and time to US, regardless from which locale the user has. How can I do that?
Then I will save the 'oldTime' into UserDefaults, and use it for later calculation. The goal is to put the user on delay for 5 minutes and the calculations will be performed to determine if user should be on delay or not.
Just make a function that takes two dates and compares them like this.
import UIKit
func minutesBetweenDates(_ oldDate: Date, _ newDate: Date) -> CGFloat {
//get both times sinces refrenced date and divide by 60 to get minutes
let newDateMinutes = newDate.timeIntervalSinceReferenceDate/60
let oldDateMinutes = oldDate.timeIntervalSinceReferenceDate/60
//then return the difference
return CGFloat(newDateMinutes - oldDateMinutes)
}
//Usage:
let myDateFormatter = DateFormatter()
myDateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
//You'll need both dates to compare, you can get them by just storing a Date object when you first start the timer.
//Then when you need to check it, compare it to Date()
let oldDate: Date = myDateFormatter.date(from: String("2019-06-22 11:25"))
func validateRefresh() {
//do the comparison between the old date and the now date like this.
if minutesBetweenDates(oldDate, Date()) > 5 {
//Do whatever
}
}
You can, of course, change the .dateFormat value on the date formatter to be whatever format you'd like. A great website for finding the right format is: https://nsdateformatter.com/.
You say:
I would like to format the date and time to US, regardless from which locale the user has. How can I do that?
Specify a Locale of en_US_POSIX:
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd hh:mm a"
formatter.locale = Locale(identifier: "en_US_POSIX")
The locale is not the only question.
There’s also a timezone question. For example, you're driving out of Chicago and go from Central to Eastern timezones; do you really want to consider that one hour has passed?
Do you really want to discard seconds? If you do that, the 59 seconds between going from 8:00:00pm to 8:00:59pm will be considered “zero minutes” but the one second between 8:00:59pm and 8:01:00pm will be considered “one minute”.
Frankly, if I wanted to save a locale and timezone invariant date string, I’d suggest using ISO8601DateFormatter.
Then I will save the 'oldTime' into UserDefaults, and use it for later calculation.
If that’s why you’re using this DateFormatter, I’d suggest saving the Date object directly.
UserDefaults.standard.set(oldTime, forKey: "oldTime")
And to retrieve it:
if let oldTime = UserDefaults.standard.object(forKey: "oldTime") as? Date {
...
}
In terms of calculating the number of minutes between two Date objects
let minutes = Calendar.current
.dateComponents([.minute], from: date1, to: date2)
.minute
If you want the number of seconds, you can also use timeIntervalSince:
let seconds = date2.timeIntervalSince(date1)
And if you wanted to show the amount of elapsed time as a nice localized string:
let intervalFormatter = DateComponentsFormatter()
intervalFormatter.allowedUnits = [.minute, .second]
intervalFormatter.unitsStyle = .full
let string = intervalFormatter.string(from: date1, to: date2)
I'm not convinced that your question is the best way to go about accomplishing your aim, but the code below will work.
let dateFormatterNow = DateFormatter()
dateFormatterNow.dateFormat = "yyyy-MM-dd hh:mm a"
dateFormatterNow.timeZone = TimeZone(abbreviation: "EST")
let oldDateString = "2019-06-23 12:44 p"
let oldDate = dateFormatterNow.date(from: oldDateString)
let newDateString = "2019-06-23 12:54 p"
let newDate = dateFormatterNow.date(from: newDateString)
if let oldDate = oldDate, let newDate = newDate {
let diffInMins = Calendar.current.dateComponents([.minute], from: oldDate, to: newDate).minute
print(diffInMins)
}

Trying to return ONLY tomorrow's data using Swift and Core Data but it returns both today's and tomorrow's together?

I am trying to return ONLY tomorrow's data using Swift and Core Data but it returns both today's and tomorrow's together. Any idea why? Below is the code I am using. Thank you in advance!
let today = NSDate()
let tomorrow = NSCalendar.currentCalendar()
.dateByAddingUnit(
.Day,
value: 1,
toDate: today,
options: []
)
todoTomorrow = CoreDataManager.getData("ToDos", predicate: NSPredicate(format:"dueDate<%#", ((tomorrow))!)) as! [ToDos]
You need to modify your predicate to be dueDate < %# AND dueDate > %# with parameters tomorrow and today so it checks both the upper and lower allowed range of the dates.

How long ago did the User create a post, NSDate(), Manipulating the format of the "time of post" created

I am making a social app that saves its posts in user specific nodes , with that i am also saving the time of post in this format :-
Wednesday, July 20, 2016, 00:14
which i display with the post in the global feed of friends of the user.
Before 24 hours of that post , i want to display time of post on the feed as this :- "5 Hours Ago"
After 24 hours of that post time of post becomes something like this :- "Yesterday"...
After 48 hours of that post time of post becomes something like this :- "On 5 Aug"...
So far i have come up with these two options:-
1.) Change the time of the feed in the database, which i think would be much better option.
2.) Retrieve the time of post , iterate through MULTIPLE if conditions and set the time of post accordingly.
I would be able to implement the second option but i have no clue to how to go forward with option one
Given that my JSON tree is something like this
appname:{
users : {....
.....
user1 : {....
.....
postsCreated : {
post1 : {
..
timeofPost : ""Wednesday, Aug 5, 2016, 00:14""
}
}
}
}
}
I did stumble upon http://momentjs.com/ but thats for Javascript
Also any suggestion on my JSON tree or is it fine the way it is?
You propose:
Change the time of the feed in the database, which i think would be much better option.
No, the date in the database, as well as that which is communicated with web service, should not be a formatted string. The database and the web service should be capturing the raw dates (or, more accurately, RFC3339/ISO8601 format or seconds from some reference date). The formatting of the elapsed time in a string for the UI is the responsibility of the app.
Retrieve the time of post, iterate through MULTIPLE if conditions and set the time of post accordingly.
Yes, that's what you should do.
By the way, if you're going to omit the year, you probably have a fourth permutation which includes year if the date is more than one year in the past, e.g.:
func formattedPostDateString(date: NSDate) -> String {
let now = NSDate()
let elapsed = NSCalendar.currentCalendar().components([.Day, .Year], fromDate: date, toDate: now, options: [])
switch (elapsed.year, elapsed.day) {
case (0, 0):
return "\(elapsedFormatter.stringFromDate(date, toDate: now)!) \(agoDateString)"
case (0, 1):
return yesterdayString
case (0, _):
return "\(onDateString) \(lessThanOneYearFormatter.stringFromDate(date))"
default:
return "\(onDateString) \(moreThanOneYearFormatter.stringFromDate(date))"
}
}
Where
let onDateString = NSLocalizedString("On", comment: "prefix used in 'On 5 Aug'")
let agoDateString = NSLocalizedString("ago", comment: "suffix use in '4 hours ago'")
let yesterdayString = NSLocalizedString("Yesterday", comment: "showing 'date' where it's between 24 and 48 hours ago")
let elapsedFormatter: NSDateComponentsFormatter = {
let formatter = NSDateComponentsFormatter()
formatter.allowedUnits = [.Year, .Month, .Day, .Hour, .Minute, .Second]
formatter.unitsStyle = .Full
formatter.maximumUnitCount = 1
return formatter
}()
let lessThanOneYearFormatter: NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.dateFormat = NSDateFormatter.dateFormatFromTemplate("MMM d", options: 0, locale: nil)
return formatter
}()
let moreThanOneYearFormatter: NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.dateStyle = .MediumStyle
return formatter
}()
The only thing you need to do is to convert the string returned by the web service into NSDate object. To that end, the web service should probably return the post date in ISO 8601/RFC 3339 format (e.g. 2016-08-26T15:01:23Z format).
To create ISO8601/RFC3339 dates in Swift 2:
let isoDateFormatter: NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
return formatter
}()
And then:
let string = isoDateFormatter.stringFromDate(date)
Or
let date = isoDateFormatter.dateFromString(string)
Or in iOS 10+ using Swift 3, you can use the new ISO8601DateFormatter:
let isoDateFormatter = ISO8601DateFormatter()

Date comparison or timezone not set properly

I'm trying to do a simple comparison of dates with the intent of moving to another array index based on the day.
Though vastly more efficient than the code I was using, the following (Unable to parse a date) doesn't preserve the timezone offset:
let noaaDate = "2014-08-22T15:00:00-04:00"
let format="yyyy-MM-dd'T'HH:mm:ssZ"
var dateFmt = NSDateFormatter()
dateFmt.dateFormat = format
let newreadableDate = dateFmt.dateFromString(noaaDate)
println(newreadableDate)
Output:
Optional(2014-08-22 19:00:00 +0000)
When I add the following:
dateFmt.timeZone = NSTimeZone.localTimeZone() // I've even tried defaultTimeZone
the output is the same. Where this seems to become an issue is later on when I'm doing the following:
// FYI: parseNOAADateTime is that code above
var earliestTimeNS = parseNOAADateTime(earliestTime!)
let calendar = NSCalendar.currentCalendar()
let components = calendar.components(.CalendarUnitDay, fromDate: earliestTimeNS)
let dayZero = components.day
// stuff, like starting a loop
let tempDateTimeString = "2014-08-31T01:00:00-04:00"
let thisDateTime = parseNOAADateTime(tempDateTimeString!)
let tempDateTimeComponents = calendar.components(.CalendarUnitDay, fromDate: thisDateTime)
let forecastIndex = tempDateTimeComponents.day - dayZero
Now, forecastIndex SHOULD be 6 because tempDateTimeComponents.day SHOULD be 31. However, they're 5 and 30, respectively, meaning four hour's worth of data is ending up with the previous day's data.
Where am I messing up?
Thanks

Resources