简体   繁体   English

将NSDateFormatter与NSString和NSDate一起使用时,其他区域设置会导致NSDate区域设置问题

[英]NSDate Locale Causing Issues for Other Locales when Using NSDateFormatter with NSString and NSDate

I have a working app right now but I have hit a big stumbling block. 我现在有一个正在运行的应用程序,但是遇到了很大的绊脚石。 The app has the premise of a tab bar controller (TB) which has two Tabs consisting of one table view in each tab. 该应用程序具有标签栏控制器(TB)的前提,该控制器具有两个标签,每个标签中包含一个表格视图。 Table view 1 (TV1) is populated by the user clicking the plus button in the navigation bar and filling in the name and event text fields and selecting a date from the date picker. 用户单击导航栏中的加号按钮,然后填写名称和事件文本字段,然后从日期选择器中选择一个日期,即可填充表格视图1(TV1)。 Table view 2 is an illustration of each unique event that the user has created. 表格视图2说明了用户创建的每个唯一事件。 Where table 1 shows every transaction in chronological order, table 2 shows only the unique event names so you can view the transactions by events. 表1按时间顺序显示每个事务,表2仅显示唯一的事件名称,因此您可以按事件查看事务。

I'm using Core Data and NSFetchedResultsControllers to tie everything together. 我正在使用Core Data和NSFetchedResultsControllers将所有内容捆绑在一起。

This is working very well but I'm looking to introduce an update. 这工作得很好,但我想介绍一个更新。

If the user clicks on the Table 2 and sees the events showing for example, Anniversary, Birthday and Wedding, and then clicks on say, Birthday, they will see all of the transactions where event = birthday (selected events scene). 如果用户单击表2并看到显示例如Anniversary,Birthday和Wedding的事件,然后单击“ Birthday”,则他们将看到event = Birthday(选定事件场景)的所有事务。 I've put a new navigation bar button in here (selected events) to allow the user to add a new entry with the date and event already populated from the selected event. 我在此处放置了一个新的导航栏按钮(选定的事件),以允许用户添加一个新条目,其中包含已从选定事件中填充的日期和事件。

I have this 95% working. 我有95%的工作。 The issue comes down to NSLocales and Date Formatters. 问题归结于NSLocales和Date Formatters。

I'll put some code here and then talk about the issue: 我将在此处放置一些代码,然后讨论这个问题:

In the Add Entry, the NSCalendar for the date and datePicker is: 在“添加条目”中,date和datePicker的NSCalendar为:

    NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    // Will explain the commented out lines    
    //NSLocale *brLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
    //[cal setLocale:brLocale];
    NSDateComponents *components = [cal components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit
                                          fromDate:self.datePicker.date];
    [components setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
    NSDate *selectedDate = [cal dateFromComponents:components];

Before this update, I did not have the locale (Commented out code) in this code because it would just use the device local and that worked very well. 在此更新之前,我在此代码中没有语言环境(注释掉的代码),因为它只会使用本地设备,并且效果很好。 Now I had to add it in to get the next part working. 现在,我必须添加它才能使下一部分正常工作。

In the Selected Event Controller, the prepareForSegue is: 在选定的事件控制器中,prepareForSegue是:

if ([segue.identifier isEqualToString:@"Create New Entry From Event"])
{
    AddEntryViewController *addEntryViewController = (AddEntryViewController *)segue.destinationViewController;
    [addEntryViewController setSelectedEvent:self.occasion.title];

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0] ;
    NSString *sectionTitle = [self tableView:self.selectedOccasionTableView titleForHeaderInSection:indexPath.section];

    NSLog(@"The section header is: %@", sectionTitle);

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"MMMM d, yyyy"];
    NSDate *dateFromString = [[NSDate alloc] init];
    dateFromString = [dateFormatter dateFromString:sectionTitle];
    NSLog(@"The new date is %@", [dateFormatter stringFromDate:dateFromString]);
    [addEntryViewController setSelectedDate:dateFromString];
    [addEntryViewController setIsFromSelectedEvent:YES]; 
}

I'm getting the date from the section title and sending that over to the Add Entry where: 我从节标题中获取日期,并将其发送到添加条目,其中:

- (void)setSelectedDate:(NSDate *)selectedDate
{
    _selectedDate = selectedDate;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.occasionTextField.text = self.selectedEvent;

    if (self.isFromSelectedEvent)
    {
        NSLog(@"This gets run");
        [self.datePicker setDate:self.selectedDate animated:YES];
    }
}

The issue I'm having is - the app crashes if the device locale is set to anything but the US locale (with the code not commented out above). 我遇到的问题是-如果设备区域设置设置为除美国区域设置以外的任何设置,则应用程序崩溃(上面的代码未注释掉)。 This is not desirable of course. 当然这是不可取的。

A LOT of effort has gone into getting the app working with the dates in this format and I cannot change that because a lot is dependent on the dates in the section headers. 为了使该应用程序使用这种格式的日期,我们付出了很多努力,但我不能更改它,因为这很大程度上取决于节标题中的日期。

I need a way to adjust the NSDateFormatter code in the prepareForSegue to take into account whatever format the device is using. 我需要一种方法来调整prepareForSegue中的NSDateFormatter代码,以考虑设备使用的任何格式。

The code below is converting the NSDate into an NSString so it's readable in the section title, but here is where the problem is. 下面的代码将NSDate转换为NSString,以便在节标题中读取它,但这是问题所在。

-(NSString *)sectionDateFormatter
{
    return [NSDateFormatter localizedStringFromDate:self.dates.dateOfEvent
                                          dateStyle:NSDateFormatterLongStyle
                                          timeStyle:NSDateFormatterNoStyle];
}

If the user is using an American locale, the date will appear as Month Date, Year. 如果用户使用的是美国语言环境,则日期将显示为“ Month Date,Year”。 If the user is using a UK locale it'll be Date Month Year. 如果用户使用的是英国语言环境,则为“日期月份年”。

I need to somehow fix this. 我需要以某种方式解决此问题。 I either need to: 我要么需要:

1) Set the locale of the NSDate/NSString to one particular format regardless of locale, or 2) Manipulate the code to support all potential locales. 1)将NSDate / NSString的语言环境设置为一种特定的格式,而与语言环境无关,或者2)处理代码以支持所有潜在的语言环境。

Number 1 seems to be easier but I have no idea how to achieve this. 第一似乎更容易,但我不知道如何实现这一目标。 I need this app to not crash if you're using it of course. 当然,如果您使用它,我需要此应用程序不会崩溃。

If you're using a UK locale, it crashes with: 如果您使用的是英国语言环境,则会崩溃,并显示以下信息:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: date'

I need a way to stick to one format regardless of where you are. 无论您身在何处,我都需要一种坚持一种格式的方法。 For example, I would love to set the format to be "Date Month, Year" regardless of whether you're in America and using an American locale, or in Singapore using a Singaporean Locale. 例如,无论您是在美国使用美国语言环境,还是在新加坡使用新加坡语言环境,我都希望将格式设置为“ Date Month,Year”。

Any thoughts in the right direction would be seriously appreciated here. 任何正确方向的想法在此都将受到赞赏。

To control the date format in depend of the current locale setting define a formats instead of using the date/time style. 要根据当前语言环境设置控制日期格式,请定义格式,而不要使用日期/时间样式。 For example if you use 例如,如果您使用

[dateFormatter setDateFormat:@"MMMM dd, yyyy"]; 

Or any other format you want to display. 或您要显示的任何其他格式。 The you can create the string object using this date formatter 您可以使用此日期格式化程序创建字符串对象

[dateFormatter stringFromDate:self.dates.dateOfEvent];

Read up on various format strings here: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html#//apple_ref/doc/uid/TP40002369-SW1 在此处阅读各种格式字符串: https : //developer.apple.com/library/ios/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html#//apple_ref/doc/uid/TP40002369-SW1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM