Is it possible to have an action from a button a) do an NSDate store when tapped, and then b) for that method to do a date comparison with an if statement?
So, for instance, if the stored NSDate was less than 12 hours ago, the user could not press the button again?
Haven't come across a tip on this from my research.
Sure. You can get current date by code
[NSDate date]
Then save him into NSUserDefaults
And check a current date with saved date on button press.
How
if ( [[NSDate date] timeIntervalSinceDate: savedDate] >= 12*60*60) // 12 hours
{
// do your steps
}
Related
I have 2 UIDatePickers, one set in UIDatePickerModeDate and the other in UIDatePickerModeTime.
If the first one has its date set to today, then the second one must have a restriction such that the user cannot select a time that is before now. To do this I use the setMinimumDate function. However, if the user sets a date in the future, I need to reset the minimumDate property, meaning that there should be no minimumDate set on the picker.
I am able to achieve this by calling
[self.timePicker setMinimumDate:nil];
But this gives me an exception in the Xcode console output as below.
-[__NSCFCalendar components:fromDate:]: date cannot be nil
Future exception.
A few of these errors are going to be reported with this complaint, then further violations will simply be ignored.
How can I remove the minimumDate property of my timePicker after it has been set, without this exception being raised?
Thank you.
EDIT:
The reason I tried setting it to nil was because Apple's documentation says that the default value of the minimumDate property is nil (here).
Also, I did try to set the minimum date to the future date selected by the user, after making the time component zero. This causes the time to be selected as 12 AM in the picker which is acceptable. Now if the user selects today's date again, nothing happens when I set the minimumDate property, i.e. I cannot toggle the minimumDate using this. The code is as follows:
(void)setMinimumDateForTimePicker {
if([[NSCalendar currentCalendar] isDateInToday:self.datePicker.date]) {
NSLog(#"Min date for today");
[self.timePicker setMinimumDate:[self roundUpToNearestFifteenMinutes:[NSDate date]]];
} else {
// date is in the future so zero out time
NSLog(#"Min date for the future");
NSDateComponents* selectedDateWithZeroTime = [[NSCalendar currentCalendar] components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:self.datePicker.date];
[self.timePicker setMinimumDate:[[NSCalendar currentCalendar] dateFromComponents:selectedDateWithZeroTime]];
}
[self updateStartTimeField:nil];
}
This is the code that worked finally for what I was trying to do.
- (void)setMinimumDateForTimePicker {
if([[NSCalendar currentCalendar] isDateInToday:self.datePicker.date]) {
[self.timePicker setMinimumDate:[self roundUpToNearestFifteenMinutes:[NSDate date]]];
} else {
[self.timePicker setMinimumDate:[[NSCalendar currentCalendar] startOfDayForDate:[NSDate date]]];
}
[self updateStartTimeField:nil];
}
In iOS, Xcode9, and Obj-C, I am trying to find out how much time has elapsed in days between two dates. I know the NSTimeIntervalSince method yields a result in seconds. But it seems that when I calculate the seconds between consecutive days (like 11-2-2016 and 11-3-2016), I am 1 second short, yielding 86,399. If I calculate seconds between larger intervals, I am always a second short.
11-2-2016 to 11-4-2016: 172,799 (two 24-hour days but missing a second)
11-2-2016 to 11-5-2016: 259,199 (three 24-hour days but missing a second)
Here's my code:
#property (strong, nonatomic) NSDate *firstDate;
#property (strong, nonatomic) NSDate *secondDate;
#synthesize firstDate, secondDate;
int secondsIntervalFirstDatetoSecondDate = (fabs([firstDate timeIntervalSinceDate:secondDate]));
NSLog(#"seconds between firstDate and secondDate %i", secondsIntervalFirstDatetoSecondDate);
firstDate and secodDate are NSDate
They are entered by the user using a datePicker and date formatting is set as
[formatter setDateFormat:#"MM-dd-yyyy"];
I've searched for an answer but could find none.
First post for a newbie, sorry for any etiquette errors, I'll try to improve.
When you create a UIDatePicker and put it in "date" mode, the time is the time the date picker was created. If you're creating two pickers, they're going to be created at slightly different times. Even a very small difference in those times can lead to a 1-second difference.
You should never compute time-differences this way. There are not 86,400 seconds in a day. "How many days are between two points in time" is complicated, and you should use the tools designed for it: NSDateComponents and NSCalendar.
NSCalendar *calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
NSInteger diffInDays = [[calendar components:NSCalendarUnitDay
fromDate:[calendar startOfDayForDate:date1]
toDate:[calendar startOfDayForDate:date2]
options:0] day];
I'm trying to figure out how I can make an alert popup once the user has reached their goal. However, I only want it to show once a day after it's been triggered. Apologies in advance. if my logic is off with tackling this issue.
// Check to see if hydration goal has been reached
if (waterCups >= dailyHydrationGoal) {
// User has reached goal
if (alert has not been fired yet today) {
// alert pop up you reached your goal!
}
}
How would I go about ensuring it only launches once per day?
You can use isDateInToday: method to check whether the given date is in “today.”
NSDate *lastAlertDate = (NSDate *)[[NSUserDefaults standardUserDefaults] objectForKey:#"lastAlertDate"];
if(![[NSCalendar currentCalendar] isDateInToday:lastAlertDate]){
//Show alert
NSDate *today= [NSDate date];
[[NSUserDefaults standardUserDefaults] setObject:today forKey:#"lastAlertDate"];
}
Do you have a persistence store? (NSUserDefaults, core data etc...)
You can store a time stamp (NSDate) of the last time an alert was shown then check if the last time it was shown is today. How to determine if an NSDate is today?
If an alert has not been shown today, pop an alert and record a new time stamp.
I have being wondering these days how can I subtract 3, 10 and 20 minutes from selected time from time picker in Swift 3. So for example when the user selects the start time of an event, to be able to receive notification 3, 10 or 20 minutes before the selected from the picker time value. I have tried
let value:TimeInterval = 1187.5
let periodComponents = startTimePicker.date.addingTimeInterval(-value)
for the 20 minutes earlier,
but I'm getting the value 2 hours behind(may be the console is showing me the GTM time only). Is it possible to schedule notification from "periodComponens" to repeat every week on the selected time on specific day of the week? Or I should use other subtracting method?
Use the built-in Calendar class:
let threeMinutesEarlier = Calendar.current.date(byAdding: .minute, value: -3, to: myPicker.date)
There is nothing wrong with your code.
The xcode console just prints out GMT date time by default. If you use NSDateFormatter to convert your NSDate into NSString and print it out, the result will be as you expected
If you use UILocalNotification and wish to schedule it to fire weekly you can set its provided property repeatInterval to NSCalendarUnitWeekOfYear.
For example:
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
NSDate *fireTime; // Your desired date time.
localNotif.fireDate = fireTime;
localNotif.repeatInterval = NSCalendarUnitWeekOfYear;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
I'm struggling to understand how to use NSDates properly.
I have an event that instantiates a timingDate = [NSDate date];
I then later on what to record the time intervals betweeen user's touches.
So I want to find the interval between the timingDate and the user touch in milliseconds.
Then I want to reset the timingDate to be equal to the touchTime so that the next time the screen is touched I can find the differnce between the previous touch and the present touch. I hope that makes sense. But I am going around in circles because I don't understand how to use NSDates or NSIntervals. The properties interval touchTime and timingDate are all currently NSDate types - Is this right?
So I've tried a lot of different things like
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
touchTime = timingDate;
interval = [[NSDate date] timeIntervalSinceDate:timingDate]; // should be the time difference from when the timingDate was first set and when the user touched the screen.
touchTime = [[[NSDate date]timeIntervalSinceDate:timingDate]doubleValue];
timingDate = [NSDate dateWithTimeIntervalSinceReferenceDate:touchTime];
NSLog(#"Time taken Later: %f", [[NSDate date]timeIntervalSinceDate:timingDate]);
}
Your code is a bit complex! You just need to calculate the difference between timingDate and the time that the touch occurred, and then set timingDate to the current time so that you can perform this calculation on every touch event.
To find the difference between timingDate and the first touch, you can use NSDate's timeIntervalSinceDate with the current time. This will return an NSTimeInterval value, which represents a time value in seconds with sub-millisecond precision. Here's an example:
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:timingDate];
NSLog(#"Time taken: %f seconds / %f milliseconds",timeInterval,timeInterval*1000);
Then, in order to set your timingDate to the current time, simply use timingDate = currentDate;. This will allow you to continuously measure the time difference between touches.
NSTimeInterval is a double which represents seconds.
NSDate is an object that holds the date/time.
Here is an example:
#property(nonatomic, strong) NSDate * lastTouchDate;
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSTimeInterval secondsSinceLastTouch = 0;
if(self.lastTouchDate){
secondsSinceLastTouch = [[NSDate date] timeIntervalSinceDate:self.lastTouchDate];
NSLog(#"It's been %.1f seconds since the user touched the screen", secondsSinceLastTouch);
}else{
NSLog(#"This is the first time the user touched the screen");
}
self.lastTouchDate = [NSDate date];
}
If you don't want the interval between the last time you touched it, do not update the self.lastTouchDate after initialization and it will be seconds since the date was initialized.
So, the first thing that you need to understand is that -[NSDate timeIntervalSinceDate:] returns an NSTimeInterval, which is really just a double value.
In your example above, you haven't declared your variables with types, but if you look at the value your variable interval it should be a decimal value of seconds since the time represented by timingDate.
Assuming that timingDate is an NSDate object, and it is set before this code is run, this code should print the time (seconds) to the debug console.
NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:timingDate];
NSLog(#"Time between touches %f", interval);
Here is the NSDate class documentation, in case you were having trouble finding it.
( https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/index.html#//apple_ref/doc/c_ref/NSDate )