The initial objective is to calculate the difference between two NSDates using NSDateComponents. Furthermore, once the days, hours, minutes, and seconds have been obtained and verified as correct. Display a real-time ticker (counter) with the difference (to the nearest minute, hour, or day) within a UITableViewCell.
Current progress can be found below.
Any suggestions, or direction in accomplishing this will be greatly appreciated!
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier =#"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = [(AGSGraphic *)[_radios objectAtIndex:indexPath.row] attributeForKey:#"parent_id"];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"YYYY-MM-dd hh:mm:ss"];
NSNumber *timestamp = [[_radios objectAtIndex:indexPath.row] valueForKey:#"date_time_edt"];
NSDate *today = [NSDate date];
NSDate *crewDate = [NSDate dateWithTimeIntervalSince1970:[timestamp doubleValue]/1000];
NSString *temp = [df stringFromDate:today];
NSString *crewtemp = [df stringFromDate:crewDate];
crewDate = [df dateFromString:crewtemp];
today = [df dateFromString:temp];
NSLog(#"%#", crewDate);
NSLog(#"%#", today);
NSTimeInterval interval = [crewDate timeIntervalSinceDate:today];
interval = -interval;
NSInteger minutes = interval/60;
NSInteger hours = minutes/60;
NSInteger days = hours/24;
// NSInteger weeks = days/7;
// NSInteger months = weeks/4;
// NSInteger years = months/12;
// NSTimeInterval years = interval/31536000;
// NSTimeInterval months = years/12;
// NSTimeInterval weeks = years/52;
// NSTimeInterval days = years/365;
// NSTimeInterval hours = days/24;
// NSTimeInterval minutes = hours/60;
// NSLog(#"%f", interval);
if(minutes < 60)
{
cell.detailTextLabel.text = [NSString stringWithFormat:#"%ld minuntes ago", (long)minutes];
}
else if(hours < 24)
{
cell.detailTextLabel.text = [NSString stringWithFormat:#"%ld hours ago", (long)hours];
}
else
{
cell.detailTextLabel.text = [NSString stringWithFormat:#"%ld days ago", (long)days];
}
return cell;
}
here's how you do it with Minutes:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSHLessonCell *cell = [tableView dequeueReusableCellWithIdentifier:NSHLessonCellIdentifier forIndexPath:indexPath];
NSDate *fromDate;
NSDate *toDate;
NSCalendar *calendar = [NSCalendar currentCalendar];
[calendar rangeOfUnit:NSCalendarUnitMinute startDate:&fromDate interval:NULL forDate:[self.ninjas[indexPath.row] started]];
[calendar rangeOfUnit:NSCalendarUnitMinute startDate:&toDate interval:NULL forDate:[self.ninjas[indexPath.row] finished]];
NSDateComponents *difference = [calendar components:NSCalendarUnitMinute fromDate:fromDate toDate:toDate options:0];
[cell setTotalDuration:[difference minute]];
}
Also, I would only assume that using the method for minutes that I use, you can also use other methods for calculating difference for different units of date measurements by swapping out NSCalendarUnitMinute with options provided in NSCalendar.h, see below:
typedef NS_OPTIONS(NSUInteger, NSCalendarUnit) {
NSCalendarUnitEra = kCFCalendarUnitEra,
NSCalendarUnitYear = kCFCalendarUnitYear,
NSCalendarUnitMonth = kCFCalendarUnitMonth,
NSCalendarUnitDay = kCFCalendarUnitDay,
NSCalendarUnitHour = kCFCalendarUnitHour,
NSCalendarUnitMinute = kCFCalendarUnitMinute,
NSCalendarUnitSecond = kCFCalendarUnitSecond,
NSCalendarUnitWeekday = kCFCalendarUnitWeekday,
NSCalendarUnitWeekdayOrdinal = kCFCalendarUnitWeekdayOrdinal,
NSCalendarUnitQuarter NS_ENUM_AVAILABLE(10_6, 4_0) = kCFCalendarUnitQuarter,
NSCalendarUnitWeekOfMonth NS_ENUM_AVAILABLE(10_7, 5_0) = kCFCalendarUnitWeekOfMonth,
NSCalendarUnitWeekOfYear NS_ENUM_AVAILABLE(10_7, 5_0) = kCFCalendarUnitWeekOfYear,
NSCalendarUnitYearForWeekOfYear NS_ENUM_AVAILABLE(10_7, 5_0) = kCFCalendarUnitYearForWeekOfYear,
NSCalendarUnitNanosecond NS_ENUM_AVAILABLE(10_7, 5_0) = (1 << 15),
NSCalendarUnitCalendar NS_ENUM_AVAILABLE(10_7, 4_0) = (1 << 20),
NSCalendarUnitTimeZone NS_ENUM_AVAILABLE(10_7, 4_0) = (1 << 21),
Related
- (void)viewDidLoad {
[super viewDidLoad];
tableData = [[NSArray alloc]initWithObjects:#"2018-05-16 06:00:00 p",#"2018-05-16 09:00:00 p",#"2018-05-16 11:00:00 p",#"2018-05-17 02:00:00 a",#"2018-05-17 04:00:00 a",nil];
currDate = [NSDate date];
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss a"];
NSLog(#"the current date and time is %#",currDate);
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"YYYY-MM-dd hh:mm:ss a"];
NSString *fxdDate = #"2018-05-16 07:00:00 a";
NSDate *StartDate = [ dateFormat dateFromString:[ NSString stringWithFormat:#"%#", fxdDate]];
for(int i=0;i<tableData.count;i++)
{
EndDate = [dateFormat dateFromString:tableData[i]];
NSDateComponents *components, *components2;
NSInteger hours, minutesfromStart, minuteFromEnd,secondsFromEnd;
components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: currDate toDate: StartDate options: 0];
hours = [components hour];
minutesfromStart = [ components minute];
components2 = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: currDate toDate: EndDate options: 0];
minuteFromEnd = [ components2 minute];
secondsFromEnd = [ components2 second];
NSDateComponents *components1;
NSInteger hours1, minutes1, Seconds1;
components1 = [[NSCalendar currentCalendar] components:
NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate: currDate toDate: EndDate options: 0];
hours1 = [components1 hour];
minutes1 = [ components1 minute];
Seconds1 = [ components1 second];
currMinute = minutes1;
currHours = hours1;
currSeconds =Seconds1;
NSLog(#"Time left is %ld:%ld:%ld", (long)hours1, (long)minutes1,(long)Seconds1);
timer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timerFired) userInfo:nil repeats:YES];
}
-(void)timerFired
{
if(( currHours>=0 || currMinute >=0 || currSeconds>=0) && currSeconds>=0)
{
if(currSeconds==0 && currMinute>0)
{
currMinute-=1;
currSeconds=59;
}
else if(currMinute==0 && currHours>0)
{
currHours-=1;
currMinute=59;
}
else if(currSeconds>=0)
{
currSeconds-=1;
}
if(currSeconds>-1)
[tableview reloadData];
}
else
{
[timer invalidate];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"Reuse";
SimpleTableViewCell *cell = (SimpleTableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
NSArray *nib =[[NSBundle mainBundle]loadNibNamed:#"SimpleTableViewCell" owner:self options:nil];
cell=[nib objectAtIndex:0];
}
if(indexPath.row == 0)
{
cell.dynamicTimerLabel.text =[NSString stringWithFormat:#"%02ld:%02ld:%02ld",currHours,currMinute, currSeconds];
}
if(indexPath.row == 1)
{
cell.dynamicTimerLabel.text =[NSString stringWithFormat:#"%02ld:%02ld:%02ld",currHours,currMinute, currSeconds];
}
if(indexPath.row == 2)
{
cell.dynamicTimerLabel.text =[NSString stringWithFormat:#" %02ld:%02ld:%02ld",currHours,currMinute, currSeconds];
}
if(indexPath.row == 3)
{
cell.dynamicTimerLabel.text =[NSString stringWithFormat:#" %02ld:%02ld:%02ld",currHours,currMinute, currSeconds];
}
if(indexPath.row == 4)
{
cell.dynamicTimerLabel.text =[NSString stringWithFormat:#" %02ld:%02ld:%02ld",currHours,currMinute, currSeconds];
}
cell.TimerLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
In the above code, it is creating a countdown timer on the UITableView cells but it is only taking the last element of the array for the timer and decrementing the same for each cell but I want it to take each element of the array for each cell. Please HELP. The timer function is getting fired only once.
1) Have your timer fire once per second, which it already does, except all it needs to call is reloadData. 2) Do your time calculations in cellForRowAtIndexPath, and based on the indexPath.row, compute the interval between the destination time for that row, and the current time, then display that interval in hours: minutes: seconds. Currently, your timer is firing, computing one interval, and all the cells are using that interval for their information.
You need to schedule a method to repeatedly trigger after 1 second. And place a currentIndex object at global level and increment it whenever timer method executed.
#interface YourCellClass(){
NSInteger currentTimerIndex;
NSTimer *timer;
NSArray *arrayOfTimes;
BOOL isTimerCompleted;
}
#property (strong, nonatomic) NSString *dateString;
#end
#implementation YourCellClass
-(void)layoutSubviews {
[super layoutSubviews];
//This line will call startTimer function after every 1 second.
if (!isTimerCompleted && timer == nil) {
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(startTimer) userInfo:nil repeats:YES];
}
}
-(void)startTimer {
// dateString should be assign from you cellForRowAtIndexPath method like this
//cell.dateString = [dateArray objectAtIndexPath:indexPath];
//Suppose you have pass 16/5/2018 9:12:45 as dateString
//So below i am checking how much is the difference between providedDate and currentDate with respect to (hours, minuts and seconds)
// if all get zero it means both dates have become equal so i am disabling the timer.
// In real scenario its like your order delivery has been set to 9:12:45 and its 8:59:45 now so you have
// 0 hours 13 minuts and 0 seconds
// In the very next second your timer have
// 0 hours 12 minutes and 59 seconds and so on.
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"YYYY-MM-dd hh:mm:ss a"];
NSString *fxdDate = #"2018-05-16 07:00:00 a";
NSDate *date = [ dateFormat dateFromString:self.dateString];
NSDateComponents *components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: NSDate.date toDate: date options: 0];
if (components.hour == 0 && components.minute == 0 && components.second == 0) {
[timer invalidate];
isTimerCompleted = YES;
}else {
NSString *newTimeString = [NSString stringWithFormat:#"%ld : %ld : %ld",components.hour,components.minute,components.second];
//
}
}
if(indexPath.row == 0)
{
currDate = [NSDate date];
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss a"];
NSLog(#"the current date and time is %#",currDate);
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"YYYY-MM-dd hh:mm:ss a"];
NSString *fxdDate = #"2018-05-16 07:00:00 a";
NSDate *StartDate = [ dateFormat dateFromString:[ NSString stringWithFormat:#"%#", fxdDate]];
NSString *dynDate = #"2018-05-17 08:00:00 p";
EndDate = [dateFormat dateFromString:dynDate];
NSDateComponents *components, *components2;
NSInteger hours, minutesfromStart, minuteFromEnd,secondsFromEnd;
components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: currDate toDate: StartDate options: 0];
hours = [components hour];
minutesfromStart = [ components minute];
components2 = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: currDate toDate: EndDate options: 0];
minuteFromEnd = [ components2 minute];
secondsFromEnd = [ components2 second];
NSDateComponents *components1;
NSInteger hours1, minutes1, Seconds1;
components1 = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate: currDate toDate: EndDate options: 0];
hours1 = [components1 hour];
minutes1 = [ components1 minute];
Seconds1 = [ components1 second];
currMinute = minutes1;
currHours = hours1;
currSeconds =Seconds1;
NSLog(#"Time left is %ld:%ld:%ld", (long)hours1, (long)minutes1,(long)Seconds1);
timer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timerFired) userInfo:nil repeats:YES];
cell.dynamicTimerLabel.text =[NSString stringWithFormat:#"%02ld:%02ld:%02ld",currHours,currMinute, currSeconds];
}
if(indexPath.row == 1)
{
currDate = [NSDate date];
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss a"];
NSLog(#"the current date and time is %#",currDate);
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"YYYY-MM-dd hh:mm:ss a"];
NSString *fxdDate = #"2018-05-16 07:00:00 a";
NSDate *StartDate = [ dateFormat dateFromString:[ NSString stringWithFormat:#"%#", fxdDate]];
NSString *dynDate = #"2018-05-17 09:00:00 p";
EndDate = [dateFormat dateFromString:dynDate];
NSDateComponents *components, *components2;
NSInteger hours, minutesfromStart, minuteFromEnd,secondsFromEnd;
components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: currDate toDate: StartDate options: 0];
hours = [components hour];
minutesfromStart = [ components minute];
components2 = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: currDate toDate: EndDate options: 0];
minuteFromEnd = [ components2 minute];
secondsFromEnd = [ components2 second];
NSDateComponents *components1;
NSInteger hours1, minutes1, Seconds1;
components1 = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate: currDate toDate: EndDate options: 0];
hours1 = [components1 hour];
minutes1 = [ components1 minute];
Seconds1 = [ components1 second];
currMinute = minutes1;
currHours = hours1;
currSeconds =Seconds1;
NSLog(#"Time left is %ld:%ld:%ld", (long)hours1, (long)minutes1,(long)Seconds1);
timer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timerFired) userInfo:nil repeats:YES];
cell.dynamicTimerLabel.text =[NSString stringWithFormat:#"%02ld:%02ld:%02ld",currHours,currMinute, currSeconds];
}
if(indexPath.row == 2)
{
currDate = [NSDate date];
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss a"];
NSLog(#"the current date and time is %#",currDate);
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"YYYY-MM-dd hh:mm:ss a"];
NSString *fxdDate = #"2018-05-16 07:00:00 a";
NSDate *StartDate = [ dateFormat dateFromString:[ NSString stringWithFormat:#"%#", fxdDate]];
NSString *dynDate = #"2018-05-17 11:00:00 p";
EndDate = [dateFormat dateFromString:dynDate];
NSDateComponents *components, *components2;
NSInteger hours, minutesfromStart, minuteFromEnd,secondsFromEnd;
components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: currDate toDate: StartDate options: 0];
hours = [components hour];
minutesfromStart = [ components minute];
components2 = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: currDate toDate: EndDate options: 0];
minuteFromEnd = [ components2 minute];
secondsFromEnd = [ components2 second];
NSDateComponents *components1;
NSInteger hours1, minutes1, Seconds1;
components1 = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate: currDate toDate: EndDate options: 0];
hours1 = [components1 hour];
minutes1 = [ components1 minute];
Seconds1 = [ components1 second];
currMinute = minutes1;
currHours = hours1;
currSeconds =Seconds1;
NSLog(#"Time left is %ld:%ld:%ld", (long)hours1, (long)minutes1,(long)Seconds1);
timer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timerFired) userInfo:nil repeats:YES];
cell.dynamicTimerLabel.text =[NSString stringWithFormat:#"%02ld:%02ld:%02ld",currHours,currMinute, currSeconds];
}
if(indexPath.row == 3)
{
currDate = [NSDate date];
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss a"];
NSLog(#"the current date and time is %#",currDate);
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"YYYY-MM-dd hh:mm:ss a"];
NSString *fxdDate = #"2018-05-16 07:00:00 a";
NSDate *StartDate = [ dateFormat dateFromString:[ NSString stringWithFormat:#"%#", fxdDate]];
NSString *dynDate = #"2018-05-18 02:00:00 a";
EndDate = [dateFormat dateFromString:dynDate];
NSDateComponents *components, *components2;
NSInteger hours, minutesfromStart, minuteFromEnd,secondsFromEnd;
components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: currDate toDate: StartDate options: 0];
hours = [components hour];
minutesfromStart = [ components minute];
components2 = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: currDate toDate: EndDate options: 0];
minuteFromEnd = [ components2 minute];
secondsFromEnd = [ components2 second];
NSDateComponents *components1;
NSInteger hours1, minutes1, Seconds1;
components1 = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate: currDate toDate: EndDate options: 0];
hours1 = [components1 hour];
minutes1 = [ components1 minute];
Seconds1 = [ components1 second];
currMinute = minutes1;
currHours = hours1;
currSeconds =Seconds1;
NSLog(#"Time left is %ld:%ld:%ld", (long)hours1, (long)minutes1,(long)Seconds1);
timer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timerFired) userInfo:nil repeats:YES];
cell.dynamicTimerLabel.text =[NSString stringWithFormat:#"%02ld:%02ld:%02ld",currHours,currMinute, currSeconds];
}
if(indexPath.row == 4)
{
currDate = [NSDate date];
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss a"];
NSLog(#"the current date and time is %#",currDate);
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"YYYY-MM-dd hh:mm:ss a"];
NSString *fxdDate = #"2018-05-16 07:00:00 a";
NSDate *StartDate = [ dateFormat dateFromString:[ NSString stringWithFormat:#"%#", fxdDate]];
NSString *dynDate = #"2018-05-18 4:00:00 a";
EndDate = [dateFormat dateFromString:dynDate];
NSDateComponents *components, *components2;
NSInteger hours, minutesfromStart, minuteFromEnd,secondsFromEnd;
components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: currDate toDate: StartDate options: 0];
hours = [components hour];
minutesfromStart = [ components minute];
components2 = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: currDate toDate: EndDate options: 0];
minuteFromEnd = [ components2 minute];
secondsFromEnd = [ components2 second];
NSDateComponents *components1;
NSInteger hours1, minutes1, Seconds1;
components1 = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate: currDate toDate: EndDate options: 0];
hours1 = [components1 hour];
minutes1 = [ components1 minute];
Seconds1 = [ components1 second];
currMinute = minutes1;
currHours = hours1;
currSeconds =Seconds1;
NSLog(#"Time left is %ld:%ld:%ld", (long)hours1, (long)minutes1,(long)Seconds1);
timer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timerFired) userInfo:nil repeats:YES];
cell.dynamicTimerLabel.text =[NSString stringWithFormat:#"%02ld:%02ld:%02ld",currHours,currMinute, currSeconds];
}
-(void)timerFired
{
if(( currHours>=0 || currMinute >=0 || currSeconds>=0) && currSeconds>=0)
{
if(currSeconds==0 && currMinute>0)
{
currMinute-=1;
currSeconds=59;
}
else if(currMinute==0 && currHours>0)
{
currHours-=1;
currMinute=59;
}
else if(currSeconds>=0)
{
currSeconds-=1;
}
if(currSeconds>-1)
time=[NSString stringWithFormat:#"%02ld:%02ld:%02ld",currHours,currMinute, currSeconds];
[tableview reloadData];
}
else
{
[timer invalidate];
}
}
It worked for me
I am trying to detect is a specific date is within the last 7 days (within the last week).
I have found a method to do that, but its eating my performance in a tableview (chat controller).
The code is posted below, and i know it can be done a LOT better, but i am running out of ideas. Does somebody have better approach? thanks!
The code:
NSDate *date = [[_messages objectAtIndex:indexPath.row] date];
NSString *lastMessageDateString = [[[NVDate alloc] initUsingDate:date] stringValueWithFormat:#"dd/MM/yy"];
NSString *todayDateString = [[[NVDate alloc] initUsingToday] stringValueWithFormat:#"dd/MM/yy"];
NSString *yesterdayDateString = [[[[NVDate alloc] initUsingToday] previousDay] stringValueWithFormat:#"dd/MM/yy"];
NSString *earlier2DaysDateString = [[[[NVDate alloc] initUsingToday] previousDays:2] stringValueWithFormat:#"dd/MM/yy"];
NSString *earlier3DaysDateString = [[[[NVDate alloc] initUsingToday] previousDays:3] stringValueWithFormat:#"dd/MM/yy"];
NSString *earlier4DaysDateString = [[[[NVDate alloc] initUsingToday] previousDays:4] stringValueWithFormat:#"dd/MM/yy"];
NSString *earlier5DaysDateString = [[[[NVDate alloc] initUsingToday] previousDays:5] stringValueWithFormat:#"dd/MM/yy"];
NSString *earlier6DaysDateString = [[[[NVDate alloc] initUsingToday] previousDays:6] stringValueWithFormat:#"dd/MM/yy"];
NSString *earlier7DaysDateString = [[[[NVDate alloc] initUsingToday] previousDays:7] stringValueWithFormat:#"dd/MM/yy"];
//return the time of the message since it is today
if ([lastMessageDateString isEqualToString:todayDateString]) {
return [SAD.myE.timeFormat stringFromDate:date];
}
//return the string "yesterday" of the message since it is yesterday
else if ([lastMessageDateString isEqualToString:yesterdayDateString]) {
return #"Yesterday";
}
//return the string of the actual day of the message since it is within last 7 days
else if ([lastMessageDateString isEqualToString:earlier2DaysDateString] ||
[lastMessageDateString isEqualToString:earlier3DaysDateString] ||
[lastMessageDateString isEqualToString:earlier4DaysDateString] ||
[lastMessageDateString isEqualToString:earlier5DaysDateString] ||
[lastMessageDateString isEqualToString:earlier6DaysDateString] ||
[lastMessageDateString isEqualToString:earlier7DaysDateString]) {
return [SAD.myE.dayFormat stringFromDate:date];
}
//return the string date since the message is olf
else {
return [SAD.myE.dateFormat stringFromDate:date];
}
EDIT
Thanks to #vikingosegundo i have tried to use his solution to implement this solution. He since then made a category that made it even easier that i will try and implement now. Just for the curious ones:
- (NSString *)stringForDate:(NSDate *)date {
NSDate *now = [NSDate date]; // now
NSDate *today;
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit // beginning of this day
startDate:&today // save it here
interval:NULL
forDate:now];
NSDateComponents *comp = [[NSDateComponents alloc] init];
comp.day = 0;
NSDate * theDayToday = [[NSCalendar currentCalendar] dateByAddingComponents:comp toDate:today options:0];
if ([date compare:theDayToday] == NSOrderedDescending) {
return #"today";
}
comp.day = -1;
NSDate * yesterday = [[NSCalendar currentCalendar] dateByAddingComponents:comp toDate:today options:0];
if ([date compare:yesterday] == NSOrderedDescending) {
return #"yesterday";
}
comp.day = -7; // lets go 7 days back from today
NSDate * oneWeekBefore = [[NSCalendar currentCalendar] dateByAddingComponents:comp toDate:today options:0];
if ([date compare:oneWeekBefore] == NSOrderedDescending) {
return #"within 7 days";
} else {
return #"before 7 days";
}
}
-(BOOL) dayOccuredDuringLast7Days
{
NSDate *now = [NSDate date]; // now
NSDate *today;
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit // beginning of this day
startDate:&today // save it here
interval:NULL
forDate:now];
NSDateComponents *comp = [[NSDateComponents alloc] init];
comp.day = -7; // lets go 7 days back from today
NSDate * oneWeekBefore = [[NSCalendar currentCalendar] dateByAddingComponents:comp
toDate:today
options:0];
if ([self compare: oneWeekBefore] == NSOrderedDescending) {
if ( [self compare:today] == NSOrderedAscending ) { // or now?
return YES;
}
}
return NO;
}
a complete command line example for last 7 days and yesterday. as category on NSDate
#import <Foundation/Foundation.h>
#interface NSDate (ExtendedComparions)
-(BOOL) dayOccuredDuringLast7Days;
-(BOOL) dayWasYesterday;
#end
#implementation NSDate (ExtendedComparions)
-(BOOL) _occuredDaysBeforeToday:(NSUInteger) nDaysBefore
{
NSDate *now = [NSDate date]; // now
NSDate *today;
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit // beginning of this day
startDate:&today // save it here
interval:NULL
forDate:now];
NSDateComponents *comp = [[NSDateComponents alloc] init];
comp.day = -nDaysBefore; // lets go N days back from today
NSDate * before = [[NSCalendar currentCalendar] dateByAddingComponents:comp
toDate:today
options:0];
if ([self compare: before] == NSOrderedDescending) {
if ( [self compare:today] == NSOrderedAscending ) {
return YES;
}
}
return NO;
}
-(BOOL) dayOccuredDuringLast7Days
{
return [self _occuredDaysBeforeToday:7];
}
-(BOOL) dayWasYesterday
{
return [self _occuredDaysBeforeToday:1];
}
#end
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSDate *now =[NSDate date];
NSDate *twoDaysBefore = [[NSCalendar currentCalendar] dateByAddingComponents:(
{
NSDateComponents *comps = [[NSDateComponents alloc] init];
comps.day = -2;
comps;
})
toDate:now
options:0];
if ([twoDaysBefore dayOccuredDuringLast7Days]) {
NSLog(#"last week");
} else {
NSLog(#"not last week");
}
if ([twoDaysBefore dayWasYesterday]) {
NSLog(#"yesteday");
} else {
NSLog(#"not yesterday");
}
}
return 0;
}
I have a method that to create timestamp in long long integer format
EX: 1386752892
+ (NSNumber *)currentTimestampWithLongLongFormat
{
double timeStamp = ceil([[NSDate date] timeIntervalSince1970] * 1000);
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setGeneratesDecimalNumbers:false];
NSNumber *timeNumber = [NSNumber numberWithDouble:timeStamp];
NSString *timeString = [formatter stringFromNumber:timeNumber];
// NSTimeInterval is defined as double
return [NSNumber numberWithLongLong:[timeString longLongValue]];
}
But this will generate 13 digitals number
EX: 1386752811802
How to fix the problem and generate the correct format of number?
int timestamp = [[NSDate date] timeIntervalSince1970];
Try this
/**
* #param nil
* #return current time in mili second
*
* Fetch the current time stamp
*/
-(NSString *)currentTimeStamp {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSTimeZone *gmt = [NSTimeZone timeZoneWithName:#"GMT"];
[dateFormatter setTimeZone:gmt];
NSString *timeStamp1 = [dateFormatter stringFromDate:[NSDate date]];
NSDate *curdate = [dateFormatter dateFromString:timeStamp1];
double unix_timestamp = [curdate timeIntervalSince1970];
NSString *timeStamp = [NSString stringWithFormat:#"%f",unix_timestamp*1000];
return timeStamp;
}
+ (NSString*) dateFromString:(NSString*)aStr
{
NSDateFormatter *formater = [[NSDateFormatter alloc] init];
[formater setDateFormat:#"yyyy-MM-dd HH:mm"];
NSDate *date2 = [formater dateFromString:aStr];
[formater setDateFormat:#"d MMM,yyyy HH:mm"];
NSString *result = [formater stringFromDate:date2];
return result;
}
+ (NSString *)calculateTime:(NSString *)datetime :(NSString *)servertime
{
NSString *time;
NSDate *date1;
NSDate *date2;
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
date1 = [formatter dateFromString:datetime];
date2 = [formatter dateFromString:servertime];
}
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *differenceComponents = [calendar components:(NSDayCalendarUnit)
fromDate:date1
toDate:date2
options:0];
NSTimeInterval interval = [date1 timeIntervalSinceDate: date2];//[date1 timeIntervalSince1970] - [date2 timeIntervalSince1970];
int hour = interval / 3600;
int minute = (int)interval % 3600 / 60;
int seconds = (int)interval % 60;
hour=ABS(hour);
minute=ABS(minute);
seconds=ABS(seconds);
if ([differenceComponents day]>0) {
time= [NSString stringWithFormat:#"%ld %#", (long)[differenceComponents day],[NSString stringWithFormat:NSLocalizedString(#"daysago", nil)]];
}
else
{
if ([differenceComponents day] == 0) {
time= [NSString stringWithFormat:#"%ld %#", (long)[differenceComponents day],[NSString stringWithFormat:NSLocalizedString(#"dayago", nil)]];
if (hour>0) {
time= [NSString stringWithFormat:#"%d %#", ABS(hour),[NSString stringWithFormat:NSLocalizedString(#"hourago", nil)]];
}
else {
time= [NSString stringWithFormat:#"%d %#", ABS(hour),[NSString stringWithFormat:NSLocalizedString(#"hoursago", nil)]];
if (minute>0) {
time= [NSString stringWithFormat:#"%d %#", ABS(minute),[NSString stringWithFormat:NSLocalizedString(#"minuteago", nil)]];
}
else {
time= [NSString stringWithFormat:#"%d %#", ABS(minute),[NSString stringWithFormat:NSLocalizedString(#"minuteago", nil)]];
if (seconds>0) {
time= [NSString stringWithFormat:#"%d %#", ABS(seconds),[NSString stringWithFormat:NSLocalizedString(#"secondago", nil)]];
}
else {
time= [NSString stringWithFormat:#"%d %#", ABS(seconds),[NSString stringWithFormat:NSLocalizedString(#"secondsago", nil)]];
}
}
}
}
}
return time;
}
/// as per requirement we will use date formats
I have a UIDatePicker on one viewController that allows the user to set a calendar date, hour, and minute in the form of (sun July 22nd, 2:33pm) for a timer to be used in a separate viewController. On the separate viewController I am trying to have the timer displayed in an overlay on the UIImagePickerController in the form of 'dd:hh:mm:ss' left between the current NSDate (todays date/time) and the chosen datePicker date. Basically it's a countdown timer that starts counting down days, hours, minutes, seconds from the selected picker date, when the camera loads. My problem is that once the camera loads, the timer displays the correct remaining time in the correct format but then quickly disappears when it get's to my refreshLabel method. I Logged the values for my timerLabel and it is displaying correctly in the log but once the loop runs once it returns Null for everything. I had some help last night in determining that my problem could most likely be with the formatting of the date from string but I don't see what it is that could be wrong since the correct date is initially displayed when the camera first loads. So here's my code from my first viewController with the datePicker that sets the timerLabels time:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showDate"]) {
NSString *textFieldContents = self.textField.text;
NSString *counterContents = self.counter;
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *deadline = [NSString stringWithFormat:#"%#/deadline.txt",
documentsDirectory];
NSString *flashName = [NSString stringWithFormat:#"%#/flashName.txt",
documentsDirectory];
NSError *fileError;
[textFieldContents writeToFile:flashName
atomically:YES
encoding:NSStringEncodingConversionAllowLossy
error:&fileError];
[counterContents writeToFile:deadline
atomically:YES
encoding:NSStringEncodingConversionAllowLossy
error:&fileError];
if(fileError.code == 0){
NSLog(#"deadline.txt was written successfully with these contents: %#,",
counterContents);
NSLog(#"flashName.txt was written successfully with these contents: %#,",
textFieldContents);}
else
[self performSegueWithIdentifier:#"showDate" sender:self];}
}
-(IBAction)refreshLabel; {
NSDate *selected = [NSDate dateWithTimeIntervalSince1970:[picker.date timeIntervalSince1970] - 1];
self.counter = [self.formatter stringFromDate:selected];
NSLog(#"selected is: %#", selected);
NSDate *todaysDate = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger unitFlags = NSDayCalendarUnit | NSMinuteCalendarUnit | NSHourCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *dateComparisonComponents = [gregorian components:unitFlags fromDate:todaysDate toDate:selected options:NSWrapCalendarComponents];
NSInteger days = [dateComparisonComponents day];
NSInteger hours = [dateComparisonComponents hour];
NSInteger minutes = [dateComparisonComponents minute];
NSInteger seconds = [dateComparisonComponents second];
self.counter = [NSString stringWithFormat:#"%ld:%02ld:%02ld:%02ld", (long)days, (long)hours, (long)minutes, (long)seconds];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *deadline = [NSString stringWithFormat:#"%#/deadline.txt", documentsDirectory];
NSInteger success = [NSKeyedArchiver archiveRootObject:selected toFile:deadline];
NSLog(#"success is: %d",success);
}e *selected = [NSDate dateWithTimeIntervalSince1970:[[picker date] timeIntervalSince1970] - 1];
- (void)viewDidLoad
{ [super viewDidLoad];
self.textField.delegate = self;
self.formatter = [NSDateFormatter new];
[self.formatter setDateFormat:#"dd:hh:mm:ss"];
NSDate *now = [NSDate date];
picker.minimumDate = [NSDate date];
picker.maximumDate = [now dateByAddingTimeInterval:604800];
[picker setDate:now animated:YES];
self.counter = [now description];
self.now = [NSDate date];
self.counter = [self.formatter stringFromDate:self.now];}
And here's my viewController code for the UIImagePickerController that I need to have the timerLabel displayed and counting down correctly:
- (IBAction)startCamera:(id)sender {
if (self.image == nil && [self.videoFilePath length] == 0) {
self.imagePickerController = [[UIImagePickerController alloc] init];
self.imagePickerController.delegate = self;
self.imagePickerController.allowsEditing = NO;
self.imagePickerController.videoMaximumDuration = 10;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
self.imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
}
else {
self.imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
self.imagePickerController.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:self.imagePickerController.sourceType];
[self presentViewController:self.imagePickerController animated:NO completion:nil];}
[[NSBundle mainBundle] loadNibNamed:#"OverlayView" owner:self options:nil];
self.overlayView.frame = CGRectMake(160,8,0,0);
self.imagePickerController.cameraOverlayView = self.overlayView;
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *deadline = [NSString stringWithFormat:#"%#/deadline.txt",
documentsDirectory];
NSString *flashName = [NSString stringWithFormat:#"%#/flashName.txt",
documentsDirectory];
NSError *fileError;
titleLabel.text = [NSString stringWithContentsOfFile:flashName
encoding:NSASCIIStringEncoding
error:&fileError];
timerLabel.text = [NSString stringWithContentsOfFile:deadline
encoding:NSASCIIStringEncoding
error:&fileError];
if(fileError.code == 0){
NSLog(#"deadline.txt was read successfully with these contents: %#,",
timerLabel.text);
NSLog(#"flashName.txt was read successfully with these contents: %#,",
titleLabel.text);}
self.startDate = [NSKeyedUnarchiver unarchiveObjectWithFile:deadline];
[self refreshLabel];
[NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(refreshLabel)
userInfo:nil
repeats:YES];
}
-(void)refreshLabel {
NSDate *todaysDate = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger unitFlags = NSDayCalendarUnit | NSMinuteCalendarUnit | NSHourCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *dateComparisonComponents = [gregorian components:unitFlags fromDate:todaysDate toDate:self.startDate options:NSWrapCalendarComponents];
NSInteger days = [dateComparisonComponents day];
NSInteger hours = [dateComparisonComponents hour];
NSInteger minutes = [dateComparisonComponents minute];
NSInteger seconds = [dateComparisonComponents second];
self.timerLabel.text = [NSString stringWithFormat:#"%ld:%02ld:%02ld:%02ld", (long)days, (long)hours, (long)minutes, (long)seconds];
if (days == 0 && hours == 0 && minutes == 0 && seconds == 0) {
[self.timer invalidate];
NSLog(#"Time's up!");
}
}
As per our discussion last night, you can't use a date formatter this way, because you're looking at time in the future like 1 day 2 hours 5 minutes, not a date. One way to do this, would be to pass the picker's selected date to the image picker controller, and do pretty much the same thing you did in the first controller to get the date components. So in the first controller, save the picker date to the file rather than a string:
-(IBAction)refreshLabel; {
NSDate *selected = [NSDate dateWithTimeIntervalSince1970:[picker.date timeIntervalSince1970] - 1];
self.counter = [self.formatter stringFromDate:selected];
NSLog(#"selected is: %#", selected);
NSDate *todaysDate = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger unitFlags = NSDayCalendarUnit | NSMinuteCalendarUnit | NSHourCalendarUnit | NSSecondCalendarUnit;
dateComparisonComponents = [gregorian components:unitFlags fromDate:todaysDate toDate:selected options:NSWrapCalendarComponents];
NSInteger days = [dateComparisonComponents day];
NSInteger hours = [dateComparisonComponents hour];
NSInteger minutes = [dateComparisonComponents minute];
NSInteger seconds = [dateComparisonComponents second];
self.counter = [NSString stringWithFormat:#"%ld:%02ld:%02ld:%02ld", (long)days, (long)hours, (long)minutes, (long)seconds];
self.textField.text = self.counter;
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *deadline = [NSString stringWithFormat:#"%#/deadline.txt", documentsDirectory];
NSInteger success = [NSKeyedArchiver archiveRootObject:selected toFile:deadline];
NSLog(#"success is: %d",success);
}
Then in the image picker controller (I'm only showing the code needed for the timer label):
- (IBAction)startCamera:(id)sender {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *deadline = [NSString stringWithFormat:#"%#/deadline.txt", documentsDirectory];
NSError *fileError;
self.startDate = [NSKeyedUnarchiver unarchiveObjectWithFile:deadline];
[self refreshLabel];
if(fileError.code == 0){
NSLog(#"deadline.txt was read successfully with these contents: %#,", self.timerLabel.text);
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(refreshLabel) userInfo:nil repeats:YES];
}
}
-(void)refreshLabel{
NSDate *todaysDate = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger unitFlags = NSDayCalendarUnit | NSMinuteCalendarUnit | NSHourCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *dateComparisonComponents = [gregorian components:unitFlags fromDate:todaysDate toDate:self.startDate options:NSWrapCalendarComponents];
NSInteger days = [dateComparisonComponents day];
NSInteger hours = [dateComparisonComponents hour];
NSInteger minutes = [dateComparisonComponents minute];
NSInteger seconds = [dateComparisonComponents second];
self.timerLabel.text = [NSString stringWithFormat:#"%ld:%02ld:%02ld:%02ld", (long)days, (long)hours, (long)minutes, (long)seconds];
if (days == 0 && hours == 0 && minutes == 0 && seconds == 0) {
[self.timer invalidate];
NSLog(#"Time's up!");
}
}
I want to have a countdown from the current time to a specific date and display that value in a label. I looked at some NSTimer tutorials but I could not figure out how to apply them to my situation.
NSTimeInterval TimeInterval = [aString doubleValue];
NSDate* upperDate = [aDate dateByAddingTimeInterval:TimeInterval];
NSDate* Today = [NSDate date];
//cell.myLabel.text = here i should write a countdown.
Sorry for insufficient code. I usually try to write some of my own code before asking a question here but this time I could not figure what to write.
Edit
So with the answer of PartiallyFinite i figured how i set timer. But because i am using tableview i could not implement the repeat message for MyTimerLabel. Here what i just did:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MyCell";
MekanListesiViewCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MyCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
aClass *aC = [myArray objectAtIndex:indexPath.row];
NSTimeInterval TimeInterval = [aC.aTimeIntervalwithString doubleValue];
NSDate* UpperDate = [aC.aNSDate dateByAddingTimeInterval:TimeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"YYYY-MM-dd"];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSUInteger unitFlags = NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit;
NSDateComponents *dateComponents = [calendar components:unitFlags fromDate:[NSDate date] toDate:UpperDate options:0];
NSInteger days = [dateComponents day];
NSInteger months = [dateComponents month];
NSInteger years = [dateComponents year];
NSInteger hours = [dateComponents hour];
NSInteger minutes = [dateComponents minute];
NSInteger seconds = [dateComponents second];
NSString *countdownText = [NSString stringWithFormat:#"%d Days %d:%d:%d", days, hours, minutes, seconds];
cell.countdownText= countdownText;
[self performSelector:#selector(updateCoundown)]; // The delay is in seconds, make it whatever you want.
return cell;
}
At myCellView.h
#interface MekanListesiViewCell : UITableViewCell
#property (nonatomic, weak) IBOutlet UILabel *MyTimerLabel;
#property(weak)NSString *countdownText;
at myCellView.m
-(void)updateCoundown{
MyTimerLabel.text = countdownText;
[self performSelector:#selector(updateCoundown) withObject:nil afterDelay:1];
}
i get nothing in the MyTimerLabel.
Using the code from this answer (copy pasted below for completeness of example) to get the individual components of the countdown period:
- (void)updateCountdown {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"YYYY-MM-dd"];
NSDate *startingDate = [dateFormatter dateFromString:#"2005-01-01"];
NSDate *endingDate = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSUInteger unitFlags = NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit;
NSDateComponents *dateComponents = [calendar components:unitFlags fromDate:startingDate toDate:endingDate options:0];
NSInteger days = [dateComponents day];
NSInteger months = [dateComponents month];
NSInteger years = [dateComponents year];
NSInteger hours = [dateComponents hour];
NSInteger minutes = [dateComponents minute];
NSInteger seconds = [dateComponents second];
We can then create a string with all of these numbers:
NSString *countdownText = [NSString stringWithFormat:#"%d Years %d Months %d Days %d Hours %d Minutes %d Seconds", days, months, years, hours, minutes, seconds];
cell.myLabel.text = countdownText;
Then, we can use performSelector:withObject:afterDelay: to make this method get called again after the specified delay (note that the delay is in seconds):
[self performSelector:#selector(updateCountdown) withObject:nil afterDelay:1];
}
Declare member variables like
NSDate *startDate,*EndDate;
unsigned long countDownSeconds;
According to your requirement
-(void)setUpCountDown{
startDate = [NSDate date]; //Current time
NSDate *endDate = [startDate dateByAddingTimeInterval:10000]; //some future date
NSTimeInterval milliseconds = [endDate timeIntervalSinceDate:startDate];/////will give time in milliseconds
countDownSeconds = (unsigned long)milliseconds/1000;
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(countDown:) userInfo:nil repeats:YES];
}
-(void)countDown:(NSTimer *)timer{
if (countDownSeconds<=0) {
[timer invalidate];
timer = nil;
}
NSLog(#"Time Elapsed in seconds %d", countDownSeconds);
countDownSeconds--;
}
let formatter = NSDateFormatter()
let userCalendar = NSCalendar.currentCalendar()
let requestedComponent: NSCalendarUnit = [
//NSCalendarUnit.Month,
//NSCalendarUnit.Day,
NSCalendarUnit.Hour,
NSCalendarUnit.Minute,
NSCalendarUnit.Second
]
func printTime() {
formatter.dateFormat = "MM/dd/yy hh:mm:ss a"
let startTime = NSDate()
let endTime = formatter.dateFromString("12/25/16 8:00:00 a")
let timeDifference = userCalendar.components(requestedComponent, fromDate: startTime, toDate: endTime!, options: [])
self.TimeLabel.text = " \(timeDifference.hour)Hours \(timeDifference.minute)Minutes \(timeDifference.second) Seconds"
}
//Put this in your initialiser
let timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(myProject.printTime), userInfo: nil, repeats: true)
timer.fire()
I know this thread is very old, but this is how i would do it in Swift
Keep an instance variable to hold the date
//Fire Timer
_savedDate = [[NSDate date]dateByAddingTimeInterval:30];
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(countDown:) userInfo:nil repeats:YES];
- (void)countDown:(NSTimer *)timer
{
NSDate *date = [NSDate date];
if ([date isEqualToDate:_savedDate]) {
[timer invalidate];
}
NSDateComponents *dateComponents = [[NSCalendar currentCalendar]components:NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit fromDate:date toDate:_savedDate options:0];
NSLog(#"%02d:%02d:%02d",dateComponents.hour,dateComponents.minute,dateComponents.second);
}