Как быстро преобразовать timeIntervalSinceNow в удобочитаемую дату

Привет, я пытаюсь найти временной интервал между определенной датой и текущим местным временем.

var a = eventDate.timeIntervalSinceNow
println(a)
//1404567.32182503 - output

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

Я хочу рассчитать количество оставшихся дней, часов, минут. Я не хочу Годы, месяцы, Секунды.

ДОЛЖЕН: мне нужен временной интервал между датой события и местным временем. Не время UTC.

Вот полный код:

//eventDate is 2015-09-01 19:39 
var date = NSDate();
var dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "YYY-MM-dd HH:mm:ss ZZZZ"
    dateFormatter.timeZone = NSTimeZone()
    var localDateString = dateFormatter.stringFromDate(date)
var localDate: NSDate = dateFormatter.dateFromString(localDateString)!

var components = NSCalendar.currentCalendar().components(.CalendarUnitSecond |
        .CalendarUnitMinute | .CalendarUnitHour | .CalendarUnitDay |
        .CalendarUnitMonth | .CalendarUnitYear, fromDate: localDate,
        toDate:  self.eventDate, options: nil)

println("\(components.day) days \(components.hour) hours \(components.minute) minutes")

16 days 5 hours 41 minutes //Origianl output
16 days 0 hours 11 minutes // Expected output

Я думаю, что столкнулся с этой проблемой из-за изменения времени UTC!


person AAA    schedule 16.08.2015    source источник
comment
Подсказка: используйте NSCalendar и NSDateComponents. Должно быть несколько примеров на SO и в Интернете.   -  person Martin R    schedule 16.08.2015
comment
Пытался. Но получаю неверное значение, потому что, если я указываю местное время, оно занимает время UTC, несмотря ни на что!   -  person AAA    schedule 16.08.2015
comment
Покажите, что вы пробовали, вместе с вашими входными данными, фактическим результатом и ожидаемым результатом.   -  person Martin R    schedule 16.08.2015
comment
@MartinR, пожалуйста, посмотрите на отредактированный вопрос   -  person AAA    schedule 16.08.2015
comment
Строка dateFormat неверна. Покажите пример исходной строки даты. По крайней мере, я бы использовал yyyy, а не YYY.   -  person Rob    schedule 16.08.2015
comment
Ваш пример не является самодостаточным, self.eventDate не определен. И почему вы конвертируете date в строку и обратно, используя тот же форматтер?   -  person Martin R    schedule 16.08.2015
comment
[ //eventDate 2015-09-01 19:39 ] я получаю его от Parse   -  person AAA    schedule 16.08.2015
comment
Этот часовой пояс является местным временем. Гринвич +0530   -  person AAA    schedule 16.08.2015
comment
@MartinR Нет, он по-прежнему дает разницу во времени между eventDate и временем UTC. Мне нужна разница во времени между eventDate и моим местным временем   -  person AAA    schedule 16.08.2015
comment
@AAA: Пожалуйста, добавьте к вашему вопросу вывод println(date) и println(self.eventDate).   -  person Martin R    schedule 16.08.2015
comment
Это даст дату UTC и eventDate. Как я могу получить localDate как NSDate?   -  person AAA    schedule 16.08.2015


Ответы (1)


Пара мыслей:

  1. #P2#
    let formatter = DateComponentsFormatter()
    formatter.allowedUnits = [.day, .hour, .minute]
    formatter.unitsStyle = .full
    let string = formatter.string(from: date1, to: date2)
    
    #P3#
    let formatter = NSDateComponentsFormatter()
    formatter.allowedUnits = [.Day, .Hour, .Minute]
    formatter.unitsStyle = .Full
    let string = formatter.stringFromDate(date1, toDate: date2)
    
    #P4#
    #P5#
    #P6#
  2. #P7# <блочная цитата> #P8# #P9# #P10#
  3. В комментариях вы продолжаете задавать разные варианты одного и того же вопроса: «Как мне сравнивать даты в моем местном часовом поясе?», На что вы отвечаете «нет». Даты не имеют часовых поясов. Строки даты подходят, а объекты NSDate — нет.

    Если вы выполняете print из Date/NSDate объектов, они обычно отображаются по Гринвичу (вы обычно видите +0000 после даты, подтверждая этот факт). Если вы хотите увидеть их в своем местном часовом поясе, используйте DateFormatter и используйте string(from:) (или в Swift 2, NSDateFormatter и используйте stringFromDate()).

    Но нет смысла использовать этот механизм stringFromDate (другой чисто для диагностических целей), чтобы увидеть эти даты в вашем местном часовом поясе. Нет такой вещи, как «разница между двумя объектами NSDate в моем местном часовом поясе». Объекты NSDate указывают на один момент времени во всем мире, а NSTimeZone необходим только в том случае, если вы хотите, чтобы этот момент времени отображался в виде строкового представления для вашего местного часового пояса.

Суть в том, что проблема заключается не в вычислении времени, прошедшего между двумя объектами NSDate, а в том, как вы сами создали эти объекты NSDate. Более чем вероятно, что исходная строка из синтаксического анализа (которой вы по какой-то причине не хотите делиться с нами) находится не в том часовом поясе, как вы думаете.

Наиболее распространенная ошибка, которую совершают люди, заключается в том, что они предполагают, что строка находится в их местном часовом поясе, тогда как она неизменно находится в GMT/UTC/Zulu, если в строке даты явно не указано иное (например, +0530). (Это ужасный дизайн, когда даты отчетов веб-службы указываются в местном часовом поясе без квалификатора часового пояса, поэтому, надеюсь, вы этого не делаете.)

person Rob    schedule 16.08.2015
comment
Но это также не учитывает переходы на летнее время (поскольку информация теряется в timeIntervalSinceNow). Было бы лучше сначала вычислить NSDateComponents между датами. - person Martin R; 16.08.2015
comment
да, он показывает правильно, но по отношению к моему местному времени он должен отображать: 16 дней, 5 часов 39 минут! так как мое время GMT+05:30 - person AAA; 16.08.2015
comment
@MartinR Я не согласен. Если вы ищете время, прошедшее между eventDate и настоящим моментом, timeIntervalSinceNow действительно отражает переход на летнее время. Если результаты неверны, проблема заключается в исходной строке даты или средстве форматирования, используемом для преобразования ее в NSDate. К сожалению, не видя подробного примера с исходной строкой, трудно ставить дальнейшие диагнозы. - person Rob; 16.08.2015
comment
Если я использую stringFromDate(localDate), я получаю правильную локальную дату и время в виде строки. Как я могу изменить это снова на сегодняшний день? Если я использую dateFromString, оно снова меняется на время по Гринвичу!!! - person AAA; 16.08.2015
comment
Без обид, но вся эта дискуссия предполагает фундаментальное заблуждение об NSDate объектах. Объекты даты не имеют часового пояса. Часовой пояс используется при преобразовании строк в даты и обратно, но сами объекты NSDate не имеют часового пояса. Мы не можем диагностировать проблему, не видя исходной строки. - person Rob; 16.08.2015
comment
@Rob: я исправляю свой комментарий. Кажется, что NSDateComponentsFormatter принимает текущую дату в качестве отправной точки, поэтому в этом случае он будет работать правильно. Как правило, если вы хотите отобразить дни/часы/минуты между двумя произвольными датами, было бы лучше вычислить разницу как NSDateComponents, а не как NSTimeInterval. - person Martin R; 16.08.2015
comment
... например, NSTimeInterval с 2015-10-24 00:00 до 2015-10-25 00:00 в часовом поясе Германии составляет 90000,0 секунд = 25 часов, а NSDateComponentsFormatter будет отображать это как 1 день + 1 час. - person Martin R; 16.08.2015
comment
@Rob: Теперь я не согласен :) NSDateComponentsFormatter имеет два метода: stringFromDateComponents и stringFromTimeInterval. Последний принимает временной интервал и не знает, когда этот временной интервал имел место, и поэтому не может знать, являются ли 90000 секунд точно одним днем ​​(как в примере моего предыдущего комментарий) или 1 день плюс 1 час. – Между прочим, в заголовке NSDateComponentsFormatter есть комментарий Обычно NSDateComponentsFormatter будет считать, как если бы отсчитывал от текущей даты и времени... - person Martin R; 16.08.2015
comment
@MartinR Хорошо, да, теперь я понимаю твою точку зрения. Да, я согласен, что вам не следует использовать NSTimeInterval. Но вам также не следует заморачиваться с NSDateComponents (если вам действительно не нужны отдельные компоненты). Я думаю, что stringFromDate:toDate: проще всего. - person Rob; 16.08.2015