UITableview title bar with date for week? - ios

How can I have the title of UITableview with date?
I know I can edit the title using:
self.title=#"meals for ..";
I want to add the date for one week. How can I do that?

You can get a date like this:
NSDate *theDateToday = [NSDate date];
And format it like this:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"EEE MMM dd"];
NSString *theDateAsAString = [dateFormatter stringFromDate:theDateToday];
Combine that with what you have like this:
self.title = [NSString stringWithFormat:#"meals for %#", theDateAsAString];
As for finding the days of the week, you could try adapting this answer.
- (NSString *)getWeekStartDateAsString:(NSDate *)date {
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorian components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:today];
int dayofweek = [[[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:today] weekday];// this will give you current day of week
[components setDay:([components day] - ((dayofweek) - 2))];// for beginning of the week.
NSDate *beginningOfWeek = [gregorian dateFromComponents:components];
NSDateFormatter *dateFormat_first = [[NSDateFormatter alloc] init];
[dateFormat_first setDateFormat:#"yyyy-MM-dd"];
dateString2Prev = [dateFormat stringFromDate:beginningOfWeek];
weekstartPrev = [[dateFormat_first dateFromString:dateString2Prev] retain];
return weekstartPrev;
}
- (NSString *)getWeekEndDateAsString:(NSDate *)date {
NSCalendar *gregorianEnd = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *componentsEnd = [gregorianEnd components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:today];
int Enddayofweek = [[[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:today] weekday];// this will give you current day of week
[componentsEnd setDay:([componentsEnd day]+(7-Enddayofweek)+1)];// for end day of the week
NSDate *EndOfWeek = [gregorianEnd dateFromComponents:componentsEnd];
NSDateFormatter *dateFormat_End = [[NSDateFormatter alloc] init];
[dateFormat_End setDateFormat:#"yyyy-MM-dd"];
dateEndPrev = [dateFormat stringFromDate:EndOfWeek];
weekEndPrev = [[dateFormat_End dateFromString:dateEndPrev] retain];
return weekEndPrev;
}
You end result might look like this:
self.title = [NSString stringWithFormat:#"meals for %#-%#", [self getWeekStartDateAsString:theDateToday], [self getWeekEndDateAsString:theDateToday]];

A rarely known NSCalendar method will be the best option IMO
rangeOfUnit:startDate:interval:forDate:. It gives you the start and the duration (interval) for a certain time unit. With it it is easy to find the start of the week in the used calendar and add the range-1 to get the latest second in that week.
With the also rarely seen localizedStringFromDate:dateStyle:timeStyle: Available in OS X v10.6, iOS 4.0 it is easy to create a localized representation of the dates.
NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *now = [NSDate date];
NSDate *startOfTheWeek;
NSDate *endOfWeek;
NSTimeInterval interval;
[cal rangeOfUnit:NSWeekCalendarUnit
startDate:&startOfTheWeek
interval:&interval
forDate:now];
//startOfWeek is 2013-06-02 22:00:00 +0000 now (note: it is GMT with timezone support for my timezone Europe/Berlin/DST)
endOfWeek = [startOfTheWeek dateByAddingTimeInterval:interval-1];
// 2013-06-09 21:59:59 +0000
NSString *text = [NSDateFormatter localizedStringFromDate:startOfTheWeek
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterNoStyle];
text = [text stringByAppendingString:#" to "];
text = [text stringByAppendingFormat:#"%#", [NSDateFormatter localizedStringFromDate:endOfWeek
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterNoStyle]];
self.title=text;
results in 03.06.13 to 09.06.13 for my german locale, where Monday is start of the week.

Related

How in iOS to get first date of the month? [duplicate]

This question already has an answer here:
NSDateFormatter - 1 day incorrect?
(1 answer)
Closed 7 years ago.
I try to get first date for the current month from [NSDate new]. My problem is that instead of 2015/06/01 I always receive 2015/05/31. I even try to convert string 20150601 to NSDate and I still receive 2015/05/31.
Here is my CODE (for the second element):
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"yyyyMMdd"];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
currentMonth = [dateFormatter dateFromString:#"20150601"];
The result is:
(lldb) print currentMonth
(__NSDate *) $0 = 0x79e64820 2015-05-31 21:00:00 UTC
EDIT:
Ok, I understand my mistake - I don't check correctly result of my operations. They always result in UTC.
10x, for answer and all comments. I will be more careful next time.
NSDate *today = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorian components:(NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:today];
components.day = 1;
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
NSTimeZone *zone = [NSTimeZone localTimeZone];
[formatter setTimeZone:zone];
[formatter setDateFormat:#"yyyyMMdd"];
NSDate *dayOneInCurrentMonth = [gregorian dateFromComponents:components];
NSString *currentMonth = [formatter stringFromDate:dayOneInCurrentMonth];
NSLog(#"%#",currentMonth);
Output
2015-06-08 14:07:30.924 NSDATEDemo[1943:39838] 20150601
Create NSDateComponents from [NSDate date], set the current day to 1 and re-create your NSDate object:
- (NSDate *) dateAtStartOfMonth
{
//Not tested!!!
NSDateComponents *comp = [[NSCalendar currentCalendar] components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]];
[comp setDay:1];
return [[NSCalendar currentCalendar] dateFromComponents:comp];
}

How to get NSDate start of previous month?

I suppose that I ask duplicate question, but I can not find solution for me. I need to get 1st day of the previous month. As I understand I have to get calendar from today, subtract 1 month and set day to be 1st. After that I have to convert to date. Unfortunately I get last day of previous month.
I use following code:
NSDate *maxDate = [[NSDate alloc] init];
NSCalendar *calendarCurr = [NSCalendar currentCalendar];
NSDateComponents *components = [calendarCurr components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:maxDate];
[components setMonth:-1];
components.day = 1;
NSDate *minDate = [calendarCurr dateFromComponents:components];
NSLog(#"%#", minDate);
EDIT:
Yes, it is duplicate, but answers in that question does not help me. I still get 30/09/2014 (when today is 17/11/2014) instead of 01/10/2014. I suppose that my problem is time of todays date.
Well, Here a new approach:
NSDate *today = [NSDate date];
NSDateFormatter *formatterYear = [[NSDateFormatter alloc] init];
[formatterYear setDateFormat:#"yyyy"];
NSDateFormatter *formatterMonth = [[NSDateFormatter alloc] init];
[formatterMonth setDateFormat:#"MM"];
[formatterMonth setTimeZone:[NSTimeZone timeZoneWithName:#"GMT"]];
NSString *yearString = [formatterYear stringFromDate:today];
NSString *monthString = [formatterMonth stringFromDate:today];
NSInteger month,year;
if ([monthString integerValue] == 1) {
year = [yearString integerValue] -1;
month = 12;
} else
{
year = [yearString integerValue];
month = [monthString integerValue]-1;
}
NSDateFormatter *exitFormatter = [[NSDateFormatter alloc] init];
[exitFormatter setDateFormat:#"yyyy-MM-dd"];
[exitFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"GMT"]];
NSString *stringDate;
if (month < 10) {
stringDate = [NSString stringWithFormat:#"%ld-0%ld-01",(long)year,(long)month];
} else {
stringDate = [NSString stringWithFormat:#"%ld-%ld-01",(long)year,(long)month];
}
NSDate *firstDatePreviousMonth = [exitFormatter dateFromString:stringDate];
NSLog(#"View the date: %#",[firstDatePreviousMonth description]);
Wrong calculation.
Use this code to set Month component.
[components setMonth:components.month -1];
NSDate *currentDate = [NSDate date];
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc]init];
[dateFormatter1 setDateFormat:#"MM"];
NSString *stringCurrentDate = [dateFormatter1 stringFromDate:currentDate];
int monthInt= [stringCurrentDate intValue];
[dateFormatter1 setDateFormat:#"yyyy"];
NSString *dateString = [dateFormatter1 stringFromDate:currentDate];
int yearInt = [dateString intValue];
monthInt-= 1;
if (monthInt== 0) {
monthInt= 12;
yearInt -=1;
}
dateString = [NSString stringWithFormat:#"%#-01-%#",[#(monthInt)stringValue],[#(yearInt)stringValue]];
NSLog(#"this is previous month first date : %#",dateString);
run it as it is, obviously first day of month will be 01, so this is static here. your can change accordingly. happy coding
Try this:
NSDate *maxDate = [NSDate date];
NSCalendar *calendarCurr = [NSCalendar currentCalendar];
NSDateComponents *components = [calendarCurr components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear | NSCalendarUnitTimeZone | NSCalendarUnitSecond | NSCalendarUnitHour | NSCalendarUnitMinute fromDate:maxDate];
[components setMonth:components.month - 1];
[components setDay:1];
NSDate *minDate = [calendarCurr dateFromComponents:components];
NSLog(#">>>>>>>>>>%#", minDate.description);

Next Week Calculation

I have a requirement in which i have to calculate working days i.e from Monday to Friday. if i pass todays date that particular week start date (Monday's Date) and end date(Friday's Date) will be displayed. And i calculated using the below Code.
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd"];// you can use your format.
todayDate= [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorian components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:todayDate];
int dayofweek = [[[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:todayDate] weekday];// this will give you current day of week
[components setDay:([components day] - ((dayofweek) - 2))];// for beginning of the week.
NSDate *beginningOfWeek = [gregorian dateFromComponents:components];
NSDateFormatter *dateFormat_first = [[NSDateFormatter alloc] init];
[dateFormat_first setDateFormat:#"yyyy-MM-dd"];
NSString * dateString2Prev = [dateFormat stringFromDate:beginningOfWeek];
NSDate * weekstartPrev = [dateFormat_first dateFromString:dateString2Prev];
// NSLog(#"The start of the week %#",weekstartPrev);
startDate= [weekstartPrev dateByAddingTimeInterval:60*60*24*1];
//NSLog(#"The date plus one is %#", startDate);
//Week End Date
NSCalendar *gregorianEnd = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *componentsEnd = [gregorianEnd components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:todayDate];
int Enddayofweek = [[[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:todayDate] weekday];// this will give you current day of week
[componentsEnd setDay:([componentsEnd day]+(7-Enddayofweek)+1)];// for end day of the week
NSDate *EndOfWeek = [gregorianEnd dateFromComponents:componentsEnd];
NSDateFormatter *dateFormat_End = [[NSDateFormatter alloc] init];
[dateFormat_End setDateFormat:#"yyyy-MM-dd"];
NSString *dateEndPrev = [dateFormat stringFromDate:EndOfWeek];
NSDate *weekEndPrev = [dateFormat_End dateFromString:dateEndPrev];
endDate= [weekEndPrev dateByAddingTimeInterval: -86400.0];
NSDateFormatter *dateF = [[NSDateFormatter alloc] init];
[dateF setDateFormat:#"dd-MMM-yyyy"];
[dateF setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[dateF setLocale:[NSLocale localeWithLocaleIdentifier:#"en_GB"]];
endDateString = [dateF stringFromDate:endDate]; //pass this date to time table view controller
NSLog(#"Start date %# and End date %# ",startDate, endDate);
NSDateFormatter *dateF = [[NSDateFormatter alloc] init];
[dateF setDateFormat:#"dd-MMM-yyyy"];
[dateF setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[dateF setLocale:[NSLocale localeWithLocaleIdentifier:#"en_GB"]];
startDateString = [dateF stringFromDate:startDate];
NSLog(#"the date start %# ", startDateString);
Now My question is how can I calculate next week for example todays date is Tue 26 Aug 2014. I calculated the current week i.e from Mon 25 Aug 2014 TO Fri 29 Aug 2014 using the above code. how can I calculate next week i.e from 1st September 2014 (monday) To 5th September 2014 (Friday).
i have worked on the similar issues some weeks ago.
I created a category on NSDate. You can use the methods.
- (NSDate *)firstDayOfWeek
{
return [NSDate firstDayOfWeekFor:self];
}
+(NSDate *)firstDayOfWeekFor:(NSDate*)p_Date
{
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *weekdayComponents = [calendar components:NSWeekdayCalendarUnit fromDate:p_Date];
NSDateComponents *componentsToSubtract = [[NSDateComponents alloc] init];
if ([weekdayComponents weekday] == 1)
{
// dimanche, on soustrait 6 jours
[componentsToSubtract setDay:-6];
}
else
{
// autres jours, on soustrait le jour courant et on rajoute 2 (=lundi)
[componentsToSubtract setDay:(-[weekdayComponents weekday] + 2)];
}
return [calendar dateByAddingComponents:componentsToSubtract toDate:[p_Date withoutTime] options:0];
}
- (NSDate *) dateByAddingDays:(NSInteger)p_Days
{
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:p_Days];
return [calendar dateByAddingComponents:components toDate:self options:0];
}

Adding one month to NSDate

I am trying to set a start date and an end date in my app. The end date should be one month from the start date.
e.g.
start date = 1st January 2014
end date = 31st January 2014
Currently I am using the following method to add one month to the start date, but the end date becomes 1st February 2014.
dateByAddingComponents:toDate:options:
Is there a way to achieve the result I am looking for so that the end date will always be one month - 1 day from the start date?
I hope this made sense.
Thank you.
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComp = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]];
NSLog(#"Input Date: %#",[NSDate date]);
[dateComp setDay:dateComp.day - 1];
[dateComp setMonth:dateComp.month + 1];
NSDate *nextMonthMinusOneday = [gregorian dateFromComponents:dateComp];
NSLog(#"Output date %#",nextMonthMinusOneday);
Output:
Input Date: 2014-03-31 21:21:34 +0000
Output date 2014-04-30 05:00:00 +0000
Sure:
- (NSDate *)lastDayOfMonthDateForDate:(NSDate *)date {
NSDateComponents *comp = [NSDateComponents new];
comp.day = -1;
comp.month = 1;
return [[NSCalendar currentCalendar] dateByAddingComponents:comp toDate:date options:0];
}
- (NSDate *)dateForNextMonthMinusSingleDay:(NSDate *)date {
NSDateComponents *dayOffsetComponents = [[NSDateComponents alloc] init];
[dayOffsetComponents setMonth:1];
[dayOffsetComponents setDay:-1];
return [[NSCalendar currentCalendar] dateByAddingComponents:dayOffsetComponents
toDate:date
options:0];
}
- (NSDate *)dateFromMMDDYYYYString:(NSString *)string {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"]];
[formatter setDateFormat:#"MM/dd/yyyy"];
return [formatter dateFromString:string];
}
NSDate *date = [self dateForNextMonthMinusSingleDay:[self dateFromMMDDYYYYString:#"01/01/2014"]];
I have verified the above code and its working as expected.

Constructing an NSDate from today's date and a string with the time

If I have a string representing a time, say "10:45 am", and do the following to parse the string:
NSDateFormatter *dateFormat;
dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"h:mm a"];
NSLog(#"%#", [dateFormat dateFromString:#"10:45 AM"]);
I would get this logged:
2013-09-09 17:52:30.416 TimeTest[49491:a0b] 2000-01-01 15:45:00 +0000
How can I create an NSDate for the current day at the given time? I tried this
NSDate *date = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"h:mm a"];
NSDate *time = [formatter dateFromString:#"10:45 AM"];
NSDateComponents *timeComponents = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit | NSMinuteCalendarUnit ) fromDate:time];
NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:date];
NSDateComponents *newComponents = [[NSDateComponents alloc]init];
newComponents.timeZone = [NSTimeZone systemTimeZone];
[newComponents setDay:[dateComponents year]];
[newComponents setMonth:[dateComponents month]];
[newComponents setYear:[dateComponents year]];
[newComponents setHour:[timeComponents hour]];
[newComponents setMinute:[timeComponents minute]];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *combinedDate = [gregorianCalendar dateFromComponents:newComponents];
NSLog(#"%#", combinedDate);
with the result
2013-09-09 19:57:14.506 TimeTest[49712:a0b] 2019-03-06 15:45:00 +0000
How should I go about this?
I'm not exactly sure what you are looking for. For what I understand, you want to build a date with the current year, month and day, but with your supplied time by parsing it from a string.
If that is the case, as others have pointed out, you need to play with NSDateComponents.
Based on your code I wrote these lines. They should build a date by merging two dates. The current one and the one you parsed.
// Get the full current date
NSDate *date = [NSDate date];
// Get the current calendar
NSCalendar *calendar = [NSCalendar currentCalendar];
// Split the date into components but only take the year, month and day and leave the rest behind
NSDateComponents *dateComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:date];
// Build the date formatter
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"h:mm a"];
// Convert the string time into an NSDate
NSDate *time = [formatter dateFromString:#"10:45 AM"];
// Split this one in components as well but take the time part this time
NSDateComponents *timeComponents = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit | NSMinuteCalendarUnit ) fromDate:time];
// Do some merging between the two date components
dateComponents.hour = timeComponents.hour;
dateComponents.minute = timeComponents.minute;
// Extract the NSDate object again
NSDate *result = [calendar dateFromComponents:dateComponents];
// Check if this was what you where looking for
NSLog(#"%#",result);
Please be aware that this sample code is by far non-optimized. There are more crisp ways to obtain what you are looking for by using time intervals, but I felt like you wanted a dirty simple example on how to do components copy and paste and then extracting dates.
This will create a date for the beginning of the day in the current time zone.
NSDate *today = [NSDate date];
NSTimeInterval interval;
NSCalendar *cal = [NSCalendar currentCalendar];
[cal rangeOfUnit:NSDayCalendarUnit
startDate:&today
interval:&interval
forDate:today];
Now we add the time:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// I have to set the locale to posix_en_us, as my system is using 24hour style as default
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[dateFormatter setDateFormat:#"hh:mm a"];
NSDate *time = [dateFormatter dateFromString:#"10:45 AM"];
NSDateComponents *comps = [cal components:(NSHourCalendarUnit | NSMinuteCalendarUnit)
fromDate:time];
NSDate *dateAndTime = [cal dateByAddingComponents:comps
toDate:today
options:0];
dateAndTime will now be todays date with 10:45 am in the local timezone.
controlling in the debugger:
po dateAndTime
$0 = 0x41b7df138c00000d 2013-09-10 08:45:00 +0000
This is correct, as my timezone is 2 hours ahead to GMT, as we still have summer time.

Resources