iOS: UTC NSDate को स्थानीय समयक्षेत्र में परिवर्तित करें


139

मैं NSDateउद्देश्य C या / और स्विफ्ट में UTC को स्थानीय समयक्षेत्र NSDate में कैसे परिवर्तित करूं ?


14
तिथियां निश्चित रूप से समय क्षेत्र हैं।
ग्लेन मेनार्ड

1
यदि यह मदद करता है, तो तापमान के बारे में सोचें। उन्हें फारेनहाइट, सेल्सियस या केल्विन में व्यक्त किया जा सकता है। लेकिन व्यक्त की जा रही जानकारी (अणुओं की औसत गति) की कोई आंतरिक इकाई नहीं है, हालांकि यह केवल हमारे लिए सार्थक है जब किसी इकाई में व्यक्त किया गया हो।
सॉफ्टवेयर का विकास

7
@DaveDeLong NSDate में टाइमजोन होता है। NSDate वर्ग के संदर्भ से: "यह विधि एक पूर्ण संदर्भ तिथि के सापेक्ष समय मान लौटाती है - 1 जनवरी, GMTT का पहला इंस्टेंट।" GMT के स्पष्ट और विशिष्ट संदर्भ पर ध्यान दें।
मुरैना सागर

3
मैं असहमत हूं। NSDate में टाइमज़ोन नहीं है। NSDate के लिए टाइमज़ोन निर्दिष्ट करने के लिए, आप NSCalendar ऑब्जेक्ट या NSDateFormatter ऑब्जेक्ट का उपयोग करते हैं। यदि आप एक स्ट्रिंग से एक NSDate बनाते हैं जिसमें कोई टाइमज़ोन निर्दिष्ट नहीं है, तो NSDate यह मान लेगा कि स्ट्रिंग GMT समय में है।
रिकस्टर

1
@MurraySagal सिर्फ इसलिए कि एक विशेष विधि एक विशिष्ट समयक्षेत्र में किसी दिनांक के सापेक्ष समय मान लौटाती है, इसका मतलब यह नहीं है कि NSDate किसी समयक्षेत्र के सापेक्ष होने की तिथि को मॉडल करता है।
er

जवाबों:


139
NSTimeInterval seconds; // assume this exists
NSDate* ts_utc = [NSDate dateWithTimeIntervalSince1970:seconds];

NSDateFormatter* df_utc = [[[NSDateFormatter alloc] init] autorelease];
[df_utc setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
[df_utc setDateFormat:@"yyyy.MM.dd G 'at' HH:mm:ss zzz"];

NSDateFormatter* df_local = [[[NSDateFormatter alloc] init] autorelease];
[df_local setTimeZone:[NSTimeZone timeZoneWithName:@"EST"]];
[df_local setDateFormat:@"yyyy.MM.dd G 'at' HH:mm:ss zzz"];

NSString* ts_utc_string = [df_utc stringFromDate:ts_utc];
NSString* ts_local_string = [df_local stringFromDate:ts_utc];

// you can also use NSDateFormatter dateFromString to go the opposite way

स्वरूपण स्ट्रिंग मापदंडों की तालिका:

https://waracle.com/iphone-nsdateformatter-date-formatting-table/

यदि प्रदर्शन एक प्राथमिकता है, तो आप उपयोग करने पर विचार कर सकते हैं strftime

https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/strftime.3.html


शायद ध्यान देने योग्य बात यह है कि आप फॉर्मेट का उपयोग स्ट्रिंग्स से वापस तिथियाँ पढ़ने के लिए कर सकते हैं
slf

34
@DaveDeLong यह सब ठीक है और अच्छा है यदि आप तारीख को एक स्ट्रिंग के रूप में प्रदर्शित कर रहे हैं। लेकिन किसी तिथि पर समय क्षेत्र रूपांतरण करने के लिए पूरी तरह से मान्य कारण हैं। उदाहरण के लिए, यदि आप सेटडेट का उपयोग करके UIDatePicker पर दिनांक को डिफ़ॉल्ट करना चाहते हैं: वेब सेवाओं द्वारा लौटाए गए डेट्स अक्सर यूटीसी होते हैं, लेकिन टीवी लिस्टिंग की तरह, उपयोगकर्ता के स्थानीय समय क्षेत्र में एक घटना का प्रतिनिधित्व करते हैं। अनकवर्ड डेट में पास होने से पिकर में गलत समय प्रदर्शित होगा।
क्रिस्टोफर पिक्सले

5
@GlennMaynard मैं असहमत हूं। इस उत्तर का सार यह है कि NSDateवस्तु में कोई रूपांतरण आवश्यक नहीं है, जो सही है। एक समयक्षेत्र में रूपांतरण तब होता है जब दिनांक स्वरूपित होती है, न कि जब इसे बनाया जाता है, क्योंकि तिथियों में समय-क्षेत्र नहीं होता है।
डेव डोंगलांग

1
@GlennMaynard ... सिवाय इसके कि NSCalendarDateपदावनत किया जाता है।
डेव डोंगलॉन्ग

1
इस पर भी ध्यान दें: oleb.net/blog/2011/11/… जहां यह कहता है "GMT! = UTC"
huggie

106

संपादित करें जब मैंने यह लिखा था तो मुझे नहीं पता था कि मुझे एक डेटफॉर्मेटर का उपयोग करना चाहिए जो शायद एक बेहतर दृष्टिकोण है, इसलिए slfइसका उत्तर भी देखें।

मेरे पास एक webservice है जो UTC में दिनांक लौटाता है। मैं toLocalTimeइसे स्थानीय समय toGlobalTimeमें परिवर्तित करने और यदि आवश्यक हो तो वापस परिवर्तित करने के लिए उपयोग करता हूं ।

यहीं से मुझे अपना उत्तर मिला:

https://agilewarrior.wordpress.com/2012/06/27/how-to-convert-nsdate-to-different-time-zones/

@implementation NSDate(Utils)

-(NSDate *) toLocalTime
{
  NSTimeZone *tz = [NSTimeZone defaultTimeZone];
  NSInteger seconds = [tz secondsFromGMTForDate: self];
  return [NSDate dateWithTimeInterval: seconds sinceDate: self];
}

-(NSDate *) toGlobalTime
{
  NSTimeZone *tz = [NSTimeZone defaultTimeZone];
  NSInteger seconds = -[tz secondsFromGMTForDate: self];
  return [NSDate dateWithTimeInterval: seconds sinceDate: self];
}

@end

25
यह मत करो। NSDates हमेशा UTC में होते हैं। यह सिर्फ मुद्दे को भ्रमित करता है।
जेरेमीप

13
यह ऊपर उल्लेखित "webservice" मामले के लिए बहुत उपयोगी हो सकता है। मान लीजिए कि आपके पास एक सर्वर है जो UTC में घटनाओं को संग्रहीत करता है और ग्राहक आज होने वाली सभी घटनाओं के लिए पूछना चाहता है। ऐसा करने के लिए, क्लाइंट को वर्तमान दिनांक (UTC / GMT) प्राप्त करने की आवश्यकता होती है और फिर इसे सर्वर पर भेजने से पहले इसे अपने टाइमज़ोन ऑफ़सेट द्वारा स्थानांतरित कर दिया जाता है।
टेलर लफ्रीनरे 10

@JeremyP यह कहना अधिक सटीक होगा कि NSDates हमेशा GMT में हैं। NSDate वर्ग के संदर्भ से: "यह विधि एक पूर्ण संदर्भ तिथि के सापेक्ष समय मान लौटाती है - 1 जनवरी, GMTT का पहला इंस्टेंट।" GMT के स्पष्ट और विशिष्ट संदर्भ पर ध्यान दें। जीएमटी और यूटीसी के बीच एक तकनीकी अंतर है, लेकिन ज्यादातर लोगों को जिन समाधानों की तलाश है, उनके लिए यह अप्रासंगिक है।
मरे सगल

3
यह नोट करना अच्छा होगा कि आपने कोड कहाँ से कॉपी किया है: agilewarrior.wordpress.com/2012/06/27/…
aryaxt

2
@aryaxt आप सही हैं, मुझे खेद है। मुझे ईमानदारी से याद नहीं था कि जब मैंने जवाब पोस्ट किया था, तो मैं कहाँ से कॉपी किया था।
गोजो कुदोर

49

सबसे आसान तरीका जो मैंने पाया है वह यह है:

NSDate *someDateInUTC = …;
NSTimeInterval timeZoneSeconds = [[NSTimeZone localTimeZone] secondsFromGMT];
NSDate *dateInLocalTimezone = [someDateInUTC dateByAddingTimeInterval:timeZoneSeconds];

3
यह उत्तर अधिक पोर्टेबल लगता है। नीचे दिए गए उत्तर को समयक्षेत्र मानते हुए रनटाइम पर तय किया गया है जबकि ऊपर दिया गया उत्तर प्लेटफॉर्म से समयक्षेत्र को प्राप्त करता है।
ब्लेकज

9
बहुत मददगार। secondsFromGMTForDateयदि आप दिन के उजाले की बचत के लिए खाते का उपयोग करना चाहते हैं, तो इसके अलावा, का उपयोग किया जाना चाहिए। देखें एप्पल डॉक्स
सेर्गेई Markelov

1
यह डीएसटी परिवर्तनों को ध्यान में रखने में विफल रहता है।
lkraider

36

स्विफ्ट 3+ : यूटीसी लोकल और लोकल से यूटीसी

extension Date {

    // Convert UTC (or GMT) to local time
    func toLocalTime() -> Date {
        let timezone = TimeZone.current
        let seconds = TimeInterval(timezone.secondsFromGMT(for: self))
        return Date(timeInterval: seconds, since: self)
    }

    // Convert local time to UTC (or GMT)
    func toGlobalTime() -> Date {
        let timezone = TimeZone.current
        let seconds = -TimeInterval(timezone.secondsFromGMT(for: self))
        return Date(timeInterval: seconds, since: self)
    }
}

यह किसी भी समय क्षेत्र को यूटीसी या इसके विपरीत में बदल देगा?
मितेश

26

यदि आप स्थानीय दिनांक और समय चाहते हैं। इस कोड को आज़माएं: -

NSString *localDate = [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle];

बहुत बढ़िया जवाब! यह वर्तमान दिनांक को हड़प लेगा। इस का एक अनुकूलन जो एक तारीख स्ट्रिंग का उपयोग करता है के [NSDate date]साथ प्रतिस्थापित करना होगा [NSDate dateWithNaturalLanguageString:sMyDateString]
ज्वालामुखी

7

अपनी UTC तिथि को स्थानीय दिनांक में बदलें

-(NSString *)getLocalDateTimeFromUTC:(NSString *)strDate
{
    NSDateFormatter *dtFormat = [[NSDateFormatter alloc] init];
    [dtFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    [dtFormat setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
    NSDate *aDate = [dtFormat dateFromString:strDate];

    [dtFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    [dtFormat setTimeZone:[NSTimeZone systemTimeZone]];

    return [dtFormat stringFromDate:aDate];
}

इस तरह का उपयोग करें

NSString *localDate = [self getLocalDateTimeFromUTC:@"yourUTCDate"];

1
मेरे लिए काम नहीं, मेरा स्थानीय समय +3 है और यह कोड वापसी +2
फडी अबुझंत

6

यहाँ इनपुट स्ट्रिंग स्ट्रिंग है (प्रारूप 08/30/2012 11:11 में) GMT में इनपुट समय को सिस्टम सेट ज़ोन समय में परिवर्तित करता है

//UTC time
NSDateFormatter *utcDateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[utcDateFormatter setDateFormat:@"MM/dd/yyyy HH:mm"];
[utcDateFormatter setTimeZone :[NSTimeZone timeZoneForSecondsFromGMT: 0]];

// utc format
NSDate *dateInUTC = [utcDateFormatter dateFromString: currentUTCTime];

// offset second
NSInteger seconds = [[NSTimeZone systemTimeZone] secondsFromGMT];

// format it and send
NSDateFormatter *localDateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[localDateFormatter setDateFormat:@"MM/dd/yyyy HH:mm"];
[localDateFormatter setTimeZone :[NSTimeZone timeZoneForSecondsFromGMT: seconds]];

// formatted string
NSString *localDate = [localDateFormatter stringFromDate: dateInUTC];
return localDate;

4
//This is basic way to get time of any GMT time.

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"hh:mm a"];  // 09:30 AM
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:1]]; // For GMT+1
NSString *time = [formatter stringFromDate:[NSDate date]];  // Current time


2

मैं इस विधि को हमारे LocalTimeZone में दिनांक समय बदलने के लिए लिखता हूं

-हेरे (NSString *) टाइमजोन पैरामीटर एक सर्वर टाइमज़ोन है

-(NSString *)convertTimeIntoLocal:(NSString *)defaultTime :(NSString *)TimeZone
{
    NSDateFormatter *serverFormatter = [[NSDateFormatter alloc] init];
    [serverFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:TimeZone]];
    [serverFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *theDate = [serverFormatter dateFromString:defaultTime];
    NSDateFormatter *userFormatter = [[NSDateFormatter alloc] init];
    [userFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    [userFormatter setTimeZone:[NSTimeZone localTimeZone]];
    NSString *dateConverted = [userFormatter stringFromDate:theDate];
    return dateConverted;
}

1

चूंकि कोई भी उपयोग नहीं कर NSDateComponentsरहा था, मुझे लगा कि मैं इसमें एक पिच करूंगा ... इस संस्करण में, कोई NSDateFormatterउपयोग नहीं किया जाता है, इसलिए कोई स्ट्रिंग पार्सिंग NSDateनहीं है , और जीएमटी (यूटीसी) के बाहर समय का प्रतिनिधित्व करने के लिए उपयोग नहीं किया जाता है। मूल NSDateचर में है i_date

NSCalendar *anotherCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:i_anotherCalendar];
anotherCalendar.timeZone = [NSTimeZone timeZoneWithName:i_anotherTimeZone];

NSDateComponents *anotherComponents = [anotherCalendar components:(NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitNanosecond) fromDate:i_date];

// The following is just for checking   
anotherComponents.calendar = anotherCalendar; // anotherComponents.date is nil without this
NSDate *anotherDate = anotherComponents.date;

i_anotherCalendarNSCalendarIdentifierGregorianया कोई अन्य कैलेंडर हो सकता है । के लिए NSStringअनुमति के i_anotherTimeZoneसाथ हासिल किया जा सकता है [NSTimeZone knownTimeZoneNames], लेकिन या या anotherCalendar.timeZoneहो सकता है[NSTimeZone defaultTimeZone][NSTimeZone localTimeZone][NSTimeZone systemTimeZone] पूरी तरह।

यह वास्तव anotherComponentsमें नए समय क्षेत्र में समय धारण कर रहा है। आप देखेंगे कि यह जीएमटी (यूटीसी) में समय के anotherDateबराबर है i_date


0

आप इसे आज़मा सकते हैं:

NSDate *currentDate = [[NSDate alloc] init];
NSTimeZone *timeZone = [NSTimeZone defaultTimeZone];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterLongStyle];
[dateFormatter setTimeStyle:NSDateFormatterLongStyle];
[dateFormatter setTimeZone:timeZone];
[dateFormatter setDateFormat:@"ZZZ"];
NSString *localDateString = [dateFormatter stringFromDate:currentDate];
NSMutableString *mu = [NSMutableString stringWithString:localDateString];
[mu insertString:@":" atIndex:3];
 NSString *strTimeZone = [NSString stringWithFormat:@"(GMT%@)%@",mu,timeZone.name];
 NSLog(@"%@",strTimeZone);

-1

यूटीसी समय को वर्तमान समय क्षेत्र में परिवर्तित करें।

कॉल फ़ंक्शन

NSLocale *locale = [NSLocale autoupdatingCurrentLocale];

NSString *myLanguageCode = [locale objectForKey: NSLocaleLanguageCode];
NSString *myCountryCode = [locale objectForKey: NSLocaleCountryCode];

NSString *rfc3339DateTimeString = @"2015-02-15 00:00:00"];
NSDate *myDateTime = (NSDate*)[_myCommonFunctions _ConvertUTCTimeToLocalTimeWithFormat:rfc3339DateTimeString LanguageCode:myLanguageCode CountryCode:myCountryCode Formated:NO];

समारोह

-NSObject*)_ConvertUTCTimeToLocalTimeWithFormat:rfc3339DateTimeString     LanguageCode:(NSString *)lgc CountryCode:(NSString *)ctc Formated:(BOOL) formated
{
    NSDateFormatter *sUserVisibleDateFormatter = nil;
    NSDateFormatter *sRFC3339DateFormatter = nil;

    NSTimeZone *timeZone = [NSTimeZone defaultTimeZone];

    if (sRFC3339DateFormatter == nil)
    {
        sRFC3339DateFormatter = [[NSDateFormatter alloc] init];

        NSLocale *myPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:[NSString stringWithFormat:@"%@", timeZone]];

        [sRFC3339DateFormatter setLocale:myPOSIXLocale];
        [sRFC3339DateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
        [sRFC3339DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
    }

    // Convert the RFC 3339 date time string to an NSDate.
    NSDate *date = [sRFC3339DateFormatter dateFromString:rfc3339DateTimeString];

    if (formated == YES)
    {
        NSString *userVisibleDateTimeString;

        if (date != nil)
        {
            if (sUserVisibleDateFormatter == nil)
            {
                sUserVisibleDateFormatter = [[NSDateFormatter alloc] init];
                [sUserVisibleDateFormatter setDateStyle:NSDateFormatterMediumStyle];
                [sUserVisibleDateFormatter setTimeStyle:NSDateFormatterShortStyle];
            }

            // Convert the date object to a user-visible date string.
            userVisibleDateTimeString = [sUserVisibleDateFormatter stringFromDate:date];

            return (NSObject*)userVisibleDateTimeString;
        }
    }

    return (NSObject*)date;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.