2014-12-23 2 views
1

Я живу в Дании (UTC + 1), и я работаю с webapi, который отправляет мое приложение временную отметку unix с 1970-1-1 00:00:00. Время в будущем (поезд depatures) Если я проверить метку времени в цифрах или Excel дает мне правильное времяВремя Unix с NSDate показывает ошибочные результаты

Чтобы рассчитать количество минут, пока поезд отъездов я делаю так:

let unixTimeTrainDeparture = 1419327780 //(or some time in the future) 
let unixRightNow = NSDate().timeIntervalSince1970 
let minutesToDeparture = (Int(unixTimeTrainDeparture) - Int(unixRightNow))/60 

Однако это дает 60 минут слишком много?

И если я делаю

let dateTest = NSDate(string: "1970-01-01 00:00:00 +0000")! 

даст мне 1 января 1970 года: 01: 00: 00 +0000

Это не имеет смысла для меня. Это похоже на timeIntervalSince1970 дает мне 3600 секунд слишком меньше, так как оно начинается с 1970-1-101:00, а не 00:00? Это ошибка, или так оно и должно быть? Я могу исправить время, используя let tz = NSTimeZone.defaultTimeZone() let seconds = tz.secondsFromGMTForDate(NSDate()) , а затем вычитая секунды из моего результата. Однако, что происходит, когда мы двигаемся в летнее время?

ответ

3

timeIntervalSince1970 всегда дает время в GMT. Ваш unixTimeTrainDeparture, вероятно, время в GMT + 1, что объясняет 60-минутную разницу (или 120 минут в летнее время). То же самое происходит со строковым преобразованием - вы вводите время по Гринвичу, и оно выводит дату в любой часовой пояс, который вы настроили (я предполагаю, что настройки вашего компьютера также равны GMT + 1).

При работе с часовыми поясами всегда начинайте с GMT/UTC и не делайте никаких изменений в часовом поясе до отображения даты пользователю.

У вас есть контроль над веб-интерфейсом? Если это так - настройте его вместо GMT. Это должно полностью избежать проблем с часовым поясом и летнего времени.

Если вы не можете этого сделать, вам придется реализовать некоторую функцию, чтобы преобразовать временную метку самостоятельно, учитывая возможность того, что будущая временная метка может быть в другом часовом поясе (например, на летнее время). NSTimeZone может быть очень полезен для этого!

Надеюсь, я правильно понял вашу проблему!

Edit, добавлен пример, который должен обрабатывать DST:

// Date far in the future in DST, replace this 
let unixTimeTrainDeparture = NSDate(timeIntervalSince1970: 1436447418) 
let now = NSDate() 

// Assume unixTimeTrainDeparture is in the Copenhagen timezone 
let tz = NSTimeZone(name: "Europe/Copenhagen") 

// This is 3600 in non-DST, otherwise 7200 
let offset = tz!.secondsFromGMTForDate(unixTimeTrainDeparture) 

let realUnixTimeTrainDeparture = Int(unixTimeTrainDeparture.timeIntervalSince1970) - offset 

let timeToDeparture = realUnixTimeTrainDeparture - Int(now.timeIntervalSince1970) 
+0

Я не имею никакого контроля над WebAPI. Я также предположил, что время API было слишком большим на 3600 секунд, но почему же эта ошибка не появляется в моей таблице, где я делаю 1970-1-1 00:00:00 + ApiTimeStamp. Это должно, на мой взгляд, дать мне такое же смещение, но это не так. – user1700737

+0

Я добавил несколько примеров кода, он предполагает, что время, которое вы получаете от API, всегда находится в датском часовом поясе. – fkarlsson

+0

Привет. Да, это работает (с первого кода, который я представил), но мое беспокойство - это то, что произойдет, когда мы изменим время на летнее время. Мое предположение, что смещение вырастет до 7200. Но большое спасибо за вашу помощь! – user1700737

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