2016-12-14 12 views
1

У меня есть объект NSDate, который я отправляю в API, который мы используем. Наше приложение используется по всему миру, так что API недостает даты, чтобы быть в UTC, например:Преобразование даты [NSDate] в локализованную строку даты UTC

"/Date(1481704200000)/" 

Однако дата должна быть временная зона смещения приняты во внимание, поскольку API/сервер не делает это для нас. Если мы этого не сделаем, дата будет неверной, если мы просмотрим ее на сервере.

Я делаю следующее, что, кажется, производят неверную дату:

// Offset 
float timezoneoffset = [[NSTimeZone localTimeZone] secondsFromGMT]; 

// Date 
CFTimeInterval startDate = [[NSDate date] timeIntervalSince1970]; 
startDate = startDate - timezoneoffset; 
NSString *dateStarted = [NSString stringWithFormat:@"/Date(%.0f000)/", startDate]; 

Как правильно взять местное время во внимание и создать правильно отформатированную строку даты UTC?

+1

времяIntervalSince1970 рассчитывается на UTC. Так что вам не нужно конвертировать. https://developer.apple.com/reference/foundation/nsdate/1407504-timeintervalsince1970 – Satachito

+0

Я думаю, что вы делаете ошибку во 2-й строке. Что вы получаете за NSLog с настройкой timezoneoffset? На самом деле, извините, моя ошибка ... –

ответ

4

Нет необходимости в манипулировании часовым поясом.

NSTimeInterval interval = [[NSDate date] timeIntervalSince1970]; 
NSString *dateStarted = [NSString stringWithFormat:@"/Date(%.0f)/", interval * 1000]; 

Это дает вам время в UTC независимо от часового пояса пользователя.

Попробуйте. Запустите этот код с несколькими различными настройками часового пояса на вашем тестовом устройстве, и вы получите одинаковый результат в каждом случае.

+0

Вам не хватает точки. Я понимаю, как создать строку с датой UTC. Но, как указано, из-за того, как API обрабатывает даты, мне нужно изменить время UTC в секундах и пересчитать это на основе смещения часового пояса. Либо добавление, либо вычитание секунд. Это был мой вопрос. –

+0

@NicHubbard Это не имеет смысла.Весь сервер должен знать, что все строковые значения указаны в UTC, и нет ничего особенного. – rmaddy

+0

Это имеет смысл, когда API имеет ошибку, которая делает это необходимым. –

0
NSDate *currentDate = [NSDate date]; 

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

double secsUtc1970 = [[NSDate date]timeIntervalSince1970]; 

Set Date форматировщик для вывода по местному времени :

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

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

Чтобы получить часовые пояса, вы можете использовать это:

NSTimeZone* timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; 
NSString* timeZoneName = [timeZone localizedName:NSTimeZoneNameStyleStandard locale:[NSLocale currentLocale]]; 
NSLog(@"Name : %@", timeZoneName); 

Если вы звоните [NSTimeZone abbreviationDictionary] вы получите словарь, содержащий все доступные сокращения.

NSLog(@"%@",[NSTimeZone abbreviationDictionary]); 

Результат:

2015-07-10 11:44:05.954 APP[1472:26120] { 
    ADT = "America/Halifax"; 
    AKDT = "America/Juneau"; 
    AKST = "America/Juneau"; 
    ART = "America/Argentina/Buenos_Aires"; 
    AST = "America/Halifax"; 
    BDT = "Asia/Dhaka"; 
    BRST = "America/Sao_Paulo"; 
    BRT = "America/Sao_Paulo"; 
    BST = "Europe/London"; 
    CAT = "Africa/Harare"; 
    CDT = "America/Chicago"; 
    CEST = "Europe/Paris"; 
    CET = "Europe/Paris"; 
    CLST = "America/Santiago"; 
    CLT = "America/Santiago"; 
    COT = "America/Bogota"; 
    CST = "America/Chicago"; 
    EAT = "Africa/Addis_Ababa"; 
    EDT = "America/New_York"; 
    EEST = "Europe/Istanbul"; 
    EET = "Europe/Istanbul"; 
    EST = "America/New_York"; 
    GMT = GMT; 
    GST = "Asia/Dubai"; 
    HKT = "Asia/Hong_Kong"; 
    HST = "Pacific/Honolulu"; 
    ICT = "Asia/Bangkok"; 
    IRST = "Asia/Tehran"; 
    IST = "Asia/Calcutta"; 
    JST = "Asia/Tokyo"; 
    KST = "Asia/Seoul"; 
    MDT = "America/Denver"; 
    MSD = "Europe/Moscow"; 
    MSK = "Europe/Moscow"; 
    MST = "America/Denver"; 
    NZDT = "Pacific/Auckland"; 
    NZST = "Pacific/Auckland"; 
    PDT = "America/Los_Angeles"; 
    PET = "America/Lima"; 
    PHT = "Asia/Manila"; 
    PKT = "Asia/Karachi"; 
    PST = "America/Los_Angeles"; 
    SGT = "Asia/Singapore"; 
    UTC = UTC; 
    WAT = "Africa/Lagos"; 
    WEST = "Europe/Lisbon"; 
    WET = "Europe/Lisbon"; 
    WIT = "Asia/Jakarta"; 
} 

Надеется, что это будет полезно.

-1
public let Date_format_Default:String = "yyyy-MM-dd HH:mm:ss" 

Установить эту строку формата для строки UTC;

public let Date_format_Z:String = "yyyy-MM-dd HH:mm:ssZ" 
public let Time_zone_UTC:String = "UTC" 

open class func convertDate2UTC(_ date:String)->(String){ 
    var df_:DateFormatter?=DateFormatter() 
    df_!.dateFormat=Date_format_Z 
    let tz_=TimeZone(identifier: Time_zone_UTC) 
    df_!.timeZone=tz_ 
    let df_s=df_!.date(from: date) 

    df_!.dateFormat=Date_format_Default 
    let string_=df_!.string(from: df_s!) 

    df_ = nil 
    return string_; 
} 
+0

1) У ОП нет строки даты, так что точка этого кода? 2) Почему явно заданы типы переменных, когда большинство из них можно определить неявно? 3) Почему вы сделали 'df_' необязательным? Для этого нет причин, и это приводит к тому, что ваш код загрязняется ненужным '!'. – rmaddy

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