【问题标题】:Display week & day lists for everymonth when we pass the year过年时显示每个月的周和日列表
【发布时间】:2014-02-12 09:58:56
【问题描述】:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = @"yyyy";
NSDate *date = [dateFormatter dateFromString:@"2011"];

NSCalendar *calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init];

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[oneDayAgoComponents setMonth:0];
NSUInteger numWeekdays = [calendar maximumRangeOfUnit:NSWeekdayCalendarUnit].length;
int w = numWeekdays;
for(int currentdateindexpath=0;currentdateindexpath<=12;currentdateindexpath++)
{
    [formatter setDateFormat:@"MMMM yyyy"];

    [oneDayAgoComponents setMonth:currentdateindexpath];
    NSDate *monthAgo = [calendar dateByAddingComponents:oneDayAgoComponents
                                                 toDate:date
                                                options:0];


    NSString *montYear = [formatter stringFromDate:monthAgo];

    NSDateComponents* subcomponent = [calendar components:NSWeekdayCalendarUnit
                                                 fromDate:date];


    [subcomponent setWeek:currentdateindexpath];
    [formatter setDateFormat:@"'week'W"];
    NSString *stringFromDate = [formatter stringFromDate:monthAgo];
    // Get the weekday component of the current date
    [oneDayAgoComponents setDay: 0 - ([subcomponent weekday] - 1)];

    NSDate *beginningOfWeek = [calendar dateByAddingComponents:oneDayAgoComponents
                                                        toDate:date options:0];


    [formatter setDateFormat:@"dd/MM/yy"];
    NSString *weekstartdate = [formatter stringFromDate:beginningOfWeek];


    NSDateComponents *components =
        [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit |
                              NSDayCalendarUnit) fromDate: beginningOfWeek];

    beginningOfWeek = [calendar dateFromComponents:components];

    for (int d = 0; d <= w; d++)
    {
        NSDate *newDate1 = [beginningOfWeek dateByAddingTimeInterval:60*60*24*d];
        NSLog(@"days %@",newDate1);
  //+++++++++++++++++++ start week+++++++++++++++
    }
    [oneDayAgoComponents setDay:7 - ([subcomponent weekday])];

    NSDate *endOfWeek = [calendar dateByAddingComponents:oneDayAgoComponents
                                                  toDate:date options:0];

    [formatter setDateFormat:@"dd/MM/yy"];
    NSString *weekendtdate = [formatter stringFromDate:endOfWeek];

    NSLog(@"...>%@",[NSString stringWithFormat:@"%@ %@ to %@   %@", stringFromDate, weekstartdate, weekendtdate, montYear]);
}

如果我通过 2011 年的年份,我需要获取月、周、日列表。在相应的月份中,该特定周有多少周可用,有多少天可用,以及需要显示周开始和结束日期的位置..但在此代码中,第一周的每个月仅显示,我需要剩下的一周本月...

样本输出:

days 2010-12-25 18:30:00 +0000
days 2010-12-26 18:30:00 +0000
days 2010-12-28 18:30:00 +0000
days 2010-12-29 18:30:00 +0000
days 2010-12-30 18:30:00 +0000
days 2010-12-31 18:30:00 +0000
days 2011-01-01 18:30:00 +0000
...>week1 26/12/10 to01/01/11   January 2011 
days 2011-01-25 18:30:00 +0000
days 2011-01-26 18:30:00 +0000
days 2011-01-27 18:30:00 +0000
days 2011-01-28 18:30:00 +0000
days 2011-01-29 18:30:00 +0000
days 2011-01-30 18:30:00 +0000
days 2011-01-31 18:30:00 +0000
days 2011-02-01 18:30:00 +0000
...>week1 26/01/11 to01/02/11   February 2011 

【问题讨论】:

标签: ios iphone nsdate nscalendar


【解决方案1】:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
     formatter.dateFormat = @"yyyy";
    NSDate *date = [formatter dateFromString:@"2011"];

    NSCalendar *calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
    // Create the start date components
    NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init];

    [oneDayAgoComponents setMonth:0];
    NSUInteger numWeekdays = [calendar maximumRangeOfUnit:NSWeekdayCalendarUnit].length;
   int w=numWeekdays;
    for(int currentdateindexpath=0;currentdateindexpath<=52;currentdateindexpath++)
    {

        [oneDayAgoComponents setWeek:currentdateindexpath];

        NSDate *monthAgo = [calendar dateByAddingComponents:oneDayAgoComponents
                                                     toDate:date
                                                    options:0];
        [formatter setDateFormat:@"MMMM yyyy"];
        NSString *montYear = [formatter stringFromDate:monthAgo];

         [formatter setDateFormat:@"'week'W"];
        stringFromDate = [formatter stringFromDate:monthAgo];
         NSDateComponents* subcomponent = [calendar components:NSWeekdayCalendarUnit
                                                     fromDate:date];


        [oneDayAgoComponents setDay: 0 - ([subcomponent weekday] - 1)];
        //NSLog(@"oneDayAgoComponents1 %@",oneDayAgoComponents);
        NSDate *beginningOfWeek = [calendar dateByAddingComponents:oneDayAgoComponents
                                                            toDate:date options:0];

        //NSLog(@" beginningOfWeek %@",beginningOfWeek);
        [formatter setDateFormat:@"dd/MM/yy"];
        NSString *weekstartdate = [formatter stringFromDate:beginningOfWeek];
        // NSLog(@"weekstartdate %@",weekstartdate);

        NSDateComponents *components =
        [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit |
                              NSDayCalendarUnit) fromDate: beginningOfWeek];

        beginningOfWeek = [calendar dateFromComponents:components];

        for(int d=0;d<=w;d++){
            NSDate *newDate1 = [beginningOfWeek dateByAddingTimeInterval:60*60*24*d];
             NSString *date_ = [formatter stringFromDate:newDate1];
            NSLog(@"days %@",date_);
            //NSLog(@"Show %@",beginningOfWeek);
        }
        [oneDayAgoComponents setDay:7- ([subcomponent weekday])];

        // NSLog(@"oneDayAgoComponents2 %@",oneDayAgoComponents);
        NSDate *endOfWeek = [calendar dateByAddingComponents:oneDayAgoComponents
                                                      toDate:date options:0];
        // NSLog(@" endOfWeek %@",endOfWeek);
        [formatter setDateFormat:@"dd/MM/yy"];
        NSString *weekendtdate = [formatter stringFromDate:endOfWeek];
        // NSLog(@"weekendtdate %@",weekendtdate);


        NSLog(@"...>%@",[NSString stringWithFormat:@"%@ %@ to%@   %@ ",stringFromDate,weekstartdate,weekendtdate,montYear]);
}

【讨论】:

    【解决方案2】:

    你可以这样做:

    NSString *userYearString = @"2011";
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    
    // Get the year from the string
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.dateFormat = @"yyyy";
    NSDate *startOfTheYear = [dateFormatter dateFromString:userYearString];
    
    // Loop until the year is over printing the data you need
    //
    // Some objects we'll use in the loop and that's better to instantiate only once
    NSDateFormatter *weekIntervalFormatter = [[NSDateFormatter alloc] init];
    weekIntervalFormatter.dateFormat = @"dd/MM/yy";
    
    NSDateFormatter *monthFormatter = [[NSDateFormatter alloc] init];
    monthFormatter.dateFormat = @"MMMM yyyy";
    
    NSDate *currentDate = startOfTheYear;
    NSTimeInterval oneDayTimeInterval = 86400;
    
    // We'll use userYear to determing when to stop the loop
    NSDateComponents *components = [calendar components:NSCalendarUnitYear fromDate:currentDate];
    NSInteger userYear = [components year];
    
    do {
        // Get the month at the begin of the iteration, to use it as the stop comparator
        NSInteger previousMonth = [[calendar components:NSCalendarUnitMonth fromDate:currentDate] month];
        // Evaluate the month string once at the begin of the iteration
        NSString *monthString = [monthFormatter stringFromDate:currentDate];
    
        // Move a the beginning of the month
        NSDate *startOfMonthDate;
        NSTimeInterval _interval;
        [calendar rangeOfUnit:NSMonthCalendarUnit
                    startDate:&startOfMonthDate
                     interval:&_interval
                      forDate:currentDate];
    
        // From the beginning of the month move at the beginning of the week
        NSDate *startOfWeekDate;
        [calendar rangeOfUnit:NSWeekCalendarUnit
                    startDate:&startOfWeekDate
                     interval:&_interval
                      forDate:startOfMonthDate];
    
        currentDate = startOfWeekDate;
    
        // Loop printing the days and week information until the month is over
        NSUInteger weekCounter = 1;
        do {
            // print a the days of the current week
            NSDate *weekStartDate = currentDate;
            for (int i=0; i < 7; i++) {
                NSLog(@"day %@", currentDate);
                currentDate = [currentDate dateByAddingTimeInterval:oneDayTimeInterval];
            }
            NSDate *weekEndDate = [currentDate dateByAddingTimeInterval:-oneDayTimeInterval];
    
            // prepare the message using the date formatter previously created
            NSString *formattedStartDay = [weekIntervalFormatter stringFromDate:weekStartDate];
            NSString *formattedEndDay = [weekIntervalFormatter stringFromDate:weekEndDate];
            NSString *message = [NSString stringWithFormat:@"...>week %d, %@ to %@\t%@", weekCounter, formattedStartDay, formattedEndDay, monthString];
            NSLog(@"%@", message);
    
            weekCounter++;
    
            // evalutate the end of loop condition
            // = is the month over?
            components = [calendar components:NSCalendarUnitMonth fromDate:currentDate];
        } while ([components month] == previousMonth); // loop until the month is over
    
    
        // evaluate the end of loop condition
        // = is the year over?
        components = [calendar components:NSCalendarUnitYear fromDate:currentDate];
    } while ([components year] == userYear); // loop until the year is over
    

    这个版本给出了这个输出

    day 2010-12-26 00:00:00 +0000
    day 2010-12-27 00:00:00 +0000
    day 2010-12-28 00:00:00 +0000
    day 2010-12-29 00:00:00 +0000
    day 2010-12-30 00:00:00 +0000
    day 2010-12-31 00:00:00 +0000
    day 2011-01-01 00:00:00 +0000
    ...>week 1, 26/12/10 to 01/01/11    January 2011
    day 2011-01-02 00:00:00 +0000
    day 2011-01-03 00:00:00 +0000
    day 2011-01-04 00:00:00 +0000
    day 2011-01-05 00:00:00 +0000
    day 2011-01-06 00:00:00 +0000
    day 2011-01-07 00:00:00 +0000
    day 2011-01-08 00:00:00 +0000
    ...>week 2, 02/01/11 to 08/01/11    January 2011
    day 2011-01-09 00:00:00 +0000
    day 2011-01-10 00:00:00 +0000
    day 2011-01-11 00:00:00 +0000
    day 2011-01-12 00:00:00 +0000
    day 2011-01-13 00:00:00 +0000
    day 2011-01-14 00:00:00 +0000
    day 2011-01-15 00:00:00 +0000
    ...>week 3, 09/01/11 to 15/01/11    January 2011
    day 2011-01-16 00:00:00 +0000
    day 2011-01-17 00:00:00 +0000
    day 2011-01-18 00:00:00 +0000
    day 2011-01-19 00:00:00 +0000
    day 2011-01-20 00:00:00 +0000
    day 2011-01-21 00:00:00 +0000
    day 2011-01-22 00:00:00 +0000
    ...>week 4, 16/01/11 to 22/01/11    January 2011
    day 2011-01-23 00:00:00 +0000
    day 2011-01-24 00:00:00 +0000
    ay 2011-01-25 00:00:00 +0000
    day 2011-01-26 00:00:00 +0000
    day 2011-01-27 00:00:00 +0000
    day 2011-01-28 00:00:00 +0000
    day 2011-01-29 00:00:00 +0000
    ...>week 5, 23/01/11 to 29/01/11    January 2011
    day 2011-01-30 00:00:00 +0000
    day 2011-01-31 00:00:00 +0000
    day 2011-02-01 00:00:00 +0000
    day 2011-02-02 00:00:00 +0000
    day 2011-02-03 00:00:00 +0000
    day 2011-02-04 00:00:00 +0000
    day 2011-02-05 00:00:00 +0000
    ...>week 6, 30/01/11 to 05/02/11    January 2011
    day 2011-01-30 00:00:00 +0000
    day 2011-01-31 00:00:00 +0000
    day 2011-02-01 00:00:00 +0000
    day 2011-02-02 00:00:00 +0000
    day 2011-02-03 00:00:00 +0000
    day 2011-02-04 00:00:00 +0000
    day 2011-02-05 00:00:00 +0000
    ...>week 1, 30/01/11 to 05/02/11    February 2011
    day 2011-02-06 00:00:00 +0000
    day 2011-02-07 00:00:00 +0000
    day 2011-02-08 00:00:00 +0000
    day 2011-02-09 00:00:00 +0000
    day 2011-02-10 00:00:00 +0000
    day 2011-02-11 00:00:00 +0000
    day 2011-02-12 00:00:00 +0000
    ...>week 2, 06/02/11 to 12/02/11    February 2011
        ...
    

    如您所见,我使用了与您不同的实现...我更喜欢 do-while 方法来了解月份或年份何时结束,因为它更内省。我还尝试创建尽可能少的对象,这始终是一个好主意。

    我还向您推荐这本书:Clean Code,它充满了编写有效代码的技巧和技巧。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-14
      • 1970-01-01
      相关资源
      最近更新 更多