Преобразование даты с одного часового пояса в другой Swift [дубликат]

Простой пример с использованием std :: sort

  struct MyStruct {int key;  std :: string stringValue;  MyStruct (int k, const std :: string & amp; s): key (k), stringValue (s) {}};  struct less_than_key {inline bool operator () (const MyStruct & amp; struct1, const MyStruct & amp; struct2) {return (struct1.key & lt; struct2.key);  }};  std :: vector & lt;  MyStruct & gt;  VEC;  vec.push_back (MyStruct (4, "test"));  vec.push_back (MyStruct (3, "a"));  vec.push_back (MyStruct (2, "is"));  vec.push_back (MyStruct (1, «this»));  std :: sort (vec.begin (), vec.end (), less_than_key ());   

Редактировать: Как указал Кирилл В. Лядвинский, вместо предоставления предиката сортировки вы можете реализовать оператор & lt; для MyStruct [ ! d3]:

  struct MyStruct {int key;  std :: string stringValue;  MyStruct (int k, const std :: string & amp; s): key (k), stringValue (s) {} Оператор bool & lt;  (const MyStruct & amp; str) const {return (key & lt; str.key);  }};   

Используя этот метод, вы можете просто отсортировать вектор следующим образом:

  std :: sort (vec.begin (), vec.end ()  );   

Edit2: Как говорит Каппа, вы также можете отсортировать вектор в порядке убывания, перегрузив оператор & gt; и немного изменив вызов сортировки:

  struct MyStruct {int key;  std :: string stringValue;  MyStruct (int k, const std :: string & amp; s): key (k), stringValue (s) {} bool operator & gt;  (const MyStruct & amp; str) const {return (key & gt; str.key);  }};   

И вы должны вызвать сортировку как:

  std :: sort (vec.begin (), vec.end (), больше & lt; MyStruct & gt; (  ));   

8
задан jylee 3 June 2011 в 16:18
поделиться

5 ответов

NSDateFormatter использует текущий часовой пояс устройства, когда он создал объект NSDate. NSDate хранит дату / время в GMT. Поэтому по умолчанию NSLog выводит дату / время в GMT + 0. Итак, в коде нет ничего плохого. Теперь, если вы хотите вывести NSDate в текущий часовой пояс, вам придется использовать объект NSDateFormatter.

2
ответ дан Black Frog 16 August 2018 в 10:25
поделиться

Используйте -[NSDateFormatter setTimeZone:], чтобы предоставить формат даты с информацией о часовом поясе. Вы можете использовать местный часовой пояс или если у вас есть фиксированный часовой пояс, связанный с информацией о дате, я рекомендую создать часовой пояс с именем (например, «Америка / Восток»), а не аббревиатурой (например, «EST» или «EDT»), поскольку имя не вносит эффект летнего времени в силу, но использует правильное смещение дневного света для этой даты в этом часовом поясе.

1
ответ дан Jeremy W. Sherman 16 August 2018 в 10:25
поделиться

Дата записывается как дата UTC, которую можно увидеть в конце +0000. Формат даты, который вы используете для синтаксического анализа строки, предполагает ваш местный часовой пояс, который предположительно на 4 часа ниже UTC с летней экономией и стандартным -5 часов.

1
ответ дан JeremyP 16 August 2018 в 10:25
поделиться

Ответ коротким: Date возвращается GMT, если не указано иное. Вы можете установить часовой пояс, чтобы получить правильную дату. Если вы планируете использовать дату в приложении для установки чего-либо (например, localNotification time или Event), вам нужно будет сделать что-то особенное с датой, потому что если вы установите дату в iPhone, она будет установлена ​​как GMT и будет выключена на несколько часов. (в вашем случае 4 часа). Я делаю то, что я только что описал в одном из моих приложений.

Я сделал беспорядок, пытаясь заставить это работать правильно, не отпуская часы. Это была огромная PITA, чтобы разобраться, но теперь она работает. Я скопировал, вставил и отредактировал свой код для совместного использования. Опять же, его беспорядок, но он работает! Команда pickerChanged получает информацию от UIDatePicker

. Используя приведенный ниже код. Чтобы ответить на ваш вопрос, вы можете остановиться на «destinationDate». Это вернет вам исправленное время для вашего текущего часового пояса. Я просто предоставил дополнительный взнос, когда вы пытались использовать дату на телефоне где-то.

ПРИМЕЧАНИЕ. Для быстрого примера я помещаю напоминание о событии в ту же функцию, что и datepicker, вы НЕ хотите делать что в противном случае у вас будет много напоминаний, установленных каждый раз, когда колесики прокручиваются в datepicker.

Код ниже.

 - (void)pickerChanged:(id)sender
    {

        NSLog(@"value: %@",[sender date]);

        NSDate* date= [sender date]; 
        NSDateFormatter *formatter=[[[NSDateFormatter alloc]init]autorelease]; 
        [formatter setDateFormat:@"MM/dd/yyyy hh:mm:ss a"];
        [formatter setTimeZone:[NSTimeZone systemTimeZone]];

        [formatter setTimeStyle:NSDateFormatterLongStyle]; 

        NSString *dateSelected =[formatter stringFromDate:date]; 

        NSString *timeZone = [dateSelected substringFromIndex:12];



    NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];

    //here we have to get the time difference between GMT and the current users Date (its in seconds)
        NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:date];

    //need to reverse offset so its correct when we put it in the calendar
        correctedTimeForCalendarEvent = destinationGMTOffset + (2*(-1*destinationGMTOffset));

    //date to enter into calendar (we will use the correctedTimeForCalendarEvent to correct the time otherwise it will be off by a few hours )
       NSDate * destinationDate = [[[NSDate alloc] initWithTimeInterval:destinationGMTOffset sinceDate:date] autorelease];
        NSDate * dateForReminder = destinationDate;
        // return destinationDate;
        NSLog(@"value: %@ - %@",destinationDate,dateForReminder);

//DO NOT put this code in this same function this is for a quick example only on StackOverflow
//otherwise you will have reminders set everytime the users scrolled to a different time
    //set event reminder
    //make sure to import EventKit framework

        EKEventStore *eventDB = [[[EKEventStore alloc] init]autorelease];
        EKEvent *myEvent  = [EKEvent eventWithEventStore:eventDB];
        NSString * eventTitle = [NSString stringWithFormat:@"%@ - %@",app.dealerBusinessName,serviceOrComments.text];
        myEvent.title = eventTitle;

    //double check date one more time
        NSLog(@"value: %@",destinationDate);

    //set event time frame (1 hour) the "initWithTimeInterval" is where we account for the users timezone by adding the correctedTime from GMT to the calendar time ( so its not off by hours when entering into calendar)
        myEvent.startDate = [[[NSDate alloc] initWithTimeInterval:correctedTimeForCalendarEvent sinceDate:destinationDate ]autorelease];
        myEvent.endDate   = [[[NSDate alloc] initWithTimeInterval:3600 sinceDate:myEvent.startDate]autorelease];
        myEvent.allDay = NO;

    //set event reminders 1 day and 1 hour before
        myAlarmsArray = [[[NSMutableArray alloc] init] autorelease];
        EKAlarm *alarm1 = [EKAlarm alarmWithRelativeOffset:-3600]; // 1 Hour
        EKAlarm *alarm2 = [EKAlarm alarmWithRelativeOffset:-86400]; // 1 Day
        [myAlarmsArray addObject:alarm1];
        [myAlarmsArray addObject:alarm2];
        myEvent.alarms = myAlarmsArray;



        [myEvent setCalendar:[eventDB defaultCalendarForNewEvents]];

        NSError *err;

        [eventDB saveEvent:myEvent span:EKSpanThisEvent error:&err]; 

        if (err == noErr) {
            //no error, but do not show alert because we do that below.
        }

    }
5
ответ дан Louie 16 August 2018 в 10:25
поделиться

Ваши данные и формат даты опускают спецификатор TimeZone. Итак, что-то вроде этого:

[inputFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ssZ"];

Будет работать - Z является спецификатором часового пояса и будет анализировать как цифровые смещения, так и коды часовых поясов. Хотя в вашем случае, когда ваша дата ввода не имеет информации о TimeZone, она не будет работать.

Ваша правильная строка времени должна выглядеть как «2011-04-12 19:23:39 -0400» или «2011-04-12 19:23:39 EST»

В зависимости от на котором вы получаете свою дату, вы должны исправить это, чтобы создать полностью квалифицированную дату, если вы не можете этого сделать, вам придется согласовать смещения часового пояса с сервером или просто «жесткий код» смещения часового пояса и добавить это число секунд к вашему NSDate.

1
ответ дан Rog 16 August 2018 в 10:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: