This question already has answers here:
Comparing time and date in objective C
(2 answers)
Closed 9 years ago.
In my app i want to check whether the current time is before or after the time saved in a variable.
like my time1 is time1=#"08:15:12"; and my time2 is time2=#"18:12:8";
so i wanna compare between time1 and time2.Currently these variables are in NSString Format.
Following are the code used to get time,and i dont know how to compare them.
CODE:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"HH:MM:SS";
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
NSLog(#"ewetwet%#",[dateFormatter stringFromDate:now]);
Please help me
Use the following code to do the convert from the nsstring to nsdate and compare them.
NSString *time1 = #"08:15:12";
NSString *time2 = #"18:12:08";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"HH:mm:ss"];
NSDate *date1= [formatter dateFromString:time1];
NSDate *date2 = [formatter dateFromString:time2];
NSComparisonResult result = [date1 compare:date2];
if(result == NSOrderedDescending)
{
NSLog(#"date1 is later than date2");
}
else if(result == NSOrderedAscending)
{
NSLog(#"date2 is later than date1");
}
else
{
NSLog(#"date1 is equal to date2");
}
// Use compare method.
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *startDate = [formatter dateFromString:#"2012-12-07 7:17:58"];
NSDate *endDate = [formatter dateFromString:#"2012-12-07 7:17:59"];
if ([startDate compare: endDate] == NSOrderedDescending) {
NSLog(#"startDate is later than endDate");
} else if ([startDate compare:endDate] == NSOrderedAscending) {
NSLog(#"startDate is earlier than endDate");
} else {
NSLog(#"dates are the same");
}
// Way 2
NSTimeInterval timeDifference = [endDate timeIntervalSinceDate:startDate];
double minutes = timeDifference / 60;
double hours = minutes / 60;
double seconds = timeDifference;
double days = minutes / 1440;
NSLog(#" days = %.0f,hours = %.2f, minutes = %.0f,seconds = %.0f", days, hours, minutes, seconds);
if (seconds >= 1)
NSLog(#"End Date is grater");
else
NSLog(#"Start Date is grater");
First you need to convert your time string to NSDate => Converting time string to Date format iOS.
Then use following code
NSDate *timer1 =...
NSDate *timer2 =...
NSComparisonResult result = [timer1 compare:timer2];
if(result == NSOrderedDescending)
{
// time 1 is greater then time 2
}
else if(result == NSOrderedAscending)
{
// time 2 is greater then time 1
}
else
{
//time 1 is equal to time 2
}
You can use this link
According to Apple documentation of NSDate compare:
Returns an NSComparisonResult value that indicates the temporal ordering of the receiver and another given date.
- (NSComparisonResult)compare:(NSDate *)anotherDate
Parameters anotherDate
The date with which to compare the receiver. This value must not be nil. If the value is nil, the behavior is undefined and may change in future versions of Mac OS X.
Return Value
If:
The receiver and anotherDate are exactly equal to each other, NSOrderedSame
The receiver is later in time than anotherDate, NSOrderedDescending
The receiver is earlier in time than anotherDate, NSOrderedAscending
In other words:
if ([date1 compare:date2]==NSOrderedSame) ...
Note that it might be easier to read and write this :
if ([date2 isEqualToDate:date2]) ...
See Apple Documentation about this one. If you feel any problem you can also use this link here. Here you can go through Nelson Brian answer.
I have done this at my end as follows-
NSDate * currentDateObj=#"firstDate";
NSDate * shiftDateFieldObj=#"SecondDate";
NSTimeInterval timeDifferenceBetweenDates = [shiftDateFieldObj timeIntervalSinceDate:currentDateObj];
You can also get time interval according to time difference between dates.
Hope this helps.
Related
compare 2 dates
if (from_date >= today && totime < = today)
i tried with this
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSLog(#"%#",[dateFormatter stringFromDate:[NSDate date]]);
NSString * TodayDate = [dateFormatter stringFromDate:[NSDate date]];
if ([displayList.fromTime compare:TodayDate] == NSOrderedDescending) {
NSLog(#"date1 is later than date2");
} else if ([displayList.toTime compare:date2] == NSOrderedAscending) {
NSLog(#"date1 is earlier than date2");
} else {
NSLog(#"dates are the same");
}
You can comparing NSString, which is wrong. You need to compare two NSDate objects.
Here is update code:
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
// You are doing wrong compareing at here. You need to compare Date nor sting.
// NSString * TodayDate = [dateFormatter stringFromDate:[NSDate date]];
NSDate *TodayDate = [NSDate date];
NSDate *compareData = [dateFormatter dateFromString:#"2017-07-09 11:12:11"];
if ([compareData compare:TodayDate] == NSOrderedDescending) {
NSLog(#"date1 is later than date2");
} else if ([compareData compare:TodayDate] == NSOrderedAscending) {
NSLog(#"date1 is earlier than date2");
} else {
NSLog(#"dates are the same");
}
You're not saying what class of object fromDate is, but since you're comparing it to TodayDate, which is a string, I'm assuming all of your dates are strings when you compare them? If so, that's a bad choice. Date comparison and string comparison are not the same and will yield different results.
Instead of turning today's date into a string, you should turn fromDate into an NSDate, and then compare those.
If, OTOH, fromDate is not a string, then that's your error. Just because two objects result in the same text being NSLogged doesn't mean they're the same type and can be compared, so make sure they're all the same type (NSDate) and then compare those.
This question already has answers here:
Check whether time falls between two time iOS
(2 answers)
Closed 6 years ago.
I have an object with 2 String properties: notifyFrom and notifyTo.
They are like:
notifyFrom: 14:00
notifyTo: 18:00
and before I send the user a notification (that's part of my app) I want to check if the time is between those hours and just if it is to send the notification.
Note: Date doesn't matter here. I just want to check the times
What is the best way to do it?
Thanks!
You can write method something like,
+ (BOOL)date:(NSDate*)date isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate
{
if ([date compare:beginDate] == NSOrderedAscending)
return NO;
if ([date compare:endDate] == NSOrderedDescending)
return NO;
return YES;
}
Reference : this so post
First of all convert the input two strings to dates
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"HH:mm:ss"];
NSDate *date1 = [dateFormatter dateFromString:notifyFrom];
NSDate *date2 = [dateFormatter dateFromString:notifyTo];
NSDate *userDate = [NSDate date];
if (([userDate laterDate: date1] == userDate) && ([userDate laterDate: date2] == date2)){
}
I am trying to find out whether current date is in between two given dates or not.First I coverted the two date into current date format i.e;2014-10-02 06:45:37 +0000
NSComparisonResult result,restult2;
NSString *startDateStr=#"10/04/2014 06:03 AM";
NSDateFormatter *startdf=[[NSDateFormatter alloc] init];
[startdf setDateFormat:#"MM/dd/yyyy hh:mm a"];
NSDate *startDate12=[startdf dateFromString:startDateStr];
NSString *startStr=[startdf stringFromDate:startDate12];
[startdf setDateFormat:#"yyyy-MM-dd hh:mm:ss"];
NSDate *startDate1=[startdf dateFromString:startStr]; //here startDate1 is nil
NSString *endDateStr=#"10/07/2014 03:03 AM";
NSDateFormatter *enddf=[[NSDateFormatter alloc] init];
[enddf setDateFormat:#"MM/dd/yyyy hh:mm a"];
NSDate *endDate12=[enddf dateFromString:endDateStr];
NSString *endStr=[enddf stringFromDate:endDate12];
[enddf setDateFormat:#"yyyy-MM-dd hh:mm:ss"];
NSDate *endDate1=[startdf dateFromString:endStr]; //here endDate1 is nil
NSDate *date = [NSDate date];
BOOL isBetween=[MyViewController date:date isBetweenDate:startDate1 andDate:endDate1];
if (isBetween)
{
NSLog(#"#####YES");
}
+ (BOOL)date:(NSDate*)date isBetweenDate:(NSDate*)beginDate andDate:(NSDate*)endDate
{
if ([date compare:beginDate] == NSOrderedAscending)
return NO;
if ([date compare:endDate] == NSOrderedDescending)
return NO;
return YES;
}
Please give any suggestions where I am going wrong.
Thanks in Advance...!
You are doing stuff in your code that is pretty much not doing anything. An NSDate object has no format. It has no time zone. It has no months, days, years. It is merely a point in time. When you then convert that date to a string you need to provide a format (which is what NSDateFormatter is for).
Change your code to something like this...
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM/dd/yyyy hh:mm a"];
NSString *startDateStr = #"10/04/2014 06:03 AM";
NSDate *startDate = [dateFormatter dateFromString:startDateStr];
NSString *endDateStr = #"10/07/2014 03:03 AM";
NSDate *endDate = [dateFormatter dateFromString:endDateStr];
NSDate *date = [NSDate date];
// use a function name that matches the convention...
if ([MyViewController isDate:date betweenStartDate:startDate andEndDate:endDate])
{
NSLog(#"#####YES");
}
I think your function should be fine. Just don't mess around with the dates. Once you have them stop there and use them.
Obtain NSDate from your string and compare.
NSDate doesnt contain any format. It is just number of seconds. So you dont need to reconvert it multiple times, its error prone.
Also double check that dateFromString: method doesnt return nil.
To verify, whether a date falls into defined date range, you can use compare method or review the following code:
NSDate *now = [NSDate date];
NSDate *yesterday = [now dateByAddingTimeInterval:-1*24*60*60];
NSDate *tomorrow = [now dateByAddingTimeInterval:+1*24*60*60];
//first condition
if([now compare:yesterday] == NSOrderedDescending && [now compare:tomorrow] == NSOrderedAscending)
NSLog(#"now > yesterday and now < tomorrow");
else
NSLog(#"now is outside yesterday and tomorrow");
NSDate *weekAgo = [now dateByAddingTimeInterval:-7*24*60*60];
//second condition
if([weekAgo compare:yesterday] == NSOrderedDescending && [weekAgo compare:tomorrow] == NSOrderedAscending)
NSLog(#"weekAgo > yesterday and weekAgo < tomorrow");
else
NSLog(#"weekAgo is outside yesterday and tomorrow");
First condition results to
2014-10-02 14:45:21.791 dateTest[95595:8857503] now > yesterday and now < tomorrow
Second condition results to
2014-10-02 14:45:24.425 dateTest[95595:8857503] weekAgo is outside yesterday and tomorrow
convert both dates in milliseconds
long firstDate = [#(floor([startDate1 timeIntervalSince1970] * 1000)) longLongValue];
long secondDate = [#(floor([endDate1 timeIntervalSince1970] * 1000)) longLongValue];
and then covert also the date you want to check like this and check if that value is bigger than firstDate and smaller than `secondDate'
Comparing dates is quite complex. I have an app that is comparing opening and closing dates for stores and it works great for times in the same day, i.e. opening a 8am and closing at 5pm the same day.
Here is the code that compares the time:
if ([self timeCompare:openDate until:closeDate withNow:now]) {
NSLog(#"TIMECOMPARATOR = timeCompare>OPEN");
status = YES;
} else {
NSLog(#"TIMECOMPARATOR = timeCompare>CLOSED");
status = NO;
}
return status;
This calls the following method:
+(BOOL)timeCompare:(NSDate*)date1 until:(NSDate*)date2 withNow:(NSDate*)now{
NSLog(#"TIMECOMPARE = open:%# now:%# close:%#", date1, now, date2);
return ([date1 compare:now] == NSOrderedAscending && [date2 compare:now] == NSOrderedDescending);
}
The problem comes when the closing time is "assumed" by a person but of course not by a computer, to close at the next day, such as 7am to 2am. I obviously mean the next day. How do I accommodate for this to signal the computer to be the next day?
Compare the date's unix time. It will be accurate regardless of date as it is constantly increasing.
First you have to convert the strings "7:00 AM", "10:00 PM" to a NSDate from the current day. This can be done e.g. with the following method:
- (NSDate *)todaysDateFromAMPMString:(NSString *)time
{
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
[fmt setLocale:[NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"]];
// Get year-month-day for today:
[fmt setDateFormat:#"yyyy-MM-dd "];
NSString *todayString = [fmt stringFromDate:[NSDate date]];
// Append the given time:
NSString *todaysTime = [todayString stringByAppendingString:time];
// Convert date+time string back to NSDate:
[fmt setDateFormat:#"yyyy-MM-dd h:mma"];
NSDate *date = [fmt dateFromString:todaysTime];
return date;
}
Then you can proceed as in https://stackoverflow.com/a/20441330/1187415:
// Some example values:
NSString *strOpenTime = #"10:00 PM";
NSString *strCloseTime = #"2:00 AM";
NSDate *openTime = [self todaysDateFromAMPMString:strOpenTime];
NSDate *closeTime = [self todaysDateFromAMPMString:strCloseTime];
if ([closeTime compare:openTime] != NSOrderedDescending) {
// closeTime is less than or equal to openTime, so add one day:
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *comp = [[NSDateComponents alloc] init];
[comp setDay:1];
closeTime = [cal dateByAddingComponents:comp toDate:closeTime options:0];
}
NSDate *now = [NSDate date];
if ([now compare:openTime] != NSOrderedAscending &&
[now compare:closeTime] != NSOrderedDescending) {
// Shop is OPEN
} else {
// Shop is CLOSED
}
This is an app design question, not a coding question. You need to define a clear vocabulary for the user to communicate what they mean. I would suggest adding a UISwitch to the screen, with 2 positions on it: "Today" and "Tomorrow". You can add some program logic that takes a guess as to times where you think the user is talking about a date tomorrow, and set the default switch to the "tomorrow" state in that case, but the user should be able to tell you what they mean.
How about you just add a check whether all the three NSDate are having the same date (DDMMYYYY) value?
This question already has answers here:
NSDate between two given NSDates
(3 answers)
Closed 9 years ago.
Current date should not go before start date and after end date but it can be equal to start date or end date.
How should i modify the code?
for(AllBookings *book in bookarray)
{
NSString *startdte = book.StartDate; //taking start date from array
NSString *enddte = book.EndDate;
NSDate *start = [self getDateFromJSON:startdte];
NSDate *end = [self getDateFromJSON:enddte];
NSDate *now = [NSDate date];
NSTimeInterval fromTime = [start timeIntervalSinceReferenceDate];
NSTimeInterval toTime = [end timeIntervalSinceReferenceDate];
NSTimeInterval currTime = [[NSDate date] timeIntervalSinceReferenceDate];
if((fromTime<currTime) && (toTime>=currTime))//checking if currnt is in btw strt n end
{
success = TRUE;
break;
}
else {
success = FALSE;
}
}
Below is the working code which i am using in my application, i have made changes according to your requirement:
-(void)isSuitableTime{
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"HH:mm"];
NSDate *currentTime = [NSDate date];
NSString *currentTimeString = [df stringFromDate: currentTime];
NSDate *gpsTimeCurrent= [df dateFromString:currentTimeString];
NSDate *gpsTimeFrom = [df dateFromString:#"09:00" ];
NSDate *gpsTimeTo = [df dateFromString:#"17:00"];
NSTimeInterval intervalFromTimeToCurrent =
[gpsTimeCurrent timeIntervalSinceDate:gpsTimeFrom];
NSTimeInterval intervalCurrentToTimeTo =
[gpsTimeTo timeIntervalSinceDate:gpsTimeCurrent];
NSLog(#"intervalToTimeToCurrent is %f",intervalCurrentToTimeTo);
if ((intervalFromTimeToCurrent>0) && (intervalCurrentToTimeTo >0)) {
NSLog(#"In my time range");
}
else {
NSLog(#"Out of my time range");
}
}
Use this method mate
- (BOOL)isDate:(NSDate *)date inRangeFirstDate:(NSDate *)firstDate lastDate:(NSDate *)lastDate {
return [date compare:firstDate] == NSOrderedDescending && [date compare:lastDate] == NSOrderedAscending;
}
use the NSDate's compare: method instead of if (current > fromTime)
From the class reference:
If:
The receiver and anotherDate are exactly equal to each other, NSOrderedSame.
The receiver is later in time than anotherDate, NSOrderedDescending.
The receiver is earlier in time than anotherDate, NSOrderedAscending.
you can use
if([current compare: From] == NSOrderedDescending||NSOrderedSame
&& [current compare: Totime]== NSOrderedAescending||NSOrderedSame)
{
// Current is between to and From
}