How to check whether now date is during 9:00-18:00 - ios

When my app is launched I want to check whether the date is between 9:00-18:00.
And I can get the time of now using NSDate. How can I check the time?

So many answers and so many flaws...
You can use NSDateFormatter in order to get an user-friendly string from a date. But it is a very bad idea to use that string for date comparisons!
Please ignore any answer to your question that involves using strings...
If you want to get information about a date's year, month, day, hour, minute, etc., you should use NSCalendar and NSDateComponents.
In order to check whether a date is between 9:00 and 18:00 you can do the following:
NSDate *date = [NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents = [calendar components:NSHourCalendarUnit fromDate:date];
if (dateComponents.hour >= 9 && dateComponents.hour < 18) {
NSLog(#"Date is between 9:00 and 18:00.");
}
EDIT:
Whoops, using dateComponents.hour <= 18 will result in wrong results for dates like 18:01. dateComponents.hour < 18 is the way to go. ;)

Construct dates for 09:00 and 18:00 today and compare the current time with those dates:
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *now = [NSDate date];
NSDateComponents *components = [cal components:NSEraCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:now];
[components setHour:9];
[components setMinute:0];
[components setSecond:0];
NSDate *nineHundred = [cal dateFromComponents:components];
[components setHour:18];
NSDate *eighteenHundred = [cal dateFromComponents:components];
if ([nineHundred compare:now] != NSOrderedDescending &&
[eighteenHundred compare:now] != NSOrderedAscending)
{
NSLog(#"Date is between 09:00 and 18:00");
}

Related

How to check whether a date belongs to this week or not in iOS?

Hello I have a date string like this.11/14/2016. What I want to do is check it whether is it
Today or This week or This month. I can compare today and the month. But how can I check whether this date belongs to "This Week"
Please help me.
Thanks
Given two dates,
NSDate *now = [NSDate date];
NSDate *then = // some other date
Find out if they're in the same week with:
BOOL sameWeek = [[NSCalendar currentCalendar] isDate:then equalToDate:now
toUnitGranularity:NSCalendarUnitWeekOfYear];
That line asks if they're "equal" with a granularity of a week, meaning that they're "equal" if they're in the same week.
Try below code,
- (void)thisWeek:(NSDate *)date
{
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *todaysComponents = [gregorian components:NSCalendarUnitWeekOfYear fromDate:[NSDate date]];
NSUInteger todaysWeek = [todaysComponents weekOfYear];
NSDateComponents *otherComponents = [gregorian components:NSCalendarUnitWeekOfYear fromDate:date];
NSUInteger datesWeek = [otherComponents weekOfYear];
//NSLog(#"Date %#",date);
if(todaysWeek==datesWeek){
NSLog(#"Date is in this week");
}else if(todaysWeek+1==datesWeek){
NSLog(#"Date is in next week");
}
}

NSDate created from NSDateComponents incorrect?

I created an NSDate by dateFromComponents, using NSCalendar with NSGregorianCalendar identifier, here's the strange part:
The date get incorrect if it's before a certain point in time before 1900/12/31
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *components = [[NSDateComponents alloc] init];
components.year = 1900; components.month = 12; components.day = 31;
NSDate *date = [calendar dateFromComponents:components];
components.year = 1901; components.month = 1; components.day = 1;
NSDate *date2 = [calendar dateFromComponents:components];
NSLog(#"%#",calendar.timeZone.description);
NSLog(#"%#",date);
NSLog(#"%#",date2);
The log will be:
2016-05-25 14:58:21.014 date[79754:2192157] Asia/Shanghai (GMT+8) offset 28800
2016-05-25 14:58:21.015 date[79754:2192157] 1900-12-30 15:54:17 +0000
2016-05-25 14:58:21.015 date[79754:2192157] 1900-12-31 16:00:00 +0000
As you can see, there is a 5 minutes gap during the day.
However, if I set the timeZone by [NSTimeZone timeZoneForSecondsFromGMT:], even with the same seconds deviation - 28800, it will be normal.
What is the cause of this?
No, the date isn't incorrect. Instead, the NSCalendar code knows things about calendars that you wouldn't dream about, like calendars changing their time offsets at some points in time in the past.
You asked for the Asia/Shanghai calendar to convert two dates, one on the day before they changed their time zone, one on the day after they changed their time zone, and both times are converted correctly. That night everyone in Shanghai had to adjust their watches.
Interesting question. What you are seeing is the effects of a time zone change from Local Mean Time to China Standard Time on 01-01-1901 when the clocks were turned back 05m43s.
More details here.
Try this!!
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setYear:1987];
[components setMonth:3];
[components setDay:17];
[components setHour:14];
[components setMinute:20];
[components setSecond:0];
NSDate *date = [calendar dateFromComponents:components];
Hope this Help:)

Trying to determine if current date is 3 days or less from the end of the month in iOS

I am trying to determine if the current date is in fact three days or less from the end of the month. In other words, if I am in August, then I would like to be alerted if it is the 28,29,30, or 31st. If I am in February, then I would like to be notified when it is the 25,26,27, or 28 (or even 29). In the case of a leap year, I would be alerted from 26th onwards.
My problem is that I am not sure how to perform such a check so that it works for any month. Here is my code that I have thus far:
-(BOOL)monthEndCheck {
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];
NSInteger day = [components day];
NSInteger month = [components month];
NSInteger year = [components year];
if (month is 3 days or less from the end of the month for any month) {
return YES;
} else {
return NO;
}
}
Because there are months with 28, 30, and 31 days, I would like a dynamic solution, rather than creating a whole series of if/else statements for each and every condition. Is there a way to do this?
This is how you get the last day of the month:
NSDate *curDate = [NSDate date];
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* comps = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:curDate]; // Get necessary date components
// set last of month
[comps setMonth:[comps month]+1];
[comps setDay:0];
NSDate *tDateMonth = [calendar dateFromComponents:comps];
NSLog(#"%#", tDateMonth);
Source: Getting the last day of a month
EDIT (another source): How to retrive Last date of month give month as parameter in iphone
Now you can simply count from the current date.
If < 3 do whatever you wanted to do.
Maybe something like this:
NSTimeInterval distanceBetweenDates = [date1 timeIntervalSinceDate:date2];
double timeInSecondsFor3Days = 280000; //Better use NSDateComponents here!
NSInteger hoursBetweenDates = distanceBetweenDates / timeInSecondsFor3Days;
However I did not test that^^
EDIT: Thanks to Aaron. Do NSDateComponents to calculate the time for three days instead!
First you have to compute the start of the current day (i.e. today at 00.00).
Otherwise, the current day will not count as a full day when computing the
difference between today and the start of the next month.
NSDate *now = [NSDate date];
NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *startOfToday;
[cal rangeOfUnit:NSCalendarUnitDay startDate:&startOfToday interval:NULL forDate:now];
Computing the start of the next month can be done with rangeOfUnit:...
(using a "statement expression" to be fancy :)
NSDate *startOfNextMonth = ({
NSDate *startOfThisMonth;
NSTimeInterval lengthOfThisMonth;
[cal rangeOfUnit:NSCalendarUnitMonth startDate:&startOfThisMonth interval:&lengthOfThisMonth forDate:now];
[startOfThisMonth dateByAddingTimeInterval:lengthOfThisMonth];
});
And finally the difference in days:
NSDateComponents *comp = [cal components:NSCalendarUnitDay fromDate:startOfToday toDate:startOfNextMonth options:0];
if (comp.day < 4) {
// ...
}

Comparing two NSDate

I have a UIViewController with 2 buttons: today and yesterday. Every time the client clicked on today it needs to set the property _date for today and the same with yesterday.
The method which I set the property value is the following:
-(IBAction)dateButtonTouched:(id)sender
{
if(![sender isSelected])
{
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *components = [cal components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:[[NSDate alloc] init]];
[components setMinute:-[components minute]];
[components setSecond:-[components second]];
if([sender tag] == YESTERDAY)
{
[components setHour:-24];
_date= [cal dateByAddingComponents:components toDate: [NSDate date] options:0]; //YESTERDAY
}
else
{
NSDate *today = [NSDate date];
[components setHour:0];
_date= [cal dateByAddingComponents:components toDate: today options:0]; //TODAY
}
NSLog(#"user selected date %#",_date);
}
}
in the following method I'm trying to check if _date is today or yesterday:
-(void) viewWillLayoutSubviews
{
NSDateFormatter *dateFormat = [NSDateFormatter new];
[dateFormat setDateFormat:#"MM-dd-YY"];
self.dateLabel.text = [dateFormat stringFromDate:_date];
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *components = [cal components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:[[NSDate alloc] init]];
[components setMinute:-[components minute]];
[components setSecond:-[components second]];
[components setHour:0];
NSDate *today = [cal dateByAddingComponents:components toDate: [NSDate date] options:0]; //TODAY
[components setHour:-24];
NSDate *yesterday = [cal dateByAddingComponents:components toDate: [NSDate date] options:0]; //YESTERDAY
if([_date isEqualToDate:yesterday])
{
//do something
}
else if( [_date isEqualToDate:today])
{
//do something
}
}
The _date is never today or yesterday although if I debug it, print it or compare the description is the same.
An NSDate instance represents a specific moment in time. It is much more specific than "yesterday" or "today". Instead of trying to reset the hours, minutes, and seconds via date components, Maybe you should compare the components you're interested in: day, month, and year. Or you can use a calendar to compare at the component level:
NSDate *today = [NSDate date];
NSDate *someDay; // the date to compare
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *difference = [cal components:NSDayCalendarUnit fromDate:today toDate:someDay options:nil];
if (difference.day == -1) {
// yesterday
} else if (difference.day == 0) {
// today
}
Without knowing exactly what you want to do, it's harder to get more specific.
An NSDate object contains both date and time, encoded as a value that is essentially the number of microseconds since Jan 1 2000.
When you do two successive [NSDate date] operations you will get two different values, if not because the time has actually changed that much between the two then because most computer clock implementations assure that you get distinct values with each access.
NSDate's isEqualToDate function compares all of the bits of the two NSDate objects to see if they are exactly equal. This means that if the two are even a microsecond apart they will not appear to be equal.
If you want to see if two NSDate values are the same day you should either use NSDateFormatter to format them into strings and compare the strings, or use one of the NSDateComponent functions to calculate the number of days between them (several ways to do this).

Comparing 2 dates gives me 1 day less in comparison in IOS

I am trying to compare 2 Dates but in i am getting 1 day less
here is a snippet:
NSDateComponents* dateComponents = [[NSDateComponents alloc] init];
[dateComponents setYear: 2014];
[dateComponents setMonth: 1];
[dateComponents setDay: 31];
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* otherDay = [calendar dateFromComponents: dateComponents];
NSDate * todaydate= [NSDate date];
if ([otherDay compare:todaydate]>= NSOrderedDescending)
{
NSLog(#"In If other Date= %# & Today = %# ", otherDay,todaydate);
}else
{
NSLog(#"I am in else other date= %# and today = %# ",otherDay, todaydate);
}
The Log i am getting is :
I am in else other date= 2014-01-30 18:30:00 +0000 and today = 2014-01-31 08:34:21 +0000
Why it's showing other date = 30th jan 2014 ?
You need to set timezone of NSDateComponents such like,
[dateComponents setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT"]];
Or as trojanfoe's suggestion you can also set timezone of NSCalendar such like,
[calendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT"]];
And To exact compare otherDay to todaydate please see answer of Martin R you need to set
NSDate * todaydate;
[calendar rangeOfUnit:NSDayCalendarUnit startDate:&todaydate interval:NULL forDate:[NSDate date]];
From Martin R's answer this is very useful.
There are two different aspects in your question. First,
NSDateComponents* dateComponents = [[NSDateComponents alloc] init];
[dateComponents setYear: 2014];
[dateComponents setMonth: 1];
[dateComponents setDay: 31];
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* otherDay = [calendar dateFromComponents: dateComponents];
computes otherDay as "2014-01-31 00:00" (in your time zone), and
NSDate *todaydate = [NSDate date];
computes todaydate as the current point in time, which includes the hours, minutes
and seconds, for example "2014-01-31 13:00:00" (in your time zone). Therefore
[otherDay compare:todaydate]
returns NSOrderedAscending: otherDay is earlier than todaydate!
What you probably want is to compute todaydate as the start of the current day
(today at 00:00). This can be done as
NSDate * todaydate;
[calendar rangeOfUnit:NSDayCalendarUnit startDate:&todaydate interval:NULL forDate:[NSDate date]];
And now [otherDay compare:todaydate] returns NSOrderedSame, as you expected.
The other aspect is the NSLog output. Printing a NSDate with NSLog()
prints the date according to GMT, and "2014-01-31 00:00" in your time zone is
exactly the same time as "2014-01-30 18:30:00 +0000" in GMT.
The output is correct, it just uses GMT instead of your local timezone for display.

Resources