আমি কীভাবে আইওএসে একটি আইএসও 8601 তারিখ পাব?


115

পিএসপিএফ-এর মাধ্যমে আইএসও 8601 তারিখের স্ট্রিং (উদাহরণস্বরূপ, 2004-02-12T15:19:21+00:00) পাওয়া যথেষ্ট সহজ date('c'), তবে কীভাবে এটি এটি উদ্দেশ্য-সি (আইফোন) এ পাবে? এটি করার জন্য কি একইভাবে সংক্ষিপ্ত পথ রয়েছে?

এখানে দীর্ঘআমি এটি করতে পথ পেয়েছি:

NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ssZ";

NSDate *now = [NSDate date];
NSString *formattedDateString = [dateFormatter stringFromDate:now];
NSLog(@"ISO-8601 date: %@", formattedDateString);

// Output: ISO-8601 date: 2013-04-27T13:27:50-0700

এটিকে কেন্দ্রিয় কোনও কিছুর জন্য মনে হচ্ছে প্রচুর কঠোরতা।


1
আমার অনুমান সংক্ষিপ্তটি দর্শকের চোখে পড়ে। তিন লাইনের কোড খুব সংক্ষিপ্ত, না? একটি সি এনএসডিট সাবক্লাস রয়েছে যা আপনি এটি যুক্ত করতে পারেন এটি একটি লাইন দিয়ে এটি করতে পারে, আমি কেবল এটির উপরে ছড়িয়ে পড়েছি : github.com/soffes/SAMCategories/tree/master/SAMCategories/… । এটি বলেছিল, সত্যিই, আপনি বেশ ভাল উত্তর পেয়েছেন (আইএমএইচও) এবং আপনার উত্তর এতিয়েনকে দেওয়া উচিত বা উত্তরটি দেওয়া উচিত। এটি কেবলমাত্র ভাল অনুশীলন এবং সত্যিকারের সহায়ক তথ্য সরবরাহকারী লোকদের পুরষ্কার দেয় (এটি আমাকে সাহায্য করেছিল, আমার আজ এই তথ্যের প্রয়োজন ছিল)। ইটিয়েন রাড্ডির চেয়ে পয়েন্টগুলি বেশি ব্যবহার করতে পারে। ভাল পরিমাপের লক্ষণ হিসাবে আমি আপনার প্রশ্নটি পর্যন্ত আপ করব!
ডেভিড এইচ

উত্তর:


212

ব্যবহার NSDateFormatter:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];   
NSLocale *enUSPOSIXLocale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
[dateFormatter setLocale:enUSPOSIXLocale];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"];
[dateFormatter setCalendar:[NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian]];

NSDate *now = [NSDate date];
NSString *iso8601String = [dateFormatter stringFromDate:now];

এবং সুইফটে:

let dateFormatter = DateFormatter()
let enUSPosixLocale = Locale(identifier: "en_US_POSIX")
dateFormatter.locale = enUSPosixLocale
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
dateFormatter.calendar = Calendar(identifier: .gregorian)

let iso8601String = dateFormatter.string(from: Date())

1
ধন্যবাদ, ম্যাডি। আমি আমার কোড পোস্ট করার পরে আমি এখনই আপনার উত্তরটি দেখেছি। setLocaleগুরুত্বপূর্ণ কি ?
JohnK

2
@ আরমড্ডি আপনি সম্ভবত জেডজেডজেডজেড ব্যবহার করার জন্য আপনার উদাহরণটি সম্পাদনা করতে পারেন যাতে লোকেরা অনুলিপি-পেষ্টিং পোড়াতে না পারে।
জেসি রুশাক

4
@ জ্লেমেডেজেবোনিনি ন। এটি খুব বিরল আপনি YYYY চান। আপনি সাধারণত yyyy চান।
rmaddy

7
কেন লোকেলটি en_US_POSIX এ সেট করা উচিত তার উত্স: বিকাশকারী.অ্যাপল.
_index.html

11
@ এমডি - গুগলের মাধ্যমে অন্যের এটির সন্ধান করা সহজ করে তুলতে চেয়েছিল এবং আপনাকে সঠিকভাবে সঠিক ফর্ম্যাট, লোকেল ইত্যাদি খননের জন্য ক্রেডিট দিতে চেয়েছিল তবে আপনি চাইলে আলাদা উত্তর হিসাবে পোস্ট করতে পেরে খুশি
রবিন

60

আইওএস 10 NSISO8601DateFormatterকেবল এটি পরিচালনা করতে একটি নতুন শ্রেণি প্রবর্তন করে । আপনি যদি সুইফট 3 ব্যবহার করেন তবে আপনার কোডটি এমন কিছু হবে:

let formatter = ISO8601DateFormatter()
let date = formatter.date(from: "2016-08-26T12:39:00Z")
let string = formatter.string(from: Date())

এবং এটি কোন ফর্ম্যাট দেয়? এছাড়াও এটি হ্যান্ডেল করতে পারে কিনা তা জানা ভাল হবে: 2016-08-26T12: 39: 00-0000 এবং 2016-08-26T12: 39: 00-00: 00 এবং 2016-08-26T12: 39: 00.374-0000
ম্যালহাল

1
আমার উত্তরের তিনটি লাইন চলার পরে string"2016-09-03T21: 47: 27Z" রয়েছে।
টুস্ট্রস

3
আপনি এই ফর্ম্যাটটি সহ মিলিসেকেন্ডগুলি পরিচালনা করতে পারবেন না
এনরিক

3
@ এনারিক: মিলিসেকেন্ডের সাথে কাজ করতে সক্ষম হওয়ার জন্য, আপনাকে ফর্ম্যাটর বিকল্পগুলিতে NSISO8601 তারিখ ফোর্ম্যাট উইথফ্রাকশনাল সেকেন্ড যুক্ত করা উচিত, ডকগুলি পরীক্ষা করে দেখুন।
পাকিতোভি

1
NSISO8601 তারিখের ফর্ম্যাট উইথফ্র্যাকশনাল সেকেন্ডগুলি কেবল 11.2+ এ কাজ করে। না হলে আপনি ক্রাশ পেয়েছেন!
hash3r

27

ম্যাডির উত্তরের পরিপূরক হিসাবে, টাইম জোনের ফর্ম্যাটটি একক "জেড" (যা আরএফসি 822 ফর্ম্যাটের জন্য) এর পরিবর্তে আইএসও 8601 এর জন্য "জেডজেডজেডজেডজেড" (5 গুণ জেড) হওয়া উচিত। কমপক্ষে আইওএস 6 এ।

( http://www.unicode.org/report/tr35/tr35-25.html# তারিখ_ফর্ম্যাট_প্যাটার্ন দেখুন )


দুর্দান্ত ধর! অন্য যে কেউ এতে আগ্রহী, লিঙ্কটিতে যান, 8601 এর জন্য অনুসন্ধান করুন আপনি এটি দেখতে পাবেন।
ডেভিড এইচ

তারিখের সময় অঞ্চলটি ইউটিসি হয়, আপনি কি জেড (যা সমতুল্য) এর পরিবর্তে 00:00 দেখানোর উপায় পাবেন?
শিম

অনেক অনেক ধন্যবাদ;) তারিখ ফর্মটারে শিরোনামের তারিখ দিয়ে দেয়ালে মাথা ফেরাচ্ছিল !!! :)
polo987

19

প্রায়শই অবহেলিত সমস্যাটি হ'ল আইএসও 8601 ফর্ম্যাটে স্ট্রিংগুলিতে মিলিসেকেন্ড থাকতে পারে এবং নাও থাকতে পারে।

অন্য কথায়, "2016-12-31T23: 59: 59.9999999" এবং "2016-12-01T00: 00: 00" উভয়ই বৈধ, তবে আপনি যদি স্ট্যাটিক-টাইপড তারিখ বিন্যাস ব্যবহার করেন তবে তার একটিও বিশ্লেষণ করা যাবে না ।

আইওএস 10 থেকে শুরু করে আপনার এমন ব্যবহার করা উচিত ISO8601DateFormatterযা আইএসও 8601 তারিখের স্ট্রিংয়ের সমস্ত প্রকারকে পরিচালনা করে। নীচে উদাহরণ দেখুন:

let date = Date()
var string: String

let formatter = ISO8601DateFormatter()
string = formatter.string(from: date)

let GMT = TimeZone(abbreviation: "GMT")
let options: ISO8601DateFormatOptions = [.withInternetDateTime, .withDashSeparatorInDate, .withColonSeparatorInTime, .withTimeZone]
string = ISO8601DateFormatter.string(from: date, timeZone: GMT, formatOptions: options)

জন্য iOS 9 এর এবং নীচের ব্যবহার একাধিক ডেটা formatters সাথে নিম্নলিখিত পদ্ধতির।

আমি এমন কোনও উত্তর খুঁজে পাইনি যা এই উভয় কেসকেই কভার করে এবং এই সূক্ষ্ম পার্থক্যটিকে দূরে সরিয়ে দেয়। সমাধান যে এখানে এটি সমাধান:

extension DateFormatter {

    static let iso8601DateFormatter: DateFormatter = {
        let enUSPOSIXLocale = Locale(identifier: "en_US_POSIX")
        let iso8601DateFormatter = DateFormatter()
        iso8601DateFormatter.locale = enUSPOSIXLocale
        iso8601DateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
        iso8601DateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
        return iso8601DateFormatter
    }()

    static let iso8601WithoutMillisecondsDateFormatter: DateFormatter = {
        let enUSPOSIXLocale = Locale(identifier: "en_US_POSIX")
        let iso8601DateFormatter = DateFormatter()
        iso8601DateFormatter.locale = enUSPOSIXLocale
        iso8601DateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
        iso8601DateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
        return iso8601DateFormatter
    }()

    static func date(fromISO8601String string: String) -> Date? {
        if let dateWithMilliseconds = iso8601DateFormatter.date(from: string) {
            return dateWithMilliseconds
        }

        if let dateWithoutMilliseconds = iso8601WithoutMillisecondsDateFormatter.date(from: string) {
            return dateWithoutMilliseconds
        }

        return nil
    }
}

ব্যবহার:

let dateToString = "2016-12-31T23:59:59.9999999"
let dateTo = DateFormatter.date(fromISO8601String: dateToString)
// dateTo: 2016-12-31 23:59:59 +0000

let dateFromString = "2016-12-01T00:00:00"
let dateFrom = DateFormatter.date(fromISO8601String: dateFromString)
// dateFrom: 2016-12-01 00:00:00 +0000

আমি তারিখের ফর্ম্যাটরগুলি সম্পর্কে অ্যাপল নিবন্ধটি চেক করার পরামর্শ দিই ।


আপনি কীভাবে ওবজে-সি-তে NSISO8601 তারিখফর্মটারকে ধরে রাখবেন তাও দয়া করে বলতে পারেন? (আইওএস 10 এবং উপরে অবশ্যই)
মোটি শ্নের

8

সুতরাং এখানে পাওয়া এনএসডেটে স্যাম সোফির বিভাগটি ব্যবহার করুন । আপনার প্রকল্পে কোডটি যুক্ত হওয়ার সাথে সাথে আপনি তখন থেকে এনএসডিটে একটি পদ্ধতি ব্যবহার করতে পারেন:

- (NSString *)sam_ISO8601String

খাঁটি সিতে রচিত হওয়ায় এটি কেবল একটি লাইনই নয়, এটি এনএসডিটফর্ম্যাটর পদ্ধতির চেয়ে অনেক দ্রুতগতিযুক্ত



1
আমি এর বিরুদ্ধে পরামর্শ দেব, এতে স্মৃতি ব্যতিক্রমী সমস্যা রয়েছে যা খুব এলোমেলোভাবে ঘটে
এম_ওয়ালি

1
@ এম_ওয়ালি আপনি কি তাকে এই প্রতিবেদন করেছেন? আমি তার কোডটি কোনও সতর্কবার্তা ছাড়াই তৈরি করেছি এবং এটি বিশ্লেষণের চেকটি ঠিক ঠিক পাস করেছে।
ডেভিড এইচ

6

আইএস 8601 থেকে , সমস্যাগুলি প্রতিনিধিত্ব এবং সময় অঞ্চল

  • আইএসও 8601 = year-month-day time timezone
  • তারিখ এবং সময়ের জন্য, এখানে বেসিক (ওয়াইওয়াইওয়াইএমএমডিডি, এইচএমএমএস, ...) এবং বর্ধিত বিন্যাস রয়েছে (ওয়াইওয়াইওয়াই-এমএম-ডিডি, এইচ: মিমি: এসএস, ...)
  • সময় অঞ্চলটি জুলু, অফসেট বা জিএমটি হতে পারে
  • তারিখ এবং সময়ের জন্য পৃথককারী স্থান হতে পারে, বা T
  • তারিখের জন্য সপ্তাহের ফর্ম্যাট রয়েছে তবে এটি খুব কমই ব্যবহৃত হয়
  • টাইমজোন পরে অনেকগুলি স্থান হতে পারে
  • দ্বিতীয়টি .চ্ছিক

এখানে কিছু বৈধ স্ট্রিং

2016-04-08T10:25:30Z
2016-04-08 11:25:30+0100
2016-04-08 202530GMT+1000
20160408 08:25:30-02:00
2016-04-08 11:25:30     +0100

সলিউশন

NSDateFormatter

সুতরাং এখানে যে ফর্ম্যাটটি আমি onmyway133 ISO8601 এ ব্যবহার করছি তা এখানে

let formatter = NSDateFormatter()
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
formatter.dateFormat = "yyyyMMdd HHmmssZ"

আমাদের সম্পর্কে Zআইডেন্টিফায়ার তারিখ ফিল্ড সাংকেতিক ছক

Z: The ISO8601 basic format with hours, minutes and optional seconds fields. The format is equivalent to RFC 822 zone format (when optional seconds field is absent)

লোকেল সেটিংস ব্যবহার করে ডেটা ফর্ম্যাট করা সম্পর্কেlocale

লোকালগুলি নির্দিষ্ট ব্যবহারকারীর পছন্দসই ভাষা নয়, নির্দিষ্ট ব্যবহারকারীর জন্য বিন্যাস পছন্দগুলি উপস্থাপন করে। এগুলি প্রায়শই একই তবে ভিন্ন হতে পারে। উদাহরণস্বরূপ, স্থানীয় নেটিভ স্পিকার যিনি জার্মানে থাকেন তিনি ভাষা হিসাবে ইংরাজী এবং অঞ্চলটিকে জার্মানি হিসাবে বেছে নিতে পারেন

প্রযুক্তিগত প্রশ্নোত্তর প্রশ্নোত্তর সম্পর্কে en_US_POSIX QA1480 এনএসডিট ফরমেটার এবং ইন্টারনেটের তারিখ

অন্যদিকে, আপনি যদি স্থির-ফর্ম্যাটের তারিখগুলি নিয়ে কাজ করছেন, আপনার প্রথমে তারিখের ফর্ম্যাটরের লোকেলটি আপনার নির্দিষ্ট বিন্যাসের জন্য উপযুক্ত কিছুতে সেট করা উচিত। বেশিরভাগ ক্ষেত্রে বেছে নেওয়া সেরা লোকেল হ'ল "en_US_POSIX", স্থানীয় এবং ব্যবহারকারী এবং সিস্টেম উভয় পছন্দ নির্বিশেষে ইউএস ইংলিশ ফলাফল আনার জন্য বিশেষভাবে তৈরি করা একটি লোকেল। "en_US_POSIX" সময়ের সাথেও অবিচ্ছিন্ন (যদি ভবিষ্যতে মার্কিন যুক্তরাষ্ট্রে, তারিখের বিন্যাসের পদ্ধতি পরিবর্তন করে তবে "en_US" নতুন আচরণ প্রতিফলিত করতে পরিবর্তিত হবে, তবে "en_US_POSIX" হবে না), এবং মেশিনগুলির মধ্যে ( "en_US_POSIX" iOS এ একই কাজ করে যেমন এটি ওএস এক্সে করে, এবং এটি অন্যান্য প্ল্যাটফর্মে যেমন করে)।

আকর্ষণীয় সম্পর্কিত কাতার


আমি কেবল 2016-07-23T07: 24: 23Z দিয়ে চেষ্টা করেছি, এটি কাজ করে না
কামেন ডবরেভ

@ কামেনডোব্রেভ "কাজ না করা" বলতে আপনার অর্থ কী? আমি কেবল পরীক্ষাগুলিতে আপনার উদাহরণটি জুড়েছি github.com/onmyway133/ISO8601/blob/master/ISO8601 পরীক্ষা /… এবং এটি কাজ করে
onwayway133


3

এই সূচনার ভিত্তিতে: https://github.com/justinmakaila/NSDate-ISO-8601/blob/master/NSDateISO8601.swift , নিম্নলিখিত পদ্ধতিটি ইয়াসি-এমএম আকারে এনএসডিটকে আইএসও 8601 তারিখের স্ট্রিংয়ে রূপান্তর করতে ব্যবহার করা যেতে পারে -dd'T'HH: mM: ss.SSSZ

-(NSString *)getISO8601String
    {
        static NSDateFormatter *formatter = nil;
        if (!formatter)
        {
            formatter = [[NSDateFormatter alloc] init];
            [formatter setLocale: [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];
            formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"UTC"];
            [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS"];

        }
        NSString *iso8601String = [formatter stringFromDate: self];
        return [iso8601String stringByAppendingString: @"Z"];
    }

Sসাব-সেকেন্ডের ক্যাপটি এখানে মূল কী ছিল
মার্ক মেয়ার

নোট করুন আপনার যদি 3 এস এর বেশি প্রয়োজন হয় তবে আপনি তারিখ বিন্যাসটি ম্যানুয়ালি পার্স করতে পারবেন না।
ম্যালহাল

-1

এটি কিছুটা সহজ এবং তারিখটিকে ইউটিসিতে রাখে।

extension NSDate
{
    func iso8601() -> String
    {
        let dateFormatter = NSDateFormatter()
        dateFormatter.timeZone = NSTimeZone(name: "UTC")
        let iso8601String = dateFormatter.stringFromDate(NSDate())
        return iso8601String
    }
}

let date = NSDate().iso8601()

-1

সুইফট 3.0 এবং আইওএস 9.0 ব্যবহার করে

extension Date {
    private static let jsonDateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.timeZone = TimeZone(identifier: "UTC")!
        return formatter
    }()

    var IOS8601String: String {
        get {
            return Date.jsonDateFormatter.string(from: self)
        }
    }

    init?(fromIOS8601 dateString: String) {
        if let d = Date.jsonDateFormatter.date(from: dateString) {
            self.init(timeInterval: 0, since:d)
        } else {
            return nil
        }
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.