i want to get all the dates from yesterday date to one month..
like today is 19 may, so i need all the date from 18 may to 18 April.
please help.
You can use this code.It works.
NSDate *currentDate = [NSDate date];
NSLog(#"Current Date = %#", currentDate);
NSDateComponents *dateComponents = [NSDateComponents new];
dateComponents.month = -1;
NSDate *currentDatePlus1Month = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:currentDate options:0];
NSLog(#"Date = %#", currentDatePlus1Month );
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents *days = [[NSDateComponents alloc] init];
NSMutableArray* arr =[[NSMutableArray alloc]init];
NSInteger dayCount = 0;
while ( TRUE ) {
[days setDay: ++dayCount];
NSDate *date = [gregorianCalendar dateByAddingComponents: days toDate: currentDatePlus1Month options: 0];
if ( [date compare: currentDate] == NSOrderedAscending ){
[arr addObject:date];
}
if([[arr lastObject] isEqual:[currentDate dateByAddingTimeInterval:-60*60*24*1]])
{
NSLog(#"%lu",(unsigned long)arr.count);
break;
}
// Do something with date like add it to an array, etc.
}
if you find all dates you can remove count and get all dates in array.
To achieve this, I think you should have an Array holding all those dates. I'll write pseudocode about the logic here.
INIT dateArray
NSDate pastDate = (today).yesterday
NSDate lastMonth = pastDate.lastMonth()
WHILE pastDate > lastMonth // pastDate is after lastMonth
dateArray.add(pastDate)
pastDate = pastDate.yesterday
END WHILE
About how to turn this pseudocode into real code is another story (this would be quite long). Hope this help.
PS: If you'd like Objective-C solution, please comment. I'll take my time write it for you ;)
Related
I want to create an array of NSDates starting from today to next month. This can easily be done in Ruby using Time.now..(Time.now + 30.days)
How can I create an array of dates just like in Ruby in Objective C?
Any ObjC solution is unfortunately going to be far more verbose than that Ruby code.
The correct way to make the calculation is with NSDateComponents:
NSMutableArray * dateArray = [NSMutableArray array];
NSCalendar * cal = [NSCalendar currentCalendar];
NSDateComponents * plusDays = [NSDateComponents new];
NSDate * now = [NSDate date];
for( NSUInteger day = 0; day < NUMDAYS; day++ ){
[plusDays setDay:day];
[dateArray addObject:[cal dateByAddingComponents:plusDays toDate:now options:0]];
}
To make the procedure more convenient (if you need to do it more than a few times), you could put this loop into a category method on NSCalendar, with NUMDAYS replaced with the argument and substituting self for cal.
There's nothing built in to do this quite as concisely as the Ruby you've posted. Breaking the problem down, you need a way to get the day after a particular date. Here's a function that will do that:
NSDate *CalendarDayAfterDate(NSDate *date)
{
NSDateComponents *components = [[NSDateComponents alloc] init];
components.day = 1;
NSCalendar *calendar = [NSCalendar currentCalendar];
return [calendar dateByAddingComponents:components toDate:date options:0];
}
Next, you need to get an array of days one after the other:
NSDate *today = [NSDate date];
NSMutableArray *dates = [NSMutableArray arrayWithObject:today];
for (NSUInteger i=0; i<30; i++) {
NSDate *tomorrow = CalendarDayAfterDate(today);
[dates addObject:tomorrow];
today = tomorrow;
}
After much downvoting and commenting, here's my REVISED answer...
-(NSDate *)nextDayFromDate:(NSDate *)originalDate {
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *dateComponent = [NSDateComponents new];
dateComponent.day = 1;
NSDate *tomorrow = [calendar dateByAddingComponents:dateComponent toDate:originalDate options:0];
return tomorrow;
}
NSMutableArray *dateArray = [NSMutableArray array];
NSDate *now = [NSDate date];
[dateArray addObject:now];
for (int i=0;i<31;i++) {
NSDate *firstDate = [dateArray objectAtIndex:i];
NSDate *newDate = [self nextDayFromDate:firstDate];
[dateArray addObject:newDate];
}
What this does is use the NSCalendar API to add a "day interval" to any given NSDate. Add "Now" to the array, then do a loop 30 times, each time using the previous NSDate object as input to the logic.
I've read all the questions and answer and all the tutorial about this subject, but for some reason it's not working for me. always showing me that the two dates are the same date!
Please some one help me to figure it out, I just want to check if one is bigger than the other (including date and time - without seconds) or if they are equal.
This is my code:
- (BOOL)isEndDateIsBiggerThanCurrectDate:(NSDate *)checkEndDate
{
NSString *endd = [NSDateFormatter localizedStringFromDate:checkEndDate
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterShortStyle];
NSString *curreeeent = [NSDateFormatter localizedStringFromDate:[NSDate date]
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterShortStyle];
NSDateFormatter * df = [[NSDateFormatter alloc]init];;
NSDate * newCurrent = [df dateFromString:endd];
NSDate * newEnd = [df dateFromString:curreeeent];
switch ([newCurrent compare:newEnd])
{
case NSOrderedAscending:
return YES;
break;
case NSOrderedSame:
return NO;
break;
case NSOrderedDescending:
return NO;
break;
}
}
Thank you very much!
For this, you have to use NSCalender.
NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger desiredComponents = (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit);
NSDateComponents *firstComponents = [calendar components:desiredComponents fromDate:[NSDate date]];
NSDateComponents *secondComponents = [calendar components:desiredComponents fromDate: checkEndDate];
NSDate *first = [calendar dateFromComponents:firstComponents];
NSDate *second = [calendar dateFromComponents:secondComponents];
NSComparisonResult result = [first compare:second];
if (result == NSOrderedAscending) {
//checkEndDate is before now
} else if (result == NSOrderedDescending) {
//checkEndDate is after now
} else {
//both are same
}
You should really be using time intervals rather than converting between dates and strings.
Something like the following should suit your needs:
//current time
NSDate *now = [NSDate date];
//time in the future
NSDate *distantFuture = [NSDate distantFuture];
//gather time interval
if([now timeIntervalSinceDate:distantFuture] > 0)
{
//huzzah!
}
I've got the answer, just checking the exact time between two dates and compare it.
- (BOOL)isEndDateIsSmallerThanCurrent:(NSDate *)checkEndDate
{
NSDate* enddate = checkEndDate;
NSDate* currentdate = [NSDate date];
NSTimeInterval distanceBetweenDates = [enddate timeIntervalSinceDate:currentdate];
double secondsInMinute = 60;
NSInteger secondsBetweenDates = distanceBetweenDates / secondsInMinute;
if (secondsBetweenDates == 0)
return YES;
else if (secondsBetweenDates < 0)
return YES;
else
return NO;
}
Why don't you change the dates into time interval since 1970 and sort by that. Extremely simple number compare, much quicker than string compare, and they will always sort correct, not like 1,10,11,2,21,22,3,....
NSDate *now = [NSDate date];
NSTimeInterval ti = [now timeIntervalSince1970];
Thats it. No new object creations, much quicker and much less taxing on the cpu.
See here how you get rid of seconds, but it is easy because you have numbers, for seconds. See here How to set seconds to zero for NSDate
I want to create a array of range which contains days betweens a specific start and end date.
For example, I have a start date with 1 January 2012 and and an end date with 7 January 2012. The array or range should contain a collection of NSDate objects (7 in total).
How do I do this?
NSCalendar is helpful here, since it knows the calendar related to the dates. So, by using the following (assuming you have startDate and endData and that you want to include both in the list), you can iterate through the dates, adding a single day (NSCalendar will take care of wrapping the months and leap year, etc).
NSMutableArray *dateList = [NSMutableArray array];
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:1];
[dateList addObject: startDate];
NSDate *currentDate = startDate;
// add one the first time through, so that we can use NSOrderedAscending (prevents millisecond infinite loop)
currentDate = [currentCalendar dateByAddingComponents:comps toDate:currentDate options:0];
while ( [endDate compare: currentDate] != NSOrderedAscending) {
[dateList addObject: currentDate];
currentDate = [currentCalendar dateByAddingComponents:comps toDate:currentDate options:0];
}
[comps release];
Just create them and add them to an array...
NSMutableArray *arr = [NSMutableArray array];
NSDateComponents *comps = [[[NSDateComponents alloc] init] autorelease];
[comps setMonth:1];
[comps setYear:2012];
for(int i=1;i<=7;i++) {
[comps setDay:i];
[arr addObject:[[NSCalendar currentCalendar] dateFromComponents:comps]];
}
From Apple doc:
To compute a sequence of dates, use the enumerateDatesStartingAfterDate:matchingComponents:options:usingBlock: method instead of calling this method (
- nextDateAfterDate:matchingComponents:options:
) in a loop with the previous loop iteration's result.
As I got, it will iterate all dates that matched with "matchingComponents" till you finish iteration with "stop.memory = true"
let calendar = NSCalendar.currentCalendar()
let startDate = calendar.startOfDayForDate(NSDate())
let finishDate = calendar.dateByAddingUnit(.Day, value: 10, toDate: startDate, options: [])
let dayComponent = NSDateComponents()
dayComponent.hour = 1
calendar.enumerateDatesStartingAfterDate(startDate, matchingComponents: dayComponent, options: [.MatchStrictly]) { (date, exactMatch, stop) in
print(date)
if date!.compare(finishDate!) == NSComparisonResult.OrderedDescending {
// .memory gets at the value of an UnsafeMutablePointer
stop.memory = true
}
}
I'm trying get only the Saturdays and Sundays between two dates, but I don't know why get me free days on a week.
Here is my code:
- (BOOL)checkForWeekend:(NSDate *)aDate {
BOOL isWeekendDate = NO;
NSCalendar *calendar = [NSCalendar currentCalendar];
NSRange weekdayRange = [calendar maximumRangeOfUnit:NSWeekdayCalendarUnit];
NSDateComponents *components = [calendar components:NSWeekdayCalendarUnit fromDate:aDate];
NSUInteger weekdayOfDate = [components weekday];
if (weekdayOfDate == weekdayRange.location || weekdayOfDate == weekdayRange.length) {
// The date falls somewhere on the first or last days of the week.
isWeekendDate = YES;
}
return isWeekendDate;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSString *strDateIni = [NSString stringWithString:#"28-01-2012"];
NSString *strDateEnd = [NSString stringWithString:#"31-01-2012"];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"dd-MM-yyyy"];
NSDate *startDate = [df dateFromString:strDateIni];
NSDate *endDate = [df dateFromString:strDateEnd];
unsigned int unitFlags = NSMonthCalendarUnit | NSDayCalendarUnit;
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [gregorian components:unitFlags fromDate:startDate toDate:endDate options:0];
// int months = [comps month];
int days = [comps day];
for (int i=0; i<days; i++)
{
NSTimeInterval interval = i;
NSDate * futureDate = [startDate dateByAddingTimeInterval:interval];
BOOL isWeekend = [self checkForWeekend:futureDate]; // Any date can be passed here.
if (isWeekend) {
NSLog(#"Weekend date! Yay!");
}
else
{
NSLog(#"Not is Weekend");
}
}
}
The problem:
The issue was caused by NSTimeInterval interval = i; The logic of the for loop was to iterate by days. Setting the time interval to i was iterating by seconds.
From documentation on NSTimeInterval
NSTimeInterval is always specified in seconds;
The answer:
Changing the NSTimeInterval line to
NSTimeInterval interval = i*24*60*60;
Here is a link to another answer I posted on SO (shameless, I know). It has some code that may help you with dates in the future. The methods are implemented as categories of NSDate, meaning they become methods of NSDate.
There are several functions there that help with weekends. But these two might be most helpful:
- (NSDate*) theFollowingWeekend;
- (NSDate *) thePreviousWeekend;
They return the date of the weekend following and prior to the receiver (self).
Generally, you should not use the notion that a day is 86400 seconds, and should use NSDateComponents and NSCalendar. This works even when daylight savings time transitions occur between dates. Like this:
- (NSDate *) dateByAddingDays:(NSInteger) numberOfDays {
NSDateComponents *dayComponent = [[NSDateComponents alloc] init];
dayComponent.day = numberOfDays;
NSCalendar *theCalendar = [NSCalendar currentCalendar];
return [theCalendar dateByAddingComponents:dayComponent toDate:self options:0];
}
One very important thing to remember is that one day is not (necessarily) equal to 24*60*60 seconds. And you should not do date arithmetic yourself
What you really need to do might seem a little tedious but this is the correct thing to do: use NSCalendar and – dateByAddingComponents:toDate:options:
See Calendrical Calculations guide.
I have two dates: 2009-05-11 and the current date. I want to check whether the given date is the current date or not. How is this possible.
Cocoa has couple of methods for this:
in NSDate
– isEqualToDate:
– earlierDate:
– laterDate:
– compare:
When you use - (NSComparisonResult)compare:(NSDate *)anotherDate ,you get back one of these:
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.
example:
NSDate * now = [NSDate date];
NSDate * mile = [[NSDate alloc] initWithString:#"2001-03-24 10:45:32 +0600"];
NSComparisonResult result = [now compare:mile];
NSLog(#"%#", now);
NSLog(#"%#", mile);
switch (result)
{
case NSOrderedAscending: NSLog(#"%# is in future from %#", mile, now); break;
case NSOrderedDescending: NSLog(#"%# is in past from %#", mile, now); break;
case NSOrderedSame: NSLog(#"%# is the same as %#", mile, now); break;
default: NSLog(#"erorr dates %#, %#", mile, now); break;
}
[mile release];
Here buddy. This function will match your date with any specific date and will be able to tell whether they match or not. You can also modify the components to match your requirements.
- (BOOL)isSameDay:(NSDate*)date1 otherDay:(NSDate*)date2 {
NSCalendar* calendar = [NSCalendar currentCalendar];
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents* comp1 = [calendar components:unitFlags fromDate:date1];
NSDateComponents* comp2 = [calendar components:unitFlags fromDate:date2];
return [comp1 day] == [comp2 day] &&
[comp1 month] == [comp2 month] &&
[comp1 year] == [comp2 year];}
Regards,
Naveed Butt
NSDate *today = [NSDate date]; // it will give you current date
NSDate *newDate = [NSDate dateWithString:#"xxxxxx"]; // your date
NSComparisonResult result;
//has three possible values: NSOrderedSame,NSOrderedDescending, NSOrderedAscending
result = [today compare:newDate]; // comparing two dates
if(result==NSOrderedAscending)
NSLog(#"today is less");
else if(result==NSOrderedDescending)
NSLog(#"newDate is less");
else
NSLog(#"Both dates are same");
There are other ways that you may use to compare an NSDate objects. Each of the
methods will be more efficient at certain tasks. I have chosen the compare method
because it will handle most of your basic date comparison needs.
This category offers a neat way to compare NSDates:
#import <Foundation/Foundation.h>
#interface NSDate (Compare)
-(BOOL) isLaterThanOrEqualTo:(NSDate*)date;
-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date;
-(BOOL) isLaterThan:(NSDate*)date;
-(BOOL) isEarlierThan:(NSDate*)date;
//- (BOOL)isEqualToDate:(NSDate *)date; already part of the NSDate API
#end
And the implementation:
#import "NSDate+Compare.h"
#implementation NSDate (Compare)
-(BOOL) isLaterThanOrEqualTo:(NSDate*)date {
return !([self compare:date] == NSOrderedAscending);
}
-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date {
return !([self compare:date] == NSOrderedDescending);
}
-(BOOL) isLaterThan:(NSDate*)date {
return ([self compare:date] == NSOrderedDescending);
}
-(BOOL) isEarlierThan:(NSDate*)date {
return ([self compare:date] == NSOrderedAscending);
}
#end
Simple to use:
if([aDateYouWantToCompare isEarlierThanOrEqualTo:[NSDate date]]) // [NSDate date] is now
{
// do your thing ...
}
If you make both dates NSDates you can use NSDate's compare: method:
NSComparisonResult result = [Date2 compare:Date1];
if(result==NSOrderedAscending)
NSLog(#"Date1 is in the future");
else if(result==NSOrderedDescending)
NSLog(#"Date1 is in the past");
else
NSLog(#"Both dates are the same");
You can take a look at the docs here.
By this method also you can compare two dates
NSDate * dateOne = [NSDate date];
NSDate * dateTwo = [NSDate date];
if([dateOne compare:dateTwo] == NSOrderedAscending)
{
}
The best way I found was to check the difference between the given date and today:
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* now = [NSDate date];
int differenceInDays =
[calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:date] -
[calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:now];
According to Listing 13 of Calendrical Calculations in Apple's Date and Time Programming Guide [NSCalendar ordinalityOfUnit:NSDayCalendarUnit inUnit: NSEraCalendarUnit forDate:myDate] gives you the number of midnights since the start of the era.
This way it's easy to check whether the date is yesterday, today, or tomorrow.
switch (differenceInDays) {
case -1:
dayString = #"Yesterday";
break;
case 0:
dayString = #"Today";
break;
case 1:
dayString = #"Tomorrow";
break;
default: {
NSDateFormatter* dayFormatter = [[NSDateFormatter alloc] init];
[dayFormatter setLocale:usLocale];
[dayFormatter setDateFormat:#"dd MMM"];
dayString = [dayFormatter stringFromDate: date];
break;
}
}
NSDateFormatter *df= [[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd"];
NSDate *dt1 = [[NSDate alloc] init];
NSDate *dt2 = [[NSDate alloc] init];
dt1=[df dateFromString:#"2011-02-25"];
dt2=[df dateFromString:#"2011-03-25"];
NSComparisonResult result = [dt1 compare:dt2];
switch (result)
{
case NSOrderedAscending: NSLog(#"%# is greater than %#", dt2, dt1); break;
case NSOrderedDescending: NSLog(#"%# is less %#", dt2, dt1); break;
case NSOrderedSame: NSLog(#"%# is equal to %#", dt2, dt1); break;
default: NSLog(#"erorr dates %#, %#", dt2, dt1); break;
}
Enjoy coding......
In Cocoa, to compare dates, use one of isEqualToDate, compare, laterDate, and earlierDate methods on NSDate objects, instantiated with the dates you need.
Documentation:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/isEqualToDate:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/earlierDate:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/laterDate:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/compare:
What you really need is to compare two objects of the same kind.
Create an NSDate out of your string date (#"2009-05-11") :
http://blog.evandavey.com/2008/12/how-to-convert-a-string-to-nsdate.html
If the current date is a string too, make it an NSDate. If its already an NSDate, leave it.
Here's the Swift variant on Pascal's answer:
extension NSDate {
func isLaterThanOrEqualTo(date:NSDate) -> Bool {
return !(self.compare(date) == NSComparisonResult.OrderedAscending)
}
func isEarlierThanOrEqualTo(date:NSDate) -> Bool {
return !(self.compare(date) == NSComparisonResult.OrderedDescending)
}
func isLaterThan(date:NSDate) -> Bool {
return (self.compare(date) == NSComparisonResult.OrderedDescending)
}
func isEarlierThan(date:NSDate) -> Bool {
return (self.compare(date) == NSComparisonResult.OrderedAscending)
}
}
Which can be used as:
self.expireDate.isEarlierThanOrEqualTo(NSDate())
Here's the function from Naveed Rafi's answer converted to Swift if anyone else is looking for it:
func isSameDate(#date1: NSDate, date2: NSDate) -> Bool {
let calendar = NSCalendar()
let date1comp = calendar.components(.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit, fromDate: date1)
let date2comp = calendar.components(.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit, fromDate: date2)
return (date1comp.year == date2comp.year) && (date1comp.month == date2comp.month) && (date1comp.day == date2comp.day)
}
Get Today's Date:
NSDate* date = [NSDate date];
Create a Date From Scratch:
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.year = 2015;
comps.month = 12;
comps.day = 31;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* date = [calendar dateFromComponents:comps];
Add a day to a Date:
NSDate* date = [NSDate date];
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.day = 1;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* tomorrow = [calendar dateByAddingComponents:comps toDate:date options:nil];
Subtract a day from a Date:
NSDate* date = [NSDate date];
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.day = -1;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* yesterday = [calendar dateByAddingComponents:comps toDate:date options:nil];
Convert a Date to a String:
NSDate* date = [NSDate date];
NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = #"MMMM dd, yyyy";
NSString* dateString = [formatter stringFromDate:date];
Convert a String to a Date:
NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = #"MMMM dd, yyyy";
NSDate* date = [formatter dateFromString:#"August 02, 2014"];
Find how many days are in a month:
NSDate* date = [NSDate date];
NSCalendar* cal = [NSCalendar currentCalendar];
NSRange currentRange = [cal rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date];
NSInteger numberOfDays = currentRange.length;
Calculate how much time something took:
NSDate* start = [NSDate date];
for(int i = 0; i < 1000000000; i++);
NSDate* end = [NSDate date];
NSTimeInterval duration = [end timeIntervalSinceDate:start];
Find the Day Of Week for a specific Date:
NSDate* date = [NSDate date];
NSCalendar* cal = [NSCalendar currentCalendar];
NSInteger dow = [cal ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:date];
Then use NSComparisonResult to compare date.
..
NSString *date = #"2009-05-11"
NSString *nowDate = [[[NSDate date]description]substringToIndex: 10];
if([date isEqualToString: nowDate])
{
// your code
}