2013-05-30 3 views
5

Я имею дело с плохо запрограммированной 3 партией API, которая заставляет меня массировать некоторые данные о дате/времени в Objective C.Как определить, является ли конкретная дата летним временем или нет?

Вместо возвращении даты как абсолютные отметки времени UNIX в UTC, он возвращает даты как форматные строки без информации о часовом поясе. (На самом деле получается, после разговора с одним из их разработчиков, что они фактически хранят дату/время в своей базе данных как строку без информации о часовом поясе, а не как временную метку!). Серверы находятся где-то посередине США, поэтому в настоящее время на CDT, поэтому теоретически я могу просто добавить «CDT» в отформатированные даты и использовать NSDateFormatter (yyyy-MM-dd HH:mm:ss zzz) для создания NSDate. Однако, в зависимости от времени года, в которое приходит данная дата, это может быть в КНТ или CDT.

Как определить, действует ли летнее время в эту конкретную дату, чтобы я мог добавить правильный часовой пояс и вычислить правильную дату UTC?

ответ

6

Ну, я не думаю, что это правильный способ сделать это. Есть интерфейсы API для этого, таких как:

[NSTimeZone isDaylightSavingTimeForDate:] и [NSTimeZone daylightSavingTimeOffsetForDate:]

НО При переходе от CDT к ДКБУ, один час будут повторяться, так что нет никакого способа узнать, является ли это CDT или CST. Кроме того, один час, предполагающий КНТ и проверку на летнее время, должен работать. Мое предложение состоит в том, чтобы установить, кто писал этот API.

+0

Right-- лучшим вариантом является изменение API. К сожалению, я не могу это сделать. Есть ли способ получить NSTimeZone из NSDate? Таким образом, я могу использовать метод isDaylightSavingsTimeForDate:. – Jason

+1

@ Джейсон Будьте очень осторожны. NSDate не имеет ничего общего с NSTimeZone (у Unix-марок есть часовой пояс? Нет, и по той же причине). Часовой пояс относится к дате * formatter *, а не к самой дате. Итак, как я уже говорил выше, просто предположите, что CST (создайте часовой пояс с этим сокращением), установите этот часовой пояс на форматирование и создайте объект NSDate с помощью форматирования. Он будет работать, за исключением повторения одного часа. Если действует летнее время, отрегулируйте NSDate соответствующим образом. – borrrden

+0

Я согласен с тем, что один час повторяется во время перехода на летнее время. Без какой-либо другой информации из API вы можете только догадываться, какая из двух она может быть, и вы можете ошибаться. –

0

Я думаю, что у меня есть решение:

NSString *originalDateString = <ORIGINAL DATE FROM API>; 

    NSDateFormatter *dateStringFormatter = [[NSDateFormatter alloc] init]; 
    dateStringFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss zzz"; 

    NSString *tempDateString = [originalDateString stringByAppendingFormat:@" CST"]; 

    // create a temporary NSDate object 
    NSDate *tempDate = [dateStringFormatter dateFromString:tempDateString]; 

    // get the time zone for this NSDate (it may be incorrect but it is an NSTimeZone object) 
    NSDateComponents *components = [[NSCalendar currentCalendar] 
            components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSTimeZoneCalendarUnit 
            fromDate:tempDate]; 
    NSTimeZone *tempTimeZone = [components timeZone]; 

    // Find out if the time zone of the temporary date 
    // (in CST or CDT depending on the local time zone of the iOS device) 
    // **would** use daylight savings time for the date in question, and 
    // select the proper time zone 
    NSString *timeZone; 
    if ([tempTimeZone isDaylightSavingTimeForDate:tempDate]) { 
     timeZone = @"CDT"; 
    } else { 
     timeZone = @"CST"; 
    } 

    NSString *finalDateString = [originalDateString stringByAppendingFormat:@" %@", timeZone]; 
+1

Будьте осторожны с сокращениями часового пояса. Я не совсем уверен, как работает iOS, но есть много зон с теми же аббревиатурами. Вы можете увидеть список [здесь] (http://www.timeanddate.com/library/abbreviations/timezones/). Например, CST может означать «Китайское стандартное время» ... –

+2

Интересно, можете ли вы просто передать зону id 'America/Chicago' вместо этого? Если это так, вам, вероятно, не придется самостоятельно проверять 'isDaylightSavingsTimeForDate'. Это, вероятно, сделает это внутренне. (Я просто догадываюсь - я не разработчик iOS/ObjectiveC) –

+0

@MattJohnson Это не имеет смысла для этого API, так как «Америка/Чикаго» будет зависеть от даты, а часового пояса - нет. Кроме того, более быстрый способ для этого API вместо создания других форматировщиков, просто добавьте 'daylightSavingTimeOffsetForDate:' к дате, которую вы создаете в 'tempDate'. Он будет равен нулю, если летнее время не будет действовать. – borrrden

Смежные вопросы