I'm either a bit overwhelmed by the complexity of NSDate or I simply don't understand the concept of it :)
The only thing I want to do is to create an NSDate Instance representing today's date and a fixed time of 20.00h respectively 8pm.
This can't be as difficult as creating an instance holding the current time and afterwards either subtracting oder adding the neccessary difference to 8pm, can it?
Thanks for your help...
the ultranoob
Use NSCalendar:
NSCalendar* myCalendar = [NSCalendar currentCalendar];
NSDateComponents* components = [myCalendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit
fromDate:[NSDate date]];
[components setHour: 20];
[components setMinute: 0];
[components setSecond: 0];
NSDate *myDate = [myCalendar dateFromComponents:components];
Related
I am building up a date using NSDateComponents from the following string:
"2014-05-17 02:39:00 PM +0000"
When I set all the components and return an NSDate I am getting (see method below):
"2014-05-17 02:39:00 AM +0000"
My question is, is there a way to specify the AM/PM to NSDateComponent, or do I just have to add 12 to my hour if the source date is PM?
- (NSDate *)dateFromYear:(int)year month:(int)month day:(int)day hour:(int)hour minute:(int)minute {
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
[components setYear:year];
[components setMonth:month];
[components setDay:day];
[components setHour:hour];
[components setMinute:minute];
NSCalendar *calendar = [NSCalendar currentCalendar];
return [calendar dateFromComponents:components];
}
Apparently, NSDateComponents doesn't seem to specify this.
Apple's own docs on it says this:
Important: An NSDateComponents object is meaningless in itself; you
need to know what calendar it is interpreted against, and you need to
know whether the values are absolute values of the units, or
quantities of the units.
Apart from your 12 hours logic, you can alternately use NSDate class dateWithNaturalLanguageString that uses AM/PM and make use it somehow for your purpose.
i have an array of NSManagedObject take from my core data, and i want filter the array with the date that is >= of today, so i do this:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(firstAired >= %#)", [NSDate date]];
but find me only the date > of today, and the date of today don't, why?
You should create Midnight date,like this, and pass it to the predicate
NSDateComponents *currentComponents = [[NSCalendar currentCalendar]components:NSMinuteCalendarUnit|NSHourCalendarUnit|NSSecondCalendarUnit fromDate:[NSDate date]];
[currentComponents setMinute:0];
[currentComponents setHour:0];
[currentComponents setSecond:0];
NSCalendar *calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *dateToCheck = [calendar dateFromComponents:currentComponents];
NSDate *now = [NSDate date];
NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
calendar.timeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:now];
[components setHour:00];
NSDate *today = [calendar dateFromComponents:components];
in this way works, thanks to all...
[NSDate date] is the current time. So this predicate will fetch only records where firstAired is later today or later, and not earlier today. Construct an NSDate with the time 00:00:00.
Because [NSDate date] returns the exact date with hour, minute, second .... of the instant when it is executed. If you want to search for every "today" item then you have to change [NSDate date] with a NSDate object for today at midnight. That is, extract the date components from NSDate.date and then, using the components year, month and day build a new date object with hour: 00:00AM.
This should be really simple!
I have a shop, it opens at 8:30 and closes at 17:00. I want my app to say the shops current open or currently closed.
Whats the best way to store my open_time and close_time? Store them as seconds since the start of the day, i.e. 30600 and 63000?
This make sense, but how do I get the current time right now, in seconds since the begining of today, so I can check if current_time is between open_time and close_time, i.e. open!!
Thanks in advance!
This problem isn't quite as trivial as you may think. You have to work with dates very carefully. The best solution is to store all of your open and close times as dates. Here is some code for creating your open/close times and comparing them:
NSDate * now = [NSDate date];
NSCalendar * calendar = [NSCalendar currentCalendar];
NSDateComponents * comps = [calendar components:~(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:now];
[comps setHour:8];
[comps setMinute:30];
NSDate * open = [calendar dateFromComponents:comps];
[comps setHour:17];
[comps setMinute:0];
NSDate * close = [calendar dateFromComponents:comps];
if ([now compare:open] == NSOrderedDescending && [now compare:close] == NSOrderedAscending) {
// The date is within the shop's hours.
}
else {
// The date is not within the shop's hours.
}
Here's what I did:
Grab the current date.
Get the components of the date, except hours, minutes, and seconds.
Set the hour and minutes.
Create an open time.
Repeat steps 3-4 for close time.
Compare open and close times to now.
If you ever need to do any modification of dates, you should always use NSCalendar and NSDateComponents. Check out this answer for why it's so important.
I think a clearer solution would be to use NSDate objects with only hour/minute components present.
Basically, somewhere in your app you need to store the shop's open/close times as such:
NSCalendar *calendar = [[NSCalendar alloc]
initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents *openTime = [[NSDateComponents alloc] init];
[openTime setHour: 12];
[openTime setMinute: 30];
NSDate *openDate = [calendar dateFromComponents: openTime];
[calendar release];
And if you need to see whether the current time is between two such NSDate objects you could have a method like this:
- (BOOL)currentTimeIsInBetween: (NSDate *)date1 andDate: (NSDate *)date2 {
NSCalendar *calendar = [[NSCalendar alloc]
initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents *currentComponents = [calendar components:
(NSMinuteCalendarUnit | NSHourCalendarUnit)
fromDate: [NSDate date]];
NSDate *currentAdjusted = [calendar dateFromComponents: currentComponents];
[calendar release];
if ([currentAdjusted compare: date1] == NSOrderedAscending)
return NO;
if ([currentAdjusted compare: date2] == NSOrderedDescending)
return NO;
return YES;
}
EDIT: Seems like user rbrown was a bit faster than me, we are suggesting the same approach.
You can do something like this.
NSDate *today = // code for getting today date at 0 oclock
NSDate *now = [NSDate date];
double second = [now timeIntervalSinceDate:today];
Now you got time in second since the start of the day for compare.
This question follows on from a previous question...
How do I create the current date (or any date) as an NSDate without hours, minutes and seconds?
I would use this code as follows...
NSDate *todaysDate = [General makeAbsoluteNSDate:[NSDate date]];
My problem is that I have users in different countries and UTC isn't their timezone and the date produced by this function at certain times of the day won't be correct.
How do I get the current time zone to correct my function ?
Or should I be using a different approach ?
Heres the function I've been using...
+ (NSDate *)makeAbsoluteNSDate:(NSDate*)datSource {
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:
NSGregorianCalendar];
[calendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
NSDateComponents *dateComponents = [calendar components:NSYearCalendarUnit |
NSMonthCalendarUnit | NSDayCalendarUnit
fromDate:datSource];
[dateComponents setHour:0];
[dateComponents setMinute:0];
[dateComponents setSecond:0];
NSDate *midnightUTC = [calendar dateFromComponents:dateComponents];
[calendar release];
return midnightUTC;
}
You get the timezone object from this call:
[NSTimeZone localTimeZone]
And you can use the secondsFromGMT method to figure out the difference and create a date with the timezone.
You can even build a Category for NSDate that includes a method to transform a date into the current timezone date, which would be even simpler.
A seemingly simple question...how can I return a list of days for any specified month?
NSDate *today = [NSDate date]; //Get a date object for today's date
NSCalendar *c = [NSCalendar currentCalendar];
NSRange days = [c rangeOfUnit:NSDayCalendarUnit
inUnit:NSMonthCalendarUnit
forDate:today];
I basically want to use that, but replace today with say, the month of January, so I can return all of those days
Carl's answer works on Mac. The following works on Mac or iPhone (no dateWithNaturalLanguageString: available there).
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease];
// Set your year and month here
[components setYear:2015];
[components setMonth:1];
NSDate *date = [calendar dateFromComponents:components];
NSRange range = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date];
NSLog(#"%d", (int)range.length);
You can make your date with pretty much any string:
NSDate *date = [NSDate dateWithNaturalLanguageString:#"January"];
Then the rest of your code will work as-is to give you back the NSRange for the number of days in January.