Получить время 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.
Ответы
Ответ 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");