Простой пример с использованием 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; ( ));
NSDateFormatter использует текущий часовой пояс устройства, когда он создал объект NSDate. NSDate хранит дату / время в GMT. Поэтому по умолчанию NSLog выводит дату / время в GMT + 0. Итак, в коде нет ничего плохого. Теперь, если вы хотите вывести NSDate в текущий часовой пояс, вам придется использовать объект NSDateFormatter.
Используйте -[NSDateFormatter setTimeZone:]
, чтобы предоставить формат даты с информацией о часовом поясе. Вы можете использовать местный часовой пояс или если у вас есть фиксированный часовой пояс, связанный с информацией о дате, я рекомендую создать часовой пояс с именем (например, «Америка / Восток»), а не аббревиатурой (например, «EST» или «EDT»), поскольку имя не вносит эффект летнего времени в силу, но использует правильное смещение дневного света для этой даты в этом часовом поясе.
Дата записывается как дата UTC, которую можно увидеть в конце +0000
. Формат даты, который вы используете для синтаксического анализа строки, предполагает ваш местный часовой пояс, который предположительно на 4 часа ниже UTC с летней экономией и стандартным -5 часов.
Ответ коротким: 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.
}
}
Ваши данные и формат даты опускают спецификатор 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.