iPhone NSCalendar - 为美国以外的用户绘制的日历不正确

时间:2011-03-17 02:25:46

标签: iphone ios4 nscalendar

在尝试处理别人的代码和许多不同的迭代后,我无法理解我在日历月视图中的日期错误。我试图以calendar.app等月视图方式呈现日历,但不幸的是,澳大利亚,英国等国家的一些用户报告日期与日期的对齐方式不正确。例如在澳大利亚,它将于3月17日星期五显示。任何帮助都非常感谢!

以下是我正在使用的代码示例:

-(void)setCalendar
{
    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *comps = [gregorian components:units fromDate:[NSDate date]];
    self.currentDate = [gregorian dateFromComponents:comps];
    NSInteger weekdayInteger=[comps weekday];
    currentMonth=[comps month]; 
    currentYear=[comps year];   
    NSString *dateString=[[NSString stringWithFormat:@"%@",currentDate] substringToIndex:10];
    NSArray *array= [dateString componentsSeparatedByString:@"-"];
    NSInteger currentDay=[[array objectAtIndex:2] intValue];
    currentMonthConstant=currentMonth;
    currentYearConstant=currentYear;
    currentDayConstant=currentDay;
    currentConstantDate=[NSString stringWithFormat:@"%d/%d/%d",currentDayConstant,currentMonthConstant,currentYearConstant];
    currentFirstDay=((8+weekdayInteger-(currentDay%7))%7);
    if(currentFirstDay==0)
        currentFirstDay=7;
    [gregorian release];
}

这就是我填充日历的方式:

-(void)fillCalender:(NSInteger)month weekStarts:(NSInteger)weekday year:(NSInteger)year
{

    currentMonth=month;
    currentYear=year;
    currentFirstDay=weekday;
    UIButton *temp;
    NSInteger numberOfDays=[self getNumberofDays:month YearVlue:year];
    currentLastDay=(currentFirstDay+numberOfDays-1)%7;
    if(currentLastDay==0)
        currentLastDay=7;
    NSString *monthName=[self getMonth:month];
    NSInteger grid=(weekday-1); 

    monthLabel.text=[NSString stringWithFormat:@"%@   %d",monthName,year];


    for(int i=1;i<=numberOfDays;i++)
    {
        if([frontView isEqualToString:@"view1"])
            temp=[arr_View2Buttons objectAtIndex:grid];
        else
            temp= [arr_View1Buttons objectAtIndex:grid];

        [temp setBackgroundImage:nil forState:UIControlStateNormal];

        [temp setUserInteractionEnabled:TRUE];
        UILabel *aLbl = (UILabel *)[temp viewWithTag:123];
        [aLbl setText:[NSString stringWithFormat:@"%d",i]];

        // check for today
        if(currentDayConstant == i && currentMonthConstant == currentMonth && currentYearConstant == currentYear)
        {
            [aLbl setTextColor:[UIColor blueColor]];
        }
        else
        {
            [aLbl setTextColor:[UIColor colorWithRed:69/255.0 green:2/255.0 blue:71/255.0 alpha:1.0]];
        }
        [temp setTag:i];

        grid++;
        if(grid==35)
            grid=0;
    }

}

最后是viewdidload:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setCalendar];
    // set views
    [self.view1 setFrame:CGRectMake(0,45,320,232)];
    [self.view2 setFrame:CGRectMake(0,277,320,232)];
    [self.view addSubview:self.view1];
    [self.view addSubview:self.view2];
    frontView = @"view2";
    [self fillCalender:currentMonth weekStarts:currentFirstDay year:currentYear];
    frontView = @"view1";
}

2 个答案:

答案 0 :(得分:1)

您使用NSDateComponents获取工作日,月份和年份。这很好。
但是之后你会使用字符串操作来获得这一天 并且您操纵从NSDate的描述方法获得的字符串。根据我的经验,这种方法可以返回它想要的东西。我永远无法弄清楚描述方法使用哪个时区偏移,在我的机器上它以UTC时区返回NSDate,其他用户在SO上提出的问题暗示该方法在本地时区或在时区中返回NSDate在当地时区旁边。或者在任意时区。通常这没有问题,因为您可以使用时区信息,但您只是忽略它。

简而言之:如果您想要日期处理,请不要使用字符串处理

恕我直言,这是一个时区问题。因为您混合了两种不同的日期处理方式,并忽略了时区 摆脱字符串操作部分,并使用NSDateComponents的一切。

答案 1 :(得分:0)

您需要更改代码

替换  NSCalendar * gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSCalendar * currentCalendar = [NSCalendar currentCalendar];

这将从设备中识别当前日历并将相应地执行

希望这能解决你的问题...