I have array which is like as below
_combinedBirthdates(
"03/12/2013",
"03/12/2013",
"08/13/1990",
"12/09/1989",
"02/06",
"09/08",
"03/02/1990",
"08/22/1989",
"03/02",
"05/13",
"10/16",
"07/08",
"08/31/1990",
"04/14/1992",
"12/15/1905",
"08/14/1989",
"10/07/1987",
"07/25",
"07/17/1989",
"03/24/1987",
"07/28/1988",
"01/21/1990",
"10/13"
)
all elements are NSString in above NSArray.
How can I make another array which contains number of days remain for particular date
something like this
_newlymadeArray(
"125",
"200",
"50",
"500",
"125",
and so on
)
Use this algorithm:
Obtain the current year
Convert each date from your array to a date in the current year. For example, "03/02/1990" becomes "03/02/2013"
If the date from the step 2 is before the current date, advance its year by one (i.e. "03/02/2013" becomes "03/02/2014")
Using a technique from this question, find the number of days till the date from step 3. It will be less than the number of days in a year.
unsigned int unitFlags = NSDayCalendarUnit;
NSCalendar *currCalendar = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterShortStyle];
NSMutableArray * _newlymadeArray = [[NSMutableArray alloc] init];
for (NSString * str in _combinedBirthdates){
NSDate * toDate = [dateFormatter dateFromString:str];
NSDateComponents *daysInfo = [currCalendar components:unitFlags fromDate:[NSDate date] toDate:toDate options:0];
int days = [daysInfo day];
[_newlymadeArray addObject:[NSString stringWithFormat:#"%d",days]];
}
You need to iterate through the first array and get the date in NSDate and use the info to get the difference in days from the current date to the next date in the array.
You will have to add the necessary checks and this is untested code.
Try this code snap.
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setTimeZone:[NSTimeZone localTimeZone]];
[formatter setDateFormat:#"MM/dd/yyyy"];
NSDate *currentDate = [formatter dateFromString:#"03/12/2013"];
NSTimeInterval srcInterval = [currentDate timeIntervalSince1970];
NSArray *_combinedBirthdates = #[#"03/15/2013", #"05/15/2013"];
NSMutableArray *_newlymadeArray = [NSMutableArray array];
const NSInteger SECONDS_PER_DAY = 60 * 60 * 24;
for (NSString *one in _combinedBirthdates) {
NSDate *destDate = [formatter dateFromString:one];
NSTimeInterval destInterval = [destDate timeIntervalSince1970];
NSInteger diff = (destInterval - srcInterval) / SECONDS_PER_DAY;
[_newlymadeArray addObject:[NSString stringWithFormat:#"%d", diff]];
}
That's it! :)
Related
This question already has answers here:
Comparing the time of two NSDates, ignoring the date component
(3 answers)
Closed 8 years ago.
I have object Item and it has only two NSDate properties.
From those properties only important part for me is time.
If it is possible this doesn't have to be NSDate it can be NSString with just a #"14:30" and #"17:30".
I have 10 objects with different times and they are in NSMutableArray.
I need to sort all those objects to load them in table.
I have tried something but no luck (actually this code works for one property) with two properties:
NSDate *now = [NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:now];
[components setHour:12];
NSDate *todayA = [calendar dateFromComponents:components];
[components setHour:11];
NSDate *todayB = [calendar dateFromComponents:components];
[components setHour:10];
NSDate *todayC = [calendar dateFromComponents:components];
Item* i1 = [[Item alloc] init];
i1.DateTimeA = todayA;
Item* i2 = [[Item alloc] init];
i2.DateTimeA = todayB;
Item* i3 = [[Item alloc] init];
i3.DateTimeA = todayC;
[array addObject:i1];
[array addObject:i2];
[array addObject:i3];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"DateTimeA" ascending:NO];
NSArray *orderedArray = [array sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
As I said Item DateTimeA and DateTimeB doesn't have to be NSDate they can be only strings but I must be able to sort by those two properties.
Is there any solution for this?
Try that:
array = [array sortedArrayUsingComparator:^(Item *i1, Item *i2) {
NSDateFormatter* df1 = [[NSDateFormatter alloc] init];
[df1 setDateFormat:#"d/LLL/yy"]; // <-- make sure it match your date format
NSDate* date1 = [df1 dateFromString:i1.DateTimeA];
NSDate* date2 = [df1 dateFromString:i2.DateTimeA];
return [date2 compare:date1];
}];
This is just example but you can customize it to match your requirements.
In this example I assume that DateTimeA is always NSString but you should cheek it first and if it's NSDate you can omit formatting bit.
For example:
if ([i1.DateTimeA isKindOfClass:[NSDate class]])
NSDate* date1 = i1.DateTimeA;
if ([i2.DateTimeA isKindOfClass:[NSDate class]])
NSDate* date2 = i2.DateTimeA;
return [date2 compare:date1];
This should the trick
NSArray *sortedArray = [array sortedArrayUsingComparator:^(Item *i1, Item *i2) {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"HHmmss"];
NSDate* date1A = [dateFormatter dateFromString:[dateFormatter stringFromDate:i1.DateTimeA]];
NSDate* date2A = [dateFormatter dateFromString:[dateFormatter stringFromDate:i2.DateTimeA]];
NSDate* date1B = [dateFormatter dateFromString:[dateFormatter stringFromDate:i1.DateTimeB]];
NSDate* date2B = [dateFormatter dateFromString:[dateFormatter stringFromDate:i2.DateTimeB]];
switch ([date1A compare:date2A]) {
case NSOrderedSame:
return [date1B compare:date2B];
break;
default:
return [date1A compare:date2A];
break;
}
}];
It's not very pretty but it'll do what you want, note that you won't need to this if you have let's say DateTimeA and DateTimeB stored as string in a format like HH:mm or whatever, you'll need only to do:
[dateFormatter dateFromString:DateTimeA];
One more thing avoid starting your iVars and properties names with an upper case letter that's really confusing.
Hope this helps.
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);
I want to get day parts from a date interval.
For example I have a date interval 21/12/2013 to 28/12/2013.
Now I want to get all day part from this interval like as 21,22,23,24,25,26,27,28.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
[dateFormatter setTimeZone:gmt];
[dateFormatter setDateFormat:#"MMM dd, yyyy"];
NSString *date_str=[NSString stringWithFormat:#"%#",from_date];
NSLog(#"%#",date_str);
NSString *date_str1=[NSString stringWithFormat:#"%#",to_date];
NSLog(#"%#",date_str1);
NSDate *starting_date = [dateFormatter dateFromString:date_str];
NSDate *end_date = [dateFormatter dateFromString:date_str1];
NSCalendar *gregorian = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger unitFlags = NSDayCalendarUnit;
NSDateComponents *components = [gregorian components:unitFlags fromDate:starting_date toDate:end_date options:0];
NSInteger days = [components day];
That code giving total no of days.
How can i get this output?
Thanks
Continuing from your code and assuming,
NSString *date_str=[NSString stringWithFormat:#"%#",#"December 21, 2013"];
NSString *date_str1=[NSString stringWithFormat:#"%#",#"December 28, 2013"];
If you need it within the same month, it can be in this way,
NSDateComponents *component1 = [gregorian components:unitFlags fromDate:starting_date];
NSDateComponents *component2 = [gregorian components:unitFlags fromDate:end_date];
for (int i = component1.day; i <= component2.day; i++) {
NSLog(#"%i", i);
}
But if your dates expand between different months, then you have to add checking for month components in the loop.
I will continue on your code, with some dirty code of mine, but it gets the job done if what you provided is your date format:
NSArray *begining_day = [date_str componentsSeparatedByString:#"/"];
NSMutableArray *part_days = [[NSMutableArray alloc] init];
for (int i = 0; i < days; i++) {
[part_days addObject:([begining_day[0] integerValue] + i)];
}
Now part_days will have your days, BUT! You have to handle the end of each month.
I'm 100% sure you'll find better solutions, but I thought I could share the first thing I thought of, you might benefit from it.
You can try below code:
NSArray *array = [[NSArray alloc] initWithObjects:#"1/12/14",#"2/12/14",#"3/12/14",#"4/12/14",#"5/12/14", nil];
for (int i = 0; i < [array count]; i++) {
NSArray *myArray = [[array objectAtIndex:i] componentsSeparatedByString:#"/"];
[dayArray addObject:[myArray objectAtIndex:0]];
}
NSLog(#"%#",dayArray);
You can incrementally add 24 hours to your startDate until you pass your endDate. Using NSDateComponents you can pick out the day. Instead of logging them with NSLog just store them in a string or array.
NSDate *startDate = [NSDate dateWithTimeIntervalSinceReferenceDate:300000000];
NSDate *endDate = [NSDate dateWithTimeIntervalSinceReferenceDate:302000000];
for (NSDate *nextDate = startDate; [nextDate compare:endDate] < 0; nextDate = [nextDate dateByAddingTimeInterval:24*60*60] ) {
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:nextDate];
NSInteger day = [components day];
NSLog(#"day %li", (long)day);
}
I have two date string and I wanted to get the in between dates.
For example,
NSString *startDate = #"25-01-2014";
NSString *endDate = #"02-02-2014";
In between dates will be (26-01-2014, 27-01-2014, 28-01-2014.......)
preferably include startDate and endDate as well. Most of the question I managed to find asked for number of days. But I needed it to be actual date. Is there anyway that I can get the in between dates?
NSString *start = #"2010-09-01";
NSString *end = #"2010-12-05";
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:#"yyyy-MM-dd"];
NSDate *startDate = [f dateFromString:start];
NSDate *endDate = [f dateFromString:end];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorianCalendar components:NSDayCalendarUnit
fromDate:startDate
toDate:endDate
options:0];
NSLog(#"Difference in date components: %d", components.day);
I managed to find this which only returns number of days difference.
NSString *start = #"2010-09-01";
NSString *end = #"2010-12-05";
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:#"yyyy-MM-dd"];
NSDate *startDate = [f dateFromString:start];
NSDate *endDate = [f dateFromString:end];
NSMutableArray *dates = [#[startDate] mutableCopy];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorianCalendar components:NSDayCalendarUnit
fromDate:startDate
toDate:endDate
options:0];
for (int i = 1; i < components.day; ++i) {
NSDateComponents *newComponents = [NSDateComponents new];
newComponents.day = i;
NSDate *date = [gregorianCalendar dateByAddingComponents:newComponents
toDate:startDate
options:0];
[dates addObject:date];
}
[dates addObject:endDate];
The array dates now contains the list of dates between startDate and endDate, including those, for midnight in the timezone of the device.
Note, that on some timezones this might cause trouble, as the switch from and to Daylight Saving Time might occur at that moment, see WWDC 2011 Video "Session 117 - Performing Calendar Calculations" for further information. One trick is to shift the hour to a save time, i.e. noon, do the calculation and than subtract 12 hours.
Ok, you're most of the way there. You have a date formatter that converts the date strings to NSDates. You have the number of days between the dates. Now you need to loop from the start date for that many days, adding a variable number of days to the start date.
The method you need is dateByAddingComponents:toDate:options:.
Something like this (goes immediately after your code) :
int days = components.day;
NSDateComponents *daysToAdd = [[NSDateComponents alloc] init];
for (int count = 0; count <= days; count++)
{
daysToAdd.day = count;
NSDate *loopDate = [gregorianCalendar dateByAddingComponents: daysToAdd
toDate: startDate
options: 0 ];
NSLog(#"Day %d = %#", count+1, [f stringFromDate: loopDate]);
}
I haven't tested it, but that's the basic idea...
The code above should include both the start and end dates.
If you don't want to include the start date, make the loop start at count = 1 instead of count = 0.
If you don't want to include the end date, make the loop check count < days.
A little late but found a fix to the 'TIMEZONE' time issue that vikingosegundo talked about in his answer. I simply converted the NSDate to an NSString by calling a stringFromDate method on the formatter *f in your for loop...
for (int i = iStart; i < components.day; ++i) {
NSDateComponents *newComponents = [NSDateComponents new];
newComponents.day = i;
newComponents.hour = 0;
newComponents.minute = 0;
newComponents.second = 0;
NSDate *date = [gregorianCalendar dateByAddingComponents:newComponents
toDate:startDate
options:0];
// THIS IS THE CODE I ADDED TO MINE //
// convert NSDate to string calling on *f (NSDateformatter)
NSString *string = [f stringFromDate:date];
// split the string to separate year, month, etc...
NSArray *array = [string componentsSeparatedByString:#"-"];
// create second NSString withFormat and only add the variable from the date that you find pertinent
NSString *sDateNew = [NSString stringWithFormat:#"%#-%#-%#",array[0],array[1],array[2]];
// then simply add the sDateNew string to dates array
[dates addObject:sDateNew];
}
I think this should be put into the comment section of your answer vikingsegundo but it would not let me.
This question already has answers here:
Number of day of current year in iOS
(4 answers)
Closed 8 years ago.
I have Listed Birthday List in Current month order(August,September....July)
I have calculated the no of days between current date and Birthday List date.
In ViewDidLoad method
NSDateFormatter *curdatemonthnoformatter = [[NSDateFormatter alloc] init];
[curdatemonthnoformatter setDateStyle:NSDateFormatterMediumStyle];
[curdatemonthnoformatter setDateFormat:#"dd-MM"];
NSString * curdatemonthnostring = [curdatemonthnoformatter stringFromDate:[NSDate date]];
[curdatemonthnoformatter release];
NSDateFormatter *tempFormatter = [[NSDateFormatter alloc]init];
[tempFormatter setDateFormat:#"dd-MM"];
NSDate *startdate = [tempFormatter dateFromString:curdatemonthnostring];
NSLog(#"%#",startdate);
[tempFormatter release];
NSLog(#"%#",curdatemonthnostring);
for (int val=0; val<[monthlistArray count]; val++)
{
NSMutableArray * dataarraylocal = [[[NSMutableArray alloc]initWithCapacity:0]autorelease];
for (int ival=0; ival<[[monthdataArray objectAtIndex:val]count]; ival++)
{
NSString *birthdatestr=[NSString stringWithFormat:#"%#",[[[monthdataArray objectAtIndex:val]objectAtIndex:ival]objectForKey:#"birthday"]];
NSDate *mybirthdate=[formatter dateFromString:birthdatestr];
NSDateFormatter *birthdatemonthFormatter = [[NSDateFormatter alloc] init];
[birthdatemonthFormatter setDateStyle:NSDateFormatterMediumStyle];
[birthdatemonthFormatter setDateFormat:#"dd-MM"];
NSString *sortmonthstr = [birthdatemonthFormatter stringFromDate:mybirthdate];
NSDateFormatter *tempFormatter1 = [[[NSDateFormatter alloc]init]autorelease];
[tempFormatter1 setDateFormat:#"dd-MM"];
NSDate *toDate = [tempFormatter1 dateFromString:sortmonthstr];
[dataarraylocal addObject:toDate];
}
[previouscomparearray addObject:dataarraylocal];
}
NSLog(#"%#",previouscomparearray);
for (int ival=0; ival<[monthlistArray count]; ival++)
{
NSMutableArray *nofdayslocal=[[NSMutableArray alloc]initWithCapacity:0];
for (int jval=0; jval<[[monthdataArray objectAtIndex:ival]count]; jval++)
{
unsigned flags = NSDayCalendarUnit;
NSDateComponents *difference = [[NSCalendar currentCalendar] components:flags fromDate:startdate toDate:[[previouscomparearray objectAtIndex:ival]objectAtIndex:jval] options:0];
int dayDiff = [difference day];
NSLog(#"%d",dayDiff);
[nofdayslocal addObject:[NSNumber numberWithInt:dayDiff]];
}
[comparedatearray addObjectsFromArray:nofdayslocal];
}
NSLog(#"%#",comparedatearray);
Output:
"-8",
"-5",
"-1",
31,
83,
115,
"-220",
"-154",
"-154",
"-130",
"-90",
"-80",
"-73",
"-68",
"-63",
"-44",
"-42"
It calculated within current year.I want after December its will be calculate based on Next Year.
Any Idea Please help me.
You can find a whole guide for Date and Time Programming. Here is a link(https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/DatesAndTimes/Articles/dtCalendricalCalculations.html#//apple_ref/doc/uid/TP40007836-SW1) which gives you help on what to do.
NSString *first = #"2010-10-09";
NSString *second = #"2011-12-10";
NSDateFormatter *form = [[NSDateFormatter alloc] init];
[form setDateFormat:#"yyyy-MM-dd"];
NSDate *startDate = [form dateFromString:first];
NSDate *endDate = [form dateFromString:second];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comp = [gregorianCalendar components:NSDayCalendarUnit
fromDate:startDate
toDate:endDate
options:0];
comp will have the difference in the number of days. You can print and check. Good luck. :)