After adding a comment i need to show comment timing like year ago,day ago,minutes ago and second ago on label but it returns -4425,-33434 seconds ago "random numbers".
Here is my code shown below am using in my app.
NSString *inDateStr = [NSString stringWithFormat:#"%#",[[[dict objectForKey:#"d"] objectAtIndex:indexPath.row-1] objectForKey:#"created"]];
NSString *s = #"yyyy-MM-dd HH:mm:ss";
// about input date(GMT)
NSDateFormatter *inDateFormatter = [[NSDateFormatter alloc] init];
inDateFormatter.dateFormat = s;
inDateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT-7.00"];
NSDate *inDate = [inDateFormatter dateFromString:inDateStr];
// about output date(IST)
NSDateFormatter *outDateFormatter = [[NSDateFormatter alloc] init];
outDateFormatter.timeZone = [NSTimeZone localTimeZone];
outDateFormatter.dateFormat = s;
NSString *outDateStr = [outDateFormatter stringFromDate:inDate];
// final output
NSLog(#"[in]%# -> [out]%#", inDateStr, outDateStr);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *dateStartingString = [[NSDate alloc] init];
NSString *datestartString = outDateStr;
dateStartingString = [dateFormatter dateFromString:datestartString];
NSTimeInterval timeDifference = [[NSDate date] timeIntervalSinceDate:dateStartingString];
double minutes = timeDifference / 60;
double hours = minutes / 60;
double seconds = timeDifference;
double days = minutes / 1440;
UILabel * dateLbl=[[UILabel alloc] initWithFrame:CGRectMake(155, [[CountArr objectAtIndex:indexPath.row] floatValue]-1, 80, 20)];
if(seconds>=86400)
dateLbl.text=[NSString stringWithFormat:#"%.0f days ", days];
else if(seconds>=3600 && seconds<86400 )
dateLbl.text=[NSString stringWithFormat:#"%.0f hours ", hours];
else if (seconds>=60 && seconds<3600 )
dateLbl.text=[NSString stringWithFormat:#"%.0f minutes ", minutes];
else
dateLbl.text=[NSString stringWithFormat:#"%.0f seconds ", seconds];
dateLbl.textColor=[UIColor lightGrayColor];
dateLbl.font = [UIFont systemFontOfSize:12];
[cell.contentView addSubview:dateLbl];
I believe NSDateFormatter only takes a string and returns a NSDate object. Setting the timezone is meant for setting the property of NSDate, but doesn't actually convert the time provided. So in the end if you put in 5:30 GMT, you will get 5:30 IST.
You would instead want to use NSCalender to do timezone conversions.
You can use this method to get difference in date.
Make sure that date formate is correct. If you are getting negative value just check date format.
-(NSDateComponents *)getDateDifference:(NSString *)date
{
NSDate *dateA=[NSDate date]; //Current date
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSDate *dateB = [dateFormatter dateFromString:date];//Convert nsstring to nsdate
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; //Gregorian allocation
NSDateComponents *components = [calendar components:NSDayCalendarUnit|NSHourCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit
fromDate:dateA
toDate:dateB
options:0]; //Get day and hour
return components;
}
// Call method like
NSDateComponents *difference = [self getDateDifference:marriageDate];
NSLog(#"diff year = %f",difference.year);
Related
In my app I need to get the days, hours, minutes and seconds from a given date which is coming from JSON response. Below is the date and time i'm getting:
"date_time" = "2017-01-31 08:30:00";
and need to calculate remaining like days: 6 hours: 18 minutes: 24 seconds: 30
End date will be today's date. I tried below code but it is giving me days in minus (I think it takes UTC timezone) and also tried many answers on SO.
NSString *start = [[self.eventsArray valueForKey:#"date_time"]objectAtIndex:0];
NSDateFormatter *date = [[NSDateFormatter alloc] init];
[date setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *end = [date stringFromDate:[NSDate date]];
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *startDate = [f dateFromString:start];
NSDate *endDate = [f dateFromString:end];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *components = [gregorianCalendar components:NSCalendarUnitDay
fromDate:startDate
toDate:endDate
options:0];
NSLog(#"day : %ld H: %ld M : %ld S:%ld", [components day], (long)[components hour],(long)[components minute],(long)[components second]);
Somebody please help i'm stuck.
You are making mistake here, your fromDate should be the today date ie [NSDate date] and with toDate will be your startDate. So your code should be something like this.
NSString *end = [[self.eventsArray valueForKey:#"date_time"]objectAtIndex:0];
NSDateFormatter *date = [[NSDateFormatter alloc] init];
[date setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
//Start date
NSDate *startDate = [NSDate date];
NSDate *endDate = [f dateFromString:end];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *components = [gregorianCalendar components:NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond
fromDate:startDate
toDate:endDate
options:0];
NSLog(#"day : %ld H: %ld M : %ld S:%ld", [components day], (long)[components hour],(long)[components minute],(long)[components second]);
Call below method and pass your date
+(NSMutableString*) timeLeftSinceDate: (NSDate *) dateT {
NSMutableString *timeLeft = [[NSMutableString alloc]init];
NSDate *today10am = [NSDate date];
today10am = [self getPickerDateForString:[self getPickerDateForDate:today10am]];
NSInteger seconds = [today10am timeIntervalSinceDate:dateT];
NSInteger days = (int) (floor(seconds / (3600 * 24)));
if(days) seconds -= days * 3600 * 24;
NSInteger hours = (int) (floor(seconds / 3600));
if(hours) seconds -= hours * 3600;
NSInteger minutes = (int) (floor(seconds / 60));
if(minutes) seconds -= minutes * 60;
if(days) {
[timeLeft appendString:[NSString stringWithFormat:#"%ld Days ago", (long)days]];
}else if(hours) {
[timeLeft appendString:[NSString stringWithFormat: #"%ld h ago", (long)hours]];
}else if(minutes) {
[timeLeft appendString: [NSString stringWithFormat: #"%ld m ago",(long)minutes]];
}else if(seconds) {
[timeLeft appendString:[NSString stringWithFormat: #"Just now"]];
}
return timeLeft;
}
+ (NSString *)getPickerDateForDate:(NSDate *)dateVal
{
NSString * stringVal;
if (!dateFormatter)
{
dateFormatter = [[NSDateFormatter alloc] init];
}
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
dateFormatter.timeZone = [NSTimeZone timeZoneWithName:#"UTC"];
stringVal = [dateFormatter stringFromDate:dateVal];
return stringVal;
}
+ (NSDate *)getPickerDateForString:(NSString *)dateString
{
NSDate * stringVal;
if (!dateFormatter)
{
dateFormatter = [[NSDateFormatter alloc] init];
}
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
dateFormatter.timeZone = [NSTimeZone systemTimeZone];
stringVal = [dateFormatter dateFromString:dateString];
return stringVal;
}
I have date in string format,that is with UTC time zone.
I want to add 20 minutes to date.
I am using following code for that:
NSString *strFinal = #"2016-11-21 13:07:04";
//NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
//[dateFormatter setDateFormat:#"yyyy-mm-dd hh:mm:ss"];
self.dateFormatter = [[NSDateFormatter alloc]init];
[self.dateFormatter setDateFormat:#"yyyy-MM-dd hh:mm:ss"];
NSDate *dateFromString = [[NSDate alloc] init];
[self.dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
dateFromString = [self.dateFormatter dateFromString:strFinal];
self.dt = [[NSDate alloc]init];
self.dt = dateFromString;
NSTimeInterval secondsInEightHours = 20 * 60;
//NSDate *dateEightHoursAhead = [dateFromString dateByAddingTimeInterval:secondsInEightHours];
NSDate *dateEightHoursAhead = [self.dt dateByAddingTimeInterval:secondsInEightHours];
//after adding 20 mins check
NSString *strFinaltoPass = [self.dateFormatter stringFromDate:dateEightHoursAhead];
but with this date time it gives strFinaltoPass as null.
This works fine with time less than 12 hours but after 12 hour its showing null.
Any help will be appreciated.
Thanks,
You can use NSCalendar to add minutes, here is an example
NSString *strDate = #"2016-11-21 13:07:04";
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
[dateFormatter1 setDateFormat:#"yyyy-MM-dd hh:mm:ss"];
NSDate *dateTemp = [dateFormatter1 dateFromString:strDate];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *dateNew = [calendar dateByAddingUnit:NSCalendarUnitMinute value:20 toDate:dateTemp options:NSCalendarWrapComponents];
here value = 20 is 20 minutes to add in the date
I want to set a UILocalNotification to go off at a certain time. The app deals with restaurant bookings. If a booking is made and the appointment is greater than 2 hours from now, then I want to show the notification 2 hours before it. If it is greater than 1 hour then I was to show it 1 hour before hand, else I want to show it 15 mins before hand. The dificulty Im having is that my UILocalNotification fire time is wrong by + 1 hour. Below is the code used:
[self setLocalNotificationWithAlertBody:#"Alert Body goes here" AndWithBookingDateString:#"2015-09-07 19:45:00"];//the booking time
-(void)setLocalNotificationWithAlertBody:(NSString *)body AndWithBookingDateString:(NSString *)dateString{
NSLog(#"Date String %#",dateString);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT"]];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"]];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *dateFromString = [[NSDate alloc] init];
dateFromString = [dateFormatter dateFromString:dateString];
NSLog(#"Date from String %#",[dateFormatter dateFromString:dateString]);
[self setLocalNotificationWithAlertBody:body AndWithBookingDate:dateFromString];
}
-(void)setLocalNotificationWithAlertBody: (NSString *) body AndWithBookingDate: (NSDate *)date{
NSDate *currentDate = [NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit
fromDate:currentDate
toDate:date
options:0];
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
NSInteger hour = [components hour];
if (components.hour>=2) {//remind the user 2 hours before hand if booking is made greater than 2 hours
NSTimeInterval secondsPerHour = (60 * 60)*2;//two hours before appointment
NSDate *givenDate = date; // what you have already
NSDate *earlierDate = [givenDate dateByAddingTimeInterval:-secondsPerHour];
NSLog(#"\n\n Greater than 2 hours %# \n\n",earlierDate);
localNotification.fireDate=earlierDate;
localNotification.alertBody = [NSString stringWithFormat:#"%# %#",body,[self getDeviceShortDateFromString:[NSString stringWithFormat:#"%#",date] WithFormat:#"yyyy-MM-dd HH:mm:ss ZZZZZ"]];
}
else if (components.hour>1) {
NSTimeInterval secondsPerHour = 60 * 60;
NSDate *givenDate = date; // what you have already
NSDate *earlierDate = [givenDate dateByAddingTimeInterval:-secondsPerHour];
NSLog(#"\n\n Greater than an hour %# \n\n",earlierDate);
localNotification.fireDate=earlierDate;
localNotification.alertBody = [NSString stringWithFormat:#"%# %#",body,[self getDeviceShortDateFromString:[NSString stringWithFormat:#"%#",date] WithFormat:#"yyyy-MM-dd HH:mm:ss ZZZZZ"]];
}
else{
NSTimeInterval secondsPer15mins = 15 * 60;
NSDate *givenDate = date; // what you have already
NSDate *earlierDate = [givenDate dateByAddingTimeInterval:-secondsPer15mins];
NSLog(#"\n\n Less than one hour %# \n",earlierDate);
localNotification.fireDate=earlierDate;
localNotification.alertBody = [NSString stringWithFormat:#"%# %#",body,[self getDeviceShortDateFromString:[NSString stringWithFormat:#"%#",date] WithFormat:#"yyyy-MM-dd HH:mm:ss ZZZZZ"]];
}
localNotification.userInfo = #{#"key" : body};
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
NSLog(#"Fire date %#",localNotification.fireDate);
NSLog(#"Notification--->: %#", localNotification);
}
-(NSString *)getDeviceShortDateFromString: (NSString *) date WithFormat: (NSString *)format{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"]];
[dateFormatter setDateFormat:format];
NSDate * tempDate =[dateFormatter dateFromString: date];
NSDateFormatter *dateFormatter2 = [[NSDateFormatter alloc] init];
[dateFormatter2 setDateFormat:#"MMM yyyy"];
if (tempDate == nil) {
return #" ";
}
return [dateFormatter2 stringFromDate:tempDate];
}
The fire date is logging as:
Fire date 2015-09-07 17:45:00 +0000
But the local notification is wrong:
Notification--->: <UIConcreteLocalNotification: 0x174178300>{fire date = Monday 7 September 2015 18:45:00 Irish Summer Time, time zone = (null), repeat interval = 0, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Monday 7 September 2015 18:45:00 Irish Summer Time, user info = {
key = "Alert Body Goes here";
}}
The appointment was booked greater than 2 hours so the notification should be going off at 5:45 but it doesnt go off until 6:45. Any help is greatly appreciated.
"Help me StackOverflow, you're my only hope" :)
For scaleable apps that rely on location specific results, ensure that your location specific properties always point to the users relative location. In your case, you just overlooked a simple setting:
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT"]];
For you, this is +1 hour, but for others it will vary some will be ahead and some will be behind, because your basing the fireDate on GMT's time.
I would simply alter this to be [NSTimeZone systemTimeZone]
I need to get a NSString that displays a total of traveled time using 2 NSStrings
I have
NSString *origin = [NSString stringWithFormat:#"5:30"];
NSString *destiny = [NSString stringWithFormat:#"6:00"];
The problem is I don't know how to format this NSStrings to NSDate and do destiny - origin so the output would be a new NSString that says 30 minutes
EDIT: I've just investigate a little about the NSDateFormatter but if I use it:
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm"];
NSDate * mydate = [dateFormatter dateFromString:origin];
NSDate returns me a nil Is there something wrong?
Any help will be very appreciated.
NSString *origin = #"5:30";
NSString *destiny = #"6:00";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"H:mm"];
NSDate *originDate = [dateFormatter dateFromString:origin];
NSDate *destinyDate = [dateFormatter dateFromString:destiny];
NSTimeInterval interval = [destinyDate timeIntervalSinceDate:originDate];
NSDate *intervalDate = [NSDate dateWithTimeInterval:interval sinceDate:originDate ];
NSDateComponents *comps =[[NSCalendar currentCalendar] components:NSMinuteCalendarUnit
fromDate:originDate
toDate:intervalDate
options:0];
Now the NSDateComponents will hold the difference in minutes
NSLog(#"%ld", [comps minute]);
will log 30
If you would like the hours and minutes, you can do
NSString *origin = #"5:30";
NSString *destiny = #"7:00";
// ....
NSDateComponents *comps =[[NSCalendar currentCalendar] components: (NSMinuteCalendarUnit|NSHourCalendarUnit)
fromDate:originDate
toDate:intervalDate
options:0];
Now comps will hold the 90 minutes as 1 hour and 30 minutes.
NSLog(#"%ld %ld", [comps hour],[comps minute]);
logs 1 30
NSString *origin = #"5:30";
NSString *destiny = #"6:00";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"H:mm"];
NSDate *originDate = [dateFormatter dateFromString:origin];
NSDate *destinyDate = [dateFormatter dateFromString:destiny];
NSTimeInterval diffInSeconds = [destinyDate timeIntervalSinceDate:originDate];
NSTimeInterval diffInMinutes = diffInSeconds / 60;
NSString *minutesString = [NSString stringWithFormat:#"%0.0f", diffInMinutes];
I'm struggling to find a way to use NSDate for time only purposes.
I was trying to do the following code:
- (void)awakeFromInsert
{
NSDateComponents *comps = [[NSDateComponents alloc] init];
comps.minute = 45;
comps.second = 0;
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
self.periodDuration = [calendar dateFromComponents:comps];
NSLog(#"periodDuration: %#",self.periodDuration);
comps = [[NSDateComponents alloc] init];
comps.hour = 8;
comps.minute = 0;
self.firstPeriodStartTime = [calendar dateFromComponents:comps];
NSLog(#"firstPeriodTime: %#",self.periodDuration);
}
But the result I get is:
periodDuration: 0001-12-31 22:24:04 +0000
firstPeriodTime: 0001-12-31 22:24:04 +0000
The result I was expecting:
periodDuration: 45:00
firstPeriodTime: 08:00
What am I doing wrong? How can I fix this?
Thank you.
The log of date is misleading you, if you are forming a date with only a few components you will not get a proper date instance which uniquely identifies a date and time.
If you try with this code snipped you can find that if you are just converting the dates back to string it is just as you expect
NSDateComponents *comps = [[NSDateComponents alloc] init];
comps.minute = 45;
comps.second = 0;
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *periodDate = [calendar dateFromComponents:comps];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"mm:ss"];
NSLog(#"periodDuration: %#",[dateFormatter stringFromDate:periodDate]);
comps = [[NSDateComponents alloc] init];
comps.hour = 8;
comps.minute = 0;
NSDate *firstPeriodDate = [calendar dateFromComponents:comps];
[dateFormatter setDateFormat:#"HH:mm"];
NSLog(#"firstPeriodTime: %#",[dateFormatter stringFromDate:firstPeriodDate]);
periodDuration: 45:00
firstPeriodTime: 08:00
You can use NSDateFormatter
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm"];
NSLog(#"%#",[dateFormatter stringFromDate:[NSDate date]]);
Use a NSTimeInterval (which is, basically, a double containing the number of seconds). To store it in CoreData:
[NSNumber numberWithDouble:myTimeInterval];
As for formatting: If you want more than 24h displayed, use this:
NSUInteger seconds = (NSUInteger)round(myTimeInterval);
NSString *formattedDate = [NSString stringWithFormat:#"%02u:%02u:%02u",
seconds / 3600, (seconds / 60) % 60, seconds % 60];
NSLog(#"%#", formattedDate);
If you don't want more than 24h, you can use NSDate and NSDateFormatter again:
NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:myTimeInterval];
NSDateFormatter *dateFormatter = [NSDateFormatter new];
[dateFormatter setDateFormat:#"HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
NSString *formattedDate = [dateFormatter stringFromDate:date];
NSLog(#"%#", formattedDate);
NSString *timeString;
timeString = [NSDateFormatter localizedStringFromDate:[NSDate date]
dateStyle:NSDateFormatterNoStyle
timeStyle:NSDateFormatterMediumStyle];
12:03:54 PM