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

Objective-C, Как я могу получить текущую дату в часовом поясе UTC?

Я пытаюсь:

NSDate *currentDateInLocal = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:SS.SSS'Z'"];
NSString *currentLocalDateAsStr = [dateFormatter stringFromDate:currentDateInLocal];

NSDateFormatter * dateFormatter2 = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
[dateFormatter2 setTimeZone:timeZone];
[dateFormatter2 setDateFormat:@"yyyy-MM-dd'T'HH:mm:SS.SSS'Z'"];
NSDate *currentDateInUTC = [dateFormatter2 dateFromString:currentLocalDateAsStr];

но он все еще не отражает текущее время UTC, как я могу это достичь?

Спасибо

4b9b3361

Ответ 1

NSDate *currentDate = [[NSDate alloc] init];

Теперь это в UTC (по крайней мере, после использования метода ниже)
Чтобы сохранить это время как UTC (начиная с даты 1970 года), используйте

double secsUtc1970 = [[NSDate date]timeIntervalSince1970];

Установите формат даты для вывода локального времени:

NSTimeZone *timeZone = [NSTimeZone defaultTimeZone];
// or Timezone with specific name like
// [NSTimeZone timeZoneWithName:@"Europe/Riga"] (see link below)
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:timeZone];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSString *localDateString = [dateFormatter stringFromDate:currentDate];

Доступные имена NSTimeZone

Объект A NSDate всегда использует UTC как ссылку на время, но строковое представление даты не обязательно основано на часовом поясе UTC.

Обратите внимание, что UTC не является (только) часовым поясом, это система измерения времени на Земле, как она координируется (C в UTC означает согласование).
NSDate связан со ссылкой на дату полуночи 1.1.1970 UTC, немного ошибочно описанную Apple как 1.1.1970 GMT.

В исходном вопросе последнее слово timeZone не является совершенным.

Ответ 2

Вы слишком сложны.

NSDate не имеют часовых поясов или календарей. [NSDate date] получает текущую дату, которая является измерением момента в истории. Если я запускаю [NSDate date] в Европе точно в то же время, когда вы запускаете его в Америке, мы получим точно такое же значение.

Как вы печатаете дату, зависит от календаря и часового пояса. Таким образом, дата, напечатанная в григорианском календаре, отличается от даты, напечатанной в юлианском календаре. И дата, напечатанная в гридском календаре UTC, отличается от даты, напечатанной в григорианском календаре PST. Но они все еще на той же дате.

Итак, вы хотите перейти прямо к своему dateFormatter2.

Ответ 3

Принятый ответ от Alex Wien является неправильным.

По умолчанию NSDateFormatter настраивает значение даты-времени NSDates из UTC в локальный часовой пояс пользователя. Чтобы предотвратить эту настройку, скажите NSDateFormatter использовать часовой пояс для UTC.

Чтобы проверить результаты, google "текущее время utc".

Мой исходный код ниже должен выполнить задание, то есть получить текущую дату-время в виде строки в ISO 8601 format в UTC (Zulu) часовой пояс, обозначенный Z на конце.

NSDate* datetime = [NSDate date];
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; // Prevent adjustment to user local time zone.
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSString* dateTimeInIsoFormatForZuluTimeZone = [dateFormatter stringFromDate:datetime];

Вы можете поместить эту логику в пару удобных методов где-нибудь в своем приложении.

- (NSString*)now
{
    // Purpose: Return a string of the current date-time in UTC (Zulu) time zone in ISO 8601 format.
    return [self toStringFromDateTime:[NSDate date]];
}

... и...

- (NSString*)toStringFromDateTime:(NSDate*)datetime
{
    // Purpose: Return a string of the specified date-time in UTC (Zulu) time zone in ISO 8601 format.
    // Example: 2013-10-25T06:59:43.431Z
    NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
    [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
    NSString* dateTimeInIsoFormatForZuluTimeZone = [dateFormatter stringFromDate:datetime];
    return dateTimeInIsoFormatForZuluTimeZone;
}

Пример использования...

NSString* now = [self now];

Или превратите эти знаки минус в знаки плюс, чтобы использовать их как методы класса, а не методы экземпляров...

NSString* now = [SomeClassNameHere now];

Совет. Для лучшей читаемости людьми измените это значение T в формате SPACE. Для лучшей совместимости с программным обеспечением держите T. Спецификация ISO 8601 допускает пробел, но рекомендует сохранять T.


Совет. Я не тестировал, но... Некоторые говорят, что экземпляр [NSDateFormatter][4] стоит дорого. Если вы так часто (например, в цикле) часто используете кеширование одного экземпляра для повторного использования.

Ответ 4

ПОЖАЛУЙСТА, НАСТРОЙИТЕ Идентификатор календаря!!!

Я не слишком поздно! Поскольку я не видел, чтобы кто-то настраивал Идентификатор календаря. действительно важно для пользователей во всем мире. Многие пользователи используют не григорианский календарь. Они получат неправильную строку года. Особенно, когда вам нужно хранить его в своей собственной базе данных. (Раньше мы встречали эту проблему)

NSCalendarIdentifierGregorian
NSCalendarIdentifierBuddhist
NSCalendarIdentifierChinese
NSCalendarIdentifierHebrew
NSCalendarIdentifierIslamic
NSCalendarIdentifierIslamicCivil
NSCalendarIdentifierJapanese
NSCalendarIdentifierRepublicOfChina
NSCalendarIdentifierPersian
NSCalendarIdentifierIndian
NSCalendarIdentifierISO8601

Код:

-(NSString *)getUTCFormateDate:(NSDate *)localDate
{
    NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
    NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
    [dateFormatter setCalendar:gregorianCalendar];
    [dateFormatter setTimeZone:timeZone];
    [dateFormatter setLocale:locale];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSString *dateString = [dateFormatter stringFromDate:localDate];
    return dateString;
}  

Ответ 5

[NSDate date] - UTC. Может быть, вас обманули, глядя на локальных жителей? Затем он преобразуется в ваш часовой пояс.

Если вы видите значение в локалях, вы увидите его по местному времени, но если вы распечатаете его в консоли, вы увидите его в формате UTC.

Когда вы увидите "+0000" по истечении времени, вы знаете, что оно находится в формате UTC

Ответ 6

Еще один способ сделать это, как и в классе С++ в вашем проекте Objective C. (Итак, создайте файл .mm и создайте класс С++ с общедоступными и частными частями и придерживайтесь его в публичной части (если вам не нужна его частная). Затем укажите ссылку как NSString *sNowUTC = MyClass::getUTCTimestamp();.

static NSString *getUTCTimestamp(){
  time_t rawtime;
  struct tm * timeinfo;
  char buffer [80];
  time (&rawtime);
  timeinfo = gmtime (&rawtime);
  // make format like "2016-06-16 02:37:00" for 
  //   June 16, 2016 @ 02:37:00 UTC time
  strftime (buffer,80,"%F %T",timeinfo);
  std::string sTime(buffer);
  NSString *sUTC = @(sTime.c_str());
  return sUTC;
}

Ответ 7

Это то, что я использовал.

static func makeISO8601Date(isoDateString: String) -> Date {
    let formatter = DateFormatter()
    formatter.calendar = Calendar(identifier: .iso8601)
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"

    return formatter.date(from: isoDateString)
}

makeISO8601Date(isoDateString: "2017-12-31T23:59:59+00:00")

Ответ 8

Swift 3

let utcTimestamp = Date().timeIntervalSince1970
print("timeStamp = \(utcTimestamp)")