I've got an array of 'reminders'. Reminder is a custom class that I wrote by myself which has got a property .fireDate.
How could I check if one of the reminders .fireDate properties is the same date as today?
let calendar = Calendar(identifier: Calendar.Identifier.gregorian)
for (idx, date) in dates.enumerated() {
if calendar.isDateInToday(date) {
print("today at index \(idx)!")
}
}
Get the index of the first item whose fireDate is in today. If it's not nil there is at least one item.
let calendar = Calendar.current
if let indexOfFirstReminderWhichFiresToday = reminders.index(where: { calendar.isDateInToday($0.fireDate) }) {
print("\(reminders[indexOfFirstReminderWhichFiresToday]) fires today")
}
This will return the dates in today:
let todayDates = arrayOfDates.filter { Calendar.current.isDateInToday($0) }
Related
Hi everyone I'm trying to get a positive answer when comparing a date earlier than today
To do this I am using a Date extension with this boolean
extension Date {
var isPreviousDate: Bool {
return self.timeIntervalSinceNow.sign == .minus
}
}
Here is my problem .. when I print the date to compare it tells me that today's date is earlier and I don't understand why
Since I'm having problems I tried to create a current date and compare it with today's date the answer is that today's date is earlier than today ... this is weird because it shouldn't tell me it's older
This is how I create the date to compare
var calendar = Calendar(identifier: Calendar.current.identifier)
calendar.timeZone = NSTimeZone(name: "UTC")! as TimeZone
guard let selectedDate = calendar.date(from: DateComponents(year: Date().currentYear, month: Date().currentMonth, day: Date().currentDate)) else { return }
print("isPrevious Date :",selectedDate.isPreviousDate)
print(selectedDate)
am I doing something wrong?
this is what I read in the console when I print the created date to compare
isPrevious Date: true
2021-02-11 00:00:00 +0000
timeIntervalSinceNow is a FloatingPoint value with a very high precision, that represents seconds passed since the Date.
To check if current date is at least on a previous day, you could do something like this:
extension Date {
var isAtLeastPreviousDay: Bool {
return isPast && !isToday
}
private var isPast: Bool {
return self < Date()
}
private var isToday: Bool {
return Calendar.current.isDateInToday(self)
}
}
The issue there is that you are using a custom calendar using UTC timezone. You should use the current calendar with the current timezone. Note that you can use Calendar method startOfDay to get the start of day of a specific date:
extension Date {
var isPreviousDate: Bool {
timeIntervalSinceNow.sign == .minus
}
var startOfDay: Date {
Calendar.current.startOfDay(for: self)
}
}
let now = Date()
let startOfDay = now.startOfDay
print("isPrevious Date:", startOfDay.isPreviousDate) // true
If you would like to check if a date is in yesterday all you need is to use calendar method isDateInYesterday:
extension Date {
var isDateInYesterday: Bool {
Calendar.current.isDateInYesterday(self)
}
}
Date().isDateInYesterday // false
Date(timeIntervalSinceNow: -3600*24).isDateInYesterday // true
I am trying to create dateComponents from Date stored in CoreData from UIDatePicker. However, I am not able to make it. I am first converting Date which is stored in editnotes?.sSelectedDate into dateComponents and then using the dateComponents for triggering my notifications.
Here is what I am doing:
var date = Date()
if let editnote = editnotes
{
date = editnote.sSelectedDate
}
else
{
print("nil")
}
let calendar = NSCalendar.current
let unitFlags = Set<Calendar.Component>([.day, .month, .year, .hour, .minute])
let anchorComponents = calendar.dateComponents(unitFlags, from: date)
var dateInfo1 = DateComponents()
dateInfo1.day = anchorComponents.day
dateInfo1.month = anchorComponents.month
dateInfo1.hour = anchorComponents.hour
dateInfo1.minute = anchorComponents.minute
dateInfo1.year = anchorComponents.year
let trigger = UNCalendarNotificationTrigger(dateMatching:dateInfo1, repeats: false)
I am doing this:
if let editnote = editnotes
{
date = editnote.sSelectedDate
}
else
{
print("nil")
}
to unwrap the optional but it's not working still. Continue reading!
I know I can use anchorComponents but that wasn't working so I copied those into a new DataComponents instance.
I am trying to print the what is stored indateInfo1.hour and I get
Optional(2)
I reckon this is the reason why dateComponents is not working for triggering notifications at scheduled time.
Help will be appreciated?
Explicit cast it like this
let anchorComponents = calendar.dateComponents(unitFlags, from: date) as! DateComponents
You'r using anchorComponents.days / .hours / .days / .minutes it's all optional. Instead, I'd used initialiser for DateComponents where you explicitly set your properties you needed. But I think you'r just doing something wrong and that's why notification not working and the reason is not date. You can simply check it by setting from date to current date plus few seconds to see whether you'll get notification or not
I have two textfields one is containing "From Date" and another one is containing "To date" based on that how to filter array of dates.
you have two date first is starting date and other in ending date and other is date that check in between of start and end date or not..
let format = DateFormatter()
format.dateFormat = "yyyy-MM-dd"// before formate
let date_selected = format.date(from: date)
format.dateFormat = "dd-MM-yyyy"// change related to my format
let seldate_selected = format.string(from: date_selected!)
let dt = format.date(from: seldate_selected)
let str_dat = format.date(from: startDate)
let end_dat = format.date(from: endDate)
if dt! >= str_dat! && dt! <= end_dat!
{
print("selected date is not in between start date and end date ")
}
else
{
print("selected date is not in between start date and end date ")
}
I'm making a kind of challenge based app that requires that the user comes back every day. If he misses one day, he has to start all over again.
My problem is my dateChanged()-function; the first thing is, that it doesn't work very reliable, the second is that I just check if the date changed, I accordingly don't know if there were one or two days between using the app.
Here's my current function:
public func changeDays()
{
myFormatter.dateStyle = .short
myFormatter.locale = Locale(identifier: "de_DE")
oldDate = defaults.string(forKey: "oldDate")!
let newDate = Date()
let newDateString = myFormatter.string(from: newDate)
if newDateString == oldDate
{
NumberOfDaysInARow.text = "\(days) / 30"
}
else if newDateString != oldDate
{
days += 1
NumberOfDaysInARow.text = "\(days) / 30"
defaults.set(days, forKey: "days")
}
oldDate = newDateString
defaults.set(oldDate, forKey: "oldDate")
}
Just today it started giving me a fatal error when starting the app on my iPhone, did not happen in the simulator though... weird.
How do I have to change my function to make it a 100% reliable (and working) while also being able to check the amount of time between the two dates?
Thank you for having a look! Have a great day
You could extend Date with the function below that returns the amount of days from another date.
extension Date {
// Returns the amount of days from another date
func days(from date: Date) -> Int {
return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
}
}
Instead of saving oldDate as a string you can set it to defaults as a date:
defaults.set(Date(), forKey: "oldDate")
You can get the old date from defaults using:
let oldDate = defaults.object(forKey:"oldDate") as! Date
Once you have your old date
let dateNow = Date()
let timeDifference = dateNow.days(from: oldDate!)
If timeDifference > 1 {
// older than 1 day
} else {
// Streak still alive
}
}
If you look in the documentation you will see that Date has a method whose sole purpose is too determine the interval between two dates timeIntervalSince(_:).
If you set the old date to always be 11:59PM on the day it was last used you only have to see if the interval is greater than 24 hours worth of seconds (60 seconds * 60 minutes * 24 hours).
You may want to look at the docs for DateComponents for help creating a date that uses the current date but with a specific time.
I have a dictionary like this:
var dic = [NSDate: Int]()
it is used in my iOS to-do app to get the number of finished tasks of a particular date. I only care about the year, month and day sections in NSDate and also want to be able to get the number of tasks in a particular date using this dictionary, how can I do that? thanks.
Instead of storing your date as NSDate in your dictionary you can save it as String so that comparison will be easier. Use following code to store it as a string
func dateFromString(date : NSDate) -> String {
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
return dateFormatter.stringFromDate(date)
}
You can pass NSDate() to above function and it will give you string containing only year, month and date. For retrieving your data from dictionary use following.
func dateFrom(year:Int, month:Int, day:Int) -> String {
let components = NSDateComponents()
components.year = year
components.month = month
components.day = day
let gregorian = NSCalendar(identifier:NSCalendarIdentifierGregorian)
let date = gregorian!.dateFromComponents(components)
return dateFromString(date!)
}
You can pass year, month and date to above function and it will return corresponding date in string format. So your dictionary operations will look like
dict[dateFromString(NSDate())] = 1 //for insertion or updation
let numOfTasks = dict[dateFrom(2016, month: 1, day: 15)] //to get task for any particular day
EDIT
If you want to proceed with NSDate as key for your dictionary then you'll have to modify above code as follows. dateFrom will return date with year,month and date of your choice, and time will be some constant value. Time will be set to midnight in your current time zone if you don't set it.
func dateFrom(year:Int, month:Int, day:Int) -> NSDate {
let components = NSDateComponents()
components.year = year
components.month = month
components.day = day
let gregorian = NSCalendar(identifier:NSCalendarIdentifierGregorian)
let date = gregorian!.dateFromComponents(components)
return date!
}
And for getting current date use following so that you store date object with current year, date, month and time to some constant value.
func getCurrentDate()->NSDate {
let date = NSDate()
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Day , .Month , .Year], fromDate: date)
return dateFrom(components.year, month: components.month, day: components.day)
}
Usage will be as follows
dict[getCurrentDate()] = i //for insertion or updation
let numOfTasks = dict[dateFrom(2016, month: 1, day: 15)] //to get task for any particular day