This question already has answers here:
How to add a time interval to an NSDate?
(5 answers)
Closed 7 years ago.
How can I convert an NSDate to seconds? I need it in seconds so that I can added 30 secs to the date and then convert back to NSDate to schedule a local notification. Any better ways of doing that are welcome too.
You can use dateByAddingTimeInterval and pass in the value as 30. This will return you an NSDate which will be 30 secs ahead.
NSDate *newDate = [previousDate dateByAddingTimeInterval:30];
Date and Time Programming Guide states that NSDateComponents should be used to perform date calculations.
Quote from the same document:
You should use the provided methods for dealing with calendrical calculations because they take into account corner cases like daylight savings time starting or ending and leap years.
So to add 30 seconds to a date, you should do something like this:
NSDate * date = [NSDate date];
NSCalendar * currentCalendar = [NSCalendar currentCalendar];
NSDateComponents * dateComponents = [NSDateComponents new];
[dateComponents setSecond:30];
NSDate * newDate = [currentCalendar dateByAddingComponents:dateComponents toDate:date options:0];
NSLog(#"%#", newDate);
Related
I am making an app to use at school and I want to make a countdown timer to countdown the amount of time between now and the end of school, which for me is 3:00. For example, at 11:15, it will read 3:45.
So far, I have figured out how to make the countdown timer and I have the following code: countdownTimer.text = [Formatter stringFromDate: [NSDate date]];
This code doesn't actually work yet, but I think it will work if I figure out how to subtract the current time from a set time and then use that value where date is, however I am open to other suggestions on how to approach the problem.
You can use NSCalendar method dateBySettingHour:minute:second: to get the NSDate object associated with 3pm today:
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *now = [NSDate date];
NSDate *schoolOut = [calendar dateBySettingHour:15 minute:0 second:0 ofDate:now options:0];
There are lots of different ways to get the NSDate object associated with 3pm today, but the above is just one example. You could also use components:fromDate of NSCalendar to extract the NSDateComponents of now, then adjust the hour, minute and second and then create a new NSDate object using dateFromComponents (also a NSCalendar method).
Anyway, once you have a NSDate object that represents your target date/time, you can then use NSDateComponentsFormatter to display the time interval between two dates in a nice format.
NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
formatter.allowedUnits = NSCalendarUnitHour | NSCalendarUnitMinute;
formatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull;
formatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorPad;
NSString *string = [formatter stringFromDate:now toDate:schoolOut];
You can adjust the unitsStyle and zeroFormattingBehavior to adjust the format of the string.
This question already has an answer here:
Programmatically getting the date "next Sunday at 5PM"
(1 answer)
Closed 8 years ago.
It's clear how can I calculate the time between two exact date, but I would like to know the date between the actual date and the next monday 2:00 PM.
As an instance, users can reserve places for yoga classes, there is a class that starts on every monday 2:00 PM. So how can I calculate the date of next monday compared to [NSDate date]? I would like to display the remaining time until the next class.
// Date of the next class - how can i get this date?
// NSDate *nextCourse = [NSDate ??];
NSCalendar *deviceCalendar = [NSCalendar autoupdatingCurrentCalendar];
NSDate *date2 = [[NSDate alloc] initWithTimeInterval:nextCourse sinceDate:date1];
unsigned int unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *conversionInfo = [deviceCalendar components:unitFlags fromDate:date1 toDate:date2 options:0];
I can recommend a third party library called DateTools, https://github.com/MatthewYork/DateTools.
Specifically, you can use the: daysUntil:, hoursUntil:, minutesUntil: methods.
For example:
double hoursUntilClass = [date2 hoursUntil];
How can I save a duration in a plist so that I can load up some sample data in Core Data?
By duration I mean a task has a time duration. Could be 1h12m. Could be 15m.
Using this category
+(NSDate *)dateWithHour:(NSInteger)hour minute:(NSInteger)minute
{
NSDateComponents *components = [[NSDateComponents alloc]init];
components.hour = hour;
components.minute = minute;
NSCalendar *calender = [NSCalendar currentCalendar];
NSDate *date = [calender dateFromComponents:components];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"HH:mm"];
NSLog(#"**Date Utils** %#",[dateFormatter stringFromDate:date]);
return date;
}
I can create a duration of 15minutes
task.duration = [NSDate dateWithHour:0 minute:15];
It outputs to the console as:
0001-01-01 04:29:24 +0000
Which doesn't appear to be 15minutes. It looks like 4h29m24s. If I run the date back through a dateFormatter sure enough it prints out 15m.
How can I input a time duration in the plist as shown below?
What am I missing?
Dates are terribly complicated because of time zones and leap years and leap seconds and so on. They're not suitable for this use case and you will have all kinds of bugs trying to use them.
The correct data type for durations is NSTimeInterval, which is a 64 bit floating point number, in seconds. NSDate uses this data type internally as well.
The easiest way to create a time interval is:
NSDate *aDate = ...
NSDate *anotherDate = ...
NSTimeInterval duration = [aDate timeIntervalSinceDate:anotherDate];
And you'd save it to a plist with NSNumber:
NSNumber *durationNumber = [NSNumber numberWithDouble:duration];
Note that NSTimeInterval is actually a double.
I am trying to implement some pseudo code I have for the date picker. However I am unsure of how to add a minute value to adjust an NSDate object.
Here is the pseudo code:
//minTime is an NSDate object
minTime = currentTime + 30mins - (currentTime % 15)
(currentTime % 15) means that the user can only select in 15mins intervals, and must be 15mins from the current 15min interval. For example, if its 10:50, the user should only be able to select 11:15 from the UIDatePicker. If is 10:20, the user should only be able to select 10:45.
I know how to get the currentTime using [NSDate date] but I do not know how to add mins to it and adjust it.
It is not considered good practice to work with time intervals when working with dates and times. The best solution is to use NSDateComponents to add time periods.
NSDateComponents* dc = [NSDateComponents new];
dc.minutes = 15;
NSDate* newDate = [[NSCalendar currentCalendar] dateByAddingComponents:dc toDate:oldDate options:0];
You can add some minutes to a NSDate using :
NSDate *nowDate = [NSDate date];
NSDate *nowDateAnd2moreMinutes = [nowDate dateByAddingTimeInterval:2*60]; //This add 2 minutes (2 * 60sec)
More information in apple documentation.
Edit I wrote a little function that add minutes :
+(NSDate) addMinutes:(int) minutes toDate:(NSDate) date{
return [date dateByAddingTimeInterval:minutes*60];
}
Bonus : Function that add minutes and seconds to a date
+(NSDate) addMinutes:(int) minutes andSeconds:(int) sec toDate:(NSDate) date{
return [date dateByAddingTimeInterval:(minutes*60)+sec];
}
I'm trying to write an application that will send the user an alert in the Notification Center 60 hours before the date arrives. Here is the code:
localNotif.fireDate = [eventDate dateByAddingTimeInterval:-60*60*60];
I was wondering if the -60*60*60 formula will work to alert them 60 hours prior to the date? I'm not sure at all how the formula works, I would like to set it up to alert 10 minutes before the date for testing purposes, then change it back to 60 hours once I confirm that everything is correct. Does any one know the formula to use for both of these?
Any help is much appreciated, thank you!
A crude but easy-to-code way is to add/subtract seconds from an NSDate directly:
NSDate *hourLaterDate = [date dateByAddingTimeInterval: 60*60];
NSDate *hourEarlierDate = [date dateByAddingTimeInterval: -60*60];
You can see how it works by logging the dates:
NSDate *now = [NSDate date];
NSDate *hourLaterDate = [now dateByAddingTimeInterval: 60*60];
NSLog(#"%# => %#", now, hourLaterDate);
In this approach a date is interpreted as a number of seconds since the reference date. So, internally it's just a big number of type double.
A tedious-to-code but pedantically correct way to do these calculations is by interpreting dates as dates expressed in a calendar system. The same thing achieved as calendrical calculations:
NSDateComponents *hour = [[NSDateComponents alloc] init];
[hour setHour: 1];
NSCalendar *calendar= [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDate *hourLaterDate = [calendar dateByAddingComponents: hour
toDate: date
options: 0];
[hour release];
[calendar release];
These calculations take into account time zones, daylight saving time, leap years, etc. They can also be more expressive in terms of what you're calculating.
Before using any of these approaches you have to decide what exactly you need: a timestamp or a full-blown calendar date.