日期选择器和列表选择器(多个时区)以创建计划的日期字符串



在此项目的UI侧,有一个日期选择器和列表选择器,旨在允许用户选择特定时区的未来时间和日期,以安排一个警报,以通过语音,短信,电子邮件等。不幸的是,GMT偏移量无法正确调整。例如,计划于2017年6月7日为德国柏林(GMT 0200(发出警报,实际上是第二天在柏林时间02:30产生的。

2017-06-08 00:33:00 0200

1。任何人都知道会导致这种差异以及如何 在所有时区更正它?

2。需要哪些步骤来调整所有计划 到中央日光时间?

新警报视图控制器的屏幕截图

在newalerttableviewcontroller.m中,此功能更新日期选择器标签:

- (void) updateDateLabel {
    NSDate *now                  = [NSDate date];
    NSDate *scheduledDate        = self.datePicker.date;
    if ([scheduledDate isToday] && scheduledDate.hour <= now.hour && scheduledDate.minute <= now.minute) {
        self.dateLabel.text      = NSLocalizedString(@"Now", @"label for time an alert is scheduled to be sent");
        self.sendButton.title    = NSLocalizedString(@"Send Alert", @"button label for sending an alert");
        self.alert.sendNow       = YES;
    } else if ([scheduledDate isToday]) {
        self.dateLabel.text      = [NSString stringWithFormat: NSLocalizedString(@"Today, %@", @"label for time an alert is scheduled to be sent"), [scheduledDate stringWithDateStyle: NSDateFormatterNoStyle                                                                                                                                                                       timeStyle: NSDateFormatterShortStyle]];
        self.sendButton.title    = NSLocalizedString(@"Save Alert", @"button label for saving an alert");
        self.alert.sendNow       = NO;
    } else {
        self.dateLabel.text      = [scheduledDate stringWithDateStyle: NSDateFormatterShortStyle
                                                            timeStyle: NSDateFormatterShortStyle];
        self.sendButton.title    = NSLocalizedString(@"Save Alert", @"button label for saving an alert");
        self.alert.sendNow       = NO;
    }
    self.alert.scheduledDate     = scheduledDate;
    DDLogInfo(@"Date Picker: %@", scheduledDate);
}

也在newalerttableviewcontroller.m中,我们有这个代表来处理时区拾取器视图:

- (void) pickerView: (UIPickerView *)pickerView didSelectRow: (NSInteger)row inComponent: (NSInteger)component {
    NSString *timeZone;
    NSString *timeZoneCity;
    NSDateFormatter *systemTimeZoneFormatter = [NSDateFormatter new];
    systemTimeZoneFormatter.timeZone         = [NSTimeZone localTimeZone];
    systemTimeZoneFormatter.dateFormat       = @"Z";
    NSString *systemTimeZoneOffset           = [systemTimeZoneFormatter stringFromDate: [NSDate date]];
    switch (row) {
        case 0:
            timeZone     = (@"GMT%@", systemTimeZoneOffset);
            timeZoneCity = @"Device Default";
            break;
        case 1:
            timeZone     = @"GMT+02:00";
            timeZoneCity = @"Berlin";
            break;
        case 2:
            timeZone     = @"GMT+01:00";
            timeZoneCity = @"London";
            break;
        case 3:
            timeZone     = @"GMT-04:00";
            timeZoneCity = @"New York";
            break;
        case 4:
            timeZone     = @"GMT-05:00";
            timeZoneCity = @"Chicago";
            break;
        case 5:
            timeZone     = @"GMT-06:00";
            timeZoneCity = @"Denver";
            break;
        case 6:
            timeZone     = @"GMT-07:00";
            timeZoneCity = @"Los Angeles";
            break;
        case 7:
            timeZone     = @"GMT-08:00";
            timeZoneCity = @"Anchorage";
            break;
        case 8:
            timeZone     = @"GMT-10:00";
            timeZoneCity = @"Honolulu";
            break;
        default:
            break;
    }
    [self updateTimeZone: timeZone];
    [[NSUserDefaults standardUserDefaults] setObject: timeZone forKey: @"timeZonePreference"];
    DDLogInfo(@"Time Zone Picker: %@, %@", timeZone, timeZoneCity);
    _timeZoneLabel.text = timeZoneCity;
}

再次在newalerttableviewcontroller.m中,此功能更新时区:

- (void) updateTimeZone: (id)timeZone {
    self.now                     = [NSDate date];    
    self.calendar                = [[NSCalendar alloc] initWithCalendarIdentifier: NSCalendarIdentifierGregorian];
    [self.calendar setTimeZone: [NSTimeZone timeZoneWithName: timeZone]];
    NSCalendarUnit units         = NSCalendarUnitHour;
    NSDateComponents *components = [self.calendar components: units fromDate: self.now];
    self.hours                   = (int)[components hour];
    self.alert.calendar          = self.calendar;
}

在警报中,我们有此字符串作为参数发送到我们的createAlert.aspx端点。理想情况下,我们希望将所有字符串调整为中央日光时间(要匹配我们在德克萨斯州休斯顿的服务器(或至少协调通用时间(UTC(。

- (NSString *)scheduledDateString { // This method solely uses the scheduledDate
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.dateFormat       = @"yyyy-MM-dd HH:mm:ss Z";
    dateFormatter.timeZone         = self.calendar.timeZone;
    NSString *dateString           = [dateFormatter stringFromDate: self.scheduledDate];
    DDLogInfo(@"Scheduled Date: %@", dateString);
    return dateString;
}

这是一些要播放的示例代码:

// User-selected Time Zone city
// using "Europe/Berlin" for this example
NSString *timeZoneName = @"Europe/Berlin";
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:timeZoneName];
// User-selected Date/Time (from the UIDatePicker)
NSDate *selDate = _datePicker.date;
// Current NSCalendar
NSCalendar *calendar = [NSCalendar currentCalendar];
// get all date components from the user-selected Date/Time
NSDateComponents *localComponents = [calendar components:-1 fromDate:selDate];
// set the Calendar to use the user-selected Time Zone
[calendar setTimeZone: timeZone];
// set the components with the values from localComponents
NSDateComponents *timeZoneComponents = [[NSDateComponents alloc] init];
[timeZoneComponents setYear:    [localComponents year]];
[timeZoneComponents setMonth:   [localComponents month]];
[timeZoneComponents setDay:     [localComponents day]];
[timeZoneComponents setHour:    [localComponents hour]];
[timeZoneComponents setMinute:  [localComponents minute]];
[timeZoneComponents setSecond:  [localComponents second]];
// get a NSDate object based on the user-selected Date/Time and Time Zone
// Note: if you print the default description of this date, it will show UTC value
NSDate *desiredDateTime = [calendar dateFromComponents:timeZoneComponents];
NSLog(@"%@", desiredDateTime);

要记住的关键是,无论您在伦敦,纽约,休斯顿,檀香山,东京,柏林等。

例如:现在,几乎是下午5:00。但是,等等,当您阅读本文时,它可能在> 4:00 pm > !!!怎么可能?好吧,我现在看[NSDate date];,我看到" 2017-06-07 20:55:56 0000" - 因为那是"绝对"日期/时间。

所以,使用此代码示例...尝试不同的时区(确保您正确获取名称(...看看这是否有意义。

如果我做正确的事(我可能会在这里有一个或两个错误(...如果您在6月16日星期五在您的约会选择器中选择了(无论世界上何处是(,然后运行此代码,最终的NSLog()应该 print:

2017-06-16 08:00:25 +0000

因为UTC比柏林时间早2小时。

感谢 @donmag 的精明建议,我在家里!现在使用此新的NewAlerttableViewController.m时区Picker视图委托:

获得完美的NSDATES:
- (void) pickerView: (UIPickerView *)pickerView didSelectRow: (NSInteger)row inComponent: (NSInteger)component {
    NSString *timeZoneName;
    NSString *timeZoneLabel;
    NSDateFormatter *systemTimeZoneFormatter = [NSDateFormatter new];
    systemTimeZoneFormatter.timeZone         = [NSTimeZone localTimeZone];
    systemTimeZoneFormatter.dateFormat       = @"VVVV";
    NSString *systemTimeZoneOffset           = [systemTimeZoneFormatter stringFromDate: [NSDate date]];
    switch (row) {
        case 0:
            timeZoneName  = ("%@", systemTimeZoneOffset);
            timeZoneLabel = @"Device Default";
            break;
        case 1:
            timeZoneName  = @"Europe/Berlin";
            timeZoneLabel = @"Berlin";
            break;
        case 2:
            timeZoneName  = @"Europe/London";
            timeZoneLabel = @"London";
            break;
        case 3:
            timeZoneName  = @"America/New_York";
            timeZoneLabel = @"New York";
            break;
        case 4:
            timeZoneName  = @"America/Chicago";
            timeZoneLabel = @"Chicago";
            break;
        case 5:
            timeZoneName  = @"America/Denver";
            timeZoneLabel = @"Denver";
            break;
        case 6:
            timeZoneName  = @"America/Los_Angeles";
            timeZoneLabel = @"Los Angeles";
            break;
        case 7:
            timeZoneName  = @"America/Anchorage";
            timeZoneLabel = @"Anchorage";
            break;
        case 8:
            timeZoneName  = @"Pacific/Honolulu";
            timeZoneLabel = @"Honolulu";
            break;
        default:
            break;
    }
    [self updateTimeZone: timeZoneName];
    _timeZoneLabel.text                  = timeZoneLabel;
    NSTimeZone *timeZone                 = [NSTimeZone timeZoneWithName: timeZoneName];
    DDLogInfo(@"Time Zone Picker: %@", timeZoneName);
    NSDate *datePickerSelection          = _datePicker.date;
    NSCalendar *calendar                 = [NSCalendar currentCalendar];
    NSDateComponents *localComponents    = [calendar components: -1 fromDate: datePickerSelection];
    [calendar setTimeZone: timeZone];
    NSDateComponents *timeZoneComponents = [[NSDateComponents alloc] init];
    [timeZoneComponents setYear:    [localComponents year]];
    [timeZoneComponents setMonth:   [localComponents month]];
    [timeZoneComponents setDay:     [localComponents day]];
    [timeZoneComponents setHour:    [localComponents hour]];
    [timeZoneComponents setMinute:  [localComponents minute]];
    [timeZoneComponents setSecond:  [localComponents second]];
    _desiredDateTime                     = [calendar dateFromComponents: timeZoneComponents];
    DDLogInfo(@"Desired Date: %@", _desiredDateTime);
}

最新更新