Подтвердить что ты не робот

Получить время UTC и местное время от объекта NSDate

В objective-c следующий код приводит к информации о времени по дате UTC с использованием API date.

NSDate *currentUTCDate = [NSDate date]

Однако в Swift

let date = NSDate.date()

приводит к локальным датам и времени.

У меня есть два вопроса:

  • Как я могу получить время UTC и местное время (хорошо date дает местное время) в объектах NSDate.
  • Как получить точность в секундах от объекта NSDate.

EDIT 1: Спасибо за все входные данные, но я не ищу объекты NSDateFormatter или строковые значения. Я просто ищу объекты NSDate (однако мы их готовим, но это требование).
См. Пункт 1.

4b9b3361

Ответ 1

В документации указано, что метод date возвращает новую дату, установленную на текущую дату и время независимо от используемого языка.

Проблема, вероятно, находится где-то, где вы указываете дату, используя NSDateFormatter. NSDate - это всего лишь точка на временной линии. Нет часовых поясов, когда речь идет о NSDate. Я сделал тест.

Swift

print(NSDate())

Выход: 2014-07-23 17:56:45 +0000

Objective-C

NSLog(@"%@", [NSDate date]);

Выход: 2014-07-23 17:58:15 +0000

Результат - Нет разницы.

Ответ 2

NSDate - это конкретный момент времени без часового пояса. Подумайте об этом как о количестве секунд, прошедших со времени отсчета. Сколько секунд прошло в одном часовом поясе против другого с определенной контрольной даты? Ответ одинаков.

В зависимости от того, как вы выводите эту дату (включая просмотр отладчика), вы можете получить ответ в другом часовом поясе.

Если они выполнялись в тот же момент, значения этих параметров одинаковы. Они равны числу секунд со времени отсчета, которое может быть отформатировано на выходе в формате UTC или по местному времени. В переменной даты они оба являются UTC.

Objective-C:

NSDate *UTCDate = [NSDate date]

Swift:

let UTCDate = NSDate.date()

Чтобы объяснить это, мы можем использовать NSDateFormatter на игровой площадке:

import UIKit

let date = NSDate.date()
    // "Jul 23, 2014, 11:01 AM" <-- looks local without seconds. But:

var formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
let defaultTimeZoneStr = formatter.stringFromDate(date)
    // "2014-07-23 11:01:35 -0700" <-- same date, local, but with seconds
formatter.timeZone = NSTimeZone(abbreviation: "UTC")
let utcTimeZoneStr = formatter.stringFromDate(date)
    // "2014-07-23 18:01:41 +0000" <-- same date, now in UTC

Выход даты меняется, но дата постоянна. Это именно то, что вы говорите. Нет такой вещи, как локальный NSDate.

Что касается того, как вывести микросекунды, вы можете использовать это (поместите его в нижнюю часть той же площадки):

let seconds = date.timeIntervalSince1970
let microseconds = Int(seconds * 1000) % 1000 // chops off seconds

Чтобы сравнить две даты, вы можете использовать date.compare(otherDate).

Ответ 3

Xcode 9 • Swift 4 (также работает Swift 3.x)

extension Formatter {
    // create static date formatters for your date representations
    static let preciseLocalTime: DateFormatter = {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.dateFormat = "HH:mm:ss.SSS"
        return formatter
    }()
    static let preciseGMTTime: DateFormatter = {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.timeZone = TimeZone(secondsFromGMT: 0)
        formatter.dateFormat = "HH:mm:ss.SSS"
        return formatter
    }()
}

extension Date {
    // you can create a read-only computed property to return just the nanoseconds from your date time
    var nanosecond: Int { return Calendar.current.component(.nanosecond,  from: self)   }
    // the same for your local time
    var preciseLocalTime: String {
        return Formatter.preciseLocalTime.string(for: self) ?? ""
    }
    // or GMT time
    var preciseGMTTime: String {
        return Formatter.preciseGMTTime.string(for: self) ?? ""
    }
}

Тестирование игровой площадки

Date().preciseLocalTime // "09:13:17.385"  GMT-3
Date().preciseGMTTime   // "12:13:17.386"  GMT
Date().nanosecond       // 386268973

Это может помочь вам также отформатировать даты:

enter image description here

Ответ 4

дата не зависит от какого-либо часового пояса, поэтому используйте Dateformatter и привяжите часовой пояс для отображения:

скор:

let date = NSDate()
let dateFormatter = NSDateFormatter()
let timeZone = NSTimeZone(name: "UTC")

dateFormatter.timeZone = timeZone

println(dateFormatter.stringFromDate(date))

ObjC:

NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];

[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeZone:timeZone];       
NSLog(@"%@", [dateFormatter stringFromDate:date]);

Ответ 5

let date = Date() 
print(date) // printed date is UTC 

Если вы используете игровую площадку, используйте отчет о печати, чтобы проверить время. Детская площадка показывает местное время, пока вы его не распечатаете. Не зависит от правой боковой панели детской площадки. enter image description here

Этот код дает дату в UTC. Если вам нужно местное время, вы должны назвать следующий добавочный номер с часовым поясом как Timezone.current

 extension Date {

   var currentUTCTimeZoneDate: String {
        let formatter = DateFormatter()
        formatter.timeZone = TimeZone(identifier: "UTC")
        formatter.amSymbol = "AM"
        formatter.pmSymbol = "PM"
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

        return formatter.string(from: self)
    }
}

Для времени UTC используйте его следующим образом: Date().currentUTCTimeZoneDate

Ответ 6

В настоящий момент (с последними изменениями в Swift) NSDate.date() недоступен.

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

var d = NSDate()
d

и вы получите:

Oct 22, 2014, 12:20 PM"  

Ответ 7

Swift 3

Вы можете получить дату в соответствии с вашим текущим часовым поясом из UTC

extension Date {
    func currentTimeZoneDate() -> String {
        let dtf = DateFormatter()
        dtf.timeZone = TimeZone.current
        dtf.dateFormat = "yyyy-MM-dd HH:mm:ss"

        return dtf.string(from: self)
    }
}

Вызов:

Date().currentTimeZoneDate()

Ответ 8

Моя версия Xcode 6.1.1 (6A2008a)

В игровой площадке проведите тест следующим образом:

// I'm in East Timezone 8
let x = NSDate() //Output:"Dec 29, 2014, 11:37 AM"
let y = NSDate.init() //Output:"Dec 29, 2014, 11:37 AM"
println(x) //Output:"2014-12-29 03:37:24 +0000"


// seconds since 2001
x.hash //Output:441,517,044
x.hashValue //Output:441,517,044
x.timeIntervalSinceReferenceDate //Output:441,517,044.875367

// seconds since 1970
x.timeIntervalSince1970 //Output:1,419,824,244.87537

Ответ 9

Я нашел более простой способ получить UTC в Swift4. Поместите этот код в игровую площадку

let date = Date() 
*//"Mar 15, 2018 at 4:01 PM"*

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)

let newDate = dateFormatter.string(from: date) 
*//"2018-03-15 21:05:04 +0000"*

Ответ 10

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

 extension Date {

 func dateInTimeZone(timeZoneIdentifier: String, dateFormat: String) -> String  {
 let dtf = DateFormatter()
 dtf.timeZone = TimeZone(identifier: timeZoneIdentifier)
 dtf.dateFormat = dateFormat

 return dtf.string(from: self)
 }
}

Теперь вы можете назвать это как

 Date().dateInTimeZone(timeZoneIdentifier: "UTC", dateFormat: "yyyy-MM-dd HH:mm:ss");