【问题标题】:Converting NSString to NSDate (and back again)将 NSString 转换为 NSDate(然后再返回)
【发布时间】:2011-04-24 10:53:03
【问题描述】:

我如何将像“01/02/10”(表示 2010 年 2 月 1 日)之类的 NSString 转换为 NSDate?我怎样才能将NSDate 转回字符串?

【问题讨论】:

  • 使用2010。然后看看我的帖子。我已经为这两个过程提供了转换。

标签: ios objective-c nsstring nsdate


【解决方案1】:

2019 年更新(斯威夫特 4):

为此做了一个 Date 扩展。它使用NSDataDetector 而不是NSDateFormatter

// Just throw at it without any format.
var date: Date? = Date.FromString("02-14-2019 17:05:05")

非常有趣,它甚至可以识别“明天 5 点”

XCTAssertEqual(Date.FromString("2019-02-14"),                    Date.FromCalendar(2019, 2, 14))
XCTAssertEqual(Date.FromString("2019.02.14"),                    Date.FromCalendar(2019, 2, 14))
XCTAssertEqual(Date.FromString("2019/02/14"),                    Date.FromCalendar(2019, 2, 14))
XCTAssertEqual(Date.FromString("2019 Feb 14"),                   Date.FromCalendar(2019, 2, 14))
XCTAssertEqual(Date.FromString("2019 Feb 14th"),                 Date.FromCalendar(2019, 2, 14))
XCTAssertEqual(Date.FromString("20190214"),                      Date.FromCalendar(2019, 2, 14))
XCTAssertEqual(Date.FromString("02-14-2019"),                    Date.FromCalendar(2019, 2, 14))
XCTAssertEqual(Date.FromString("02.14.2019 5:00 PM"),            Date.FromCalendar(2019, 2, 14, 17))
XCTAssertEqual(Date.FromString("02/14/2019 17:00"),              Date.FromCalendar(2019, 2, 14, 17))
XCTAssertEqual(Date.FromString("14 February 2019 at 5 hour"),    Date.FromCalendar(2019, 2, 14, 17))
XCTAssertEqual(Date.FromString("02-14-2019 17:05:05"),           Date.FromCalendar(2019, 2, 14, 17, 05, 05))
XCTAssertEqual(Date.FromString("17:05, 14 February 2019 (UTC)"), Date.FromCalendar(2019, 2, 14, 17, 05))
XCTAssertEqual(Date.FromString("02-14-2019 17:05:05 GMT"),       Date.FromCalendar(2019, 2, 14, 17, 05, 05))
XCTAssertEqual(Date.FromString("02-13-2019 Tomorrow"),           Date.FromCalendar(2019, 2, 14))
XCTAssertEqual(Date.FromString("2019 Feb 14th Tomorrow at 5"),   Date.FromCalendar(2019, 2, 14, 17))

类似:

extension Date
{


    public static func FromString(_ dateString: String) -> Date?
    {
        // Date detector.
        let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.date.rawValue)

        // Enumerate matches.
        var matchedDate: Date?
        var matchedTimeZone: TimeZone?
        detector.enumerateMatches(
            in: dateString,
            options: [],
            range: NSRange(location: 0, length: dateString.utf16.count),
            using:
            {
                (eachResult, _, _) in

                // Lookup matches.
                matchedDate = eachResult?.date
                matchedTimeZone = eachResult?.timeZone

                // Convert to GMT (!) if no timezone detected.
                if matchedTimeZone == nil, let detectedDate = matchedDate
                { matchedDate = Calendar.current.date(byAdding: .second, value: TimeZone.current.secondsFromGMT(), to: detectedDate)! }
        })

        // Result.
        return matchedDate
    }
}

2014 年更新:

为此做了一个 NSString 扩展

// Simple as this.   
date = dateString.dateValue;

感谢NSDataDetector,它可以识别很多格式。

'2014-01-16' dateValue is <2014-01-16 11:00:00 +0000>
'2014.01.16' dateValue is <2014-01-16 11:00:00 +0000>
'2014/01/16' dateValue is <2014-01-16 11:00:00 +0000>
'2014 Jan 16' dateValue is <2014-01-16 11:00:00 +0000>
'2014 Jan 16th' dateValue is <2014-01-16 11:00:00 +0000>
'20140116' dateValue is <2014-01-16 11:00:00 +0000>
'01-16-2014' dateValue is <2014-01-16 11:00:00 +0000>
'01.16.2014' dateValue is <2014-01-16 11:00:00 +0000>
'01/16/2014' dateValue is <2014-01-16 11:00:00 +0000>
'16 January 2014' dateValue is <2014-01-16 11:00:00 +0000>
'01-16-2014 17:05:05' dateValue is <2014-01-16 16:05:05 +0000>
'01-16-2014 T 17:05:05 UTC' dateValue is <2014-01-16 17:05:05 +0000>
'17:05, 1 January 2014 (UTC)' dateValue is <2014-01-01 16:05:00 +0000>

eppz!kit 的一部分,从 GitHub 获取类别 NSString+EPPZKit.h


2013 年原始答案:

无论您不确定(或不关心)字符串中包含的日期格式,使用 NSDataDetector 解析日期

//Role players.
NSString *dateString = @"Wed, 03 Jul 2013 02:16:02 -0700";
__block NSDate *detectedDate;

//Detect.
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingAllTypes error:nil];
[detector enumerateMatchesInString:dateString
                           options:kNilOptions
                             range:NSMakeRange(0, [dateString length])
                        usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
{ detectedDate = result.date; }];

【讨论】:

  • 好像不支持24小时制。例如。 NSString -> 2013-09-11 01:31:22 +0000 转换为 NSDate -> 2013-09-11 13:31:22 +0000
  • 我最喜欢这个答案,因为原始日期字符串可能非常随意。这在用户在文本字段中而不是通过选择器输入日期的情况下非常有用。
  • 此方法如何确定日期是 DD/MM/yyyy 还是 MM/DD/yyyy ?例如,如果输入是 01/03/2014,结果会是什么?
  • @ahmad 我完全同意 - 如果您必须支持不同的语言设置,这种方法可能行不通。
  • @sooper XCTAssertEqual(Date.FromString("2013-09-11 01:31:22 +0000"), Date.FromCalendar(2013, 9, 11, 1, 31, 22)) 看起来不错。
【解决方案2】:

Swift 4 及更高版本

更新:2018 年

字符串到日期

var dateString = "02-03-2017"
var dateFormatter = DateFormatter()

// This is important - we set our input date format to match our input string
// if the format doesn't match you'll get nil from your string, so be careful
dateFormatter.dateFormat = "dd-MM-yyyy"

//`date(from:)` returns an optional so make sure you unwrap when using. 
var dateFromString: Date? = dateFormatter.date(from: dateString)

日期转字符串

var formatter = DateFormatter()
formatter.dateFormat = "dd-MM-yyyy"
guard let unwrappedDate = dateFromString else { return }

//Using the dateFromString variable from before. 
let stringDate: String = formatter.string(from: dateFromString)

斯威夫特 3

更新日期:2017 年 7 月 20 日

字符串到 NSDate

var dateString = "02-03-2017"
var dateFormatter = DateFormatter()
// This is important - we set our input date format to match our input string
// if the format doesn't match you'll get nil from your string, so be careful
dateFormatter.dateFormat = "dd-MM-yyyy"
var dateFromString = dateFormatter.date(from: dateString)

NSDate 转字符串

var formatter = DateFormatter()
formatter.dateFormat = "dd-MM-yyyy"
let stringDate: String = formatter.string(from: dateFromString)

斯威夫特

更新日期:2015 年 10 月 22 日

字符串到 NSDate

var dateString = "01-02-2010"
var dateFormatter = NSDateFormatter()
// this is imporant - we set our input date format to match our input string
dateFormatter.dateFormat = "dd-MM-yyyy"
// voila!
var dateFromString = dateFormatter.dateFromString(dateString)

NSDate 转字符串

var formatter = NSDateFormatter()
formatter.dateFormat = "dd-MM-yyyy"
let stringDate: String = formatter.stringFromDate(NSDate())
println(stringDate)

目标-C

NSString 到 NSDate

NSString *dateString = @"01-02-2010";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"dd-MM-yyyy"];
NSDate *dateFromString = [dateFormatter dateFromString:dateString];

NSDate 转换为 NSString:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"dd-MM-yyyy"];
NSString *stringDate = [dateFormatter stringFromDate:[NSDate date]];
NSLog(@"%@", stringDate);

【讨论】:

  • setDateFormat中应该是两个y吗?
  • 我不确定 2 y 的工作是否有效。但经验法则是你要给keeo的setDateFormat格式相同的格式。所以首先 trty 2010 并写 4 y's like so 'yyyy'。我确信这肯定会起作用
  • 这篇文章值得一看。
  • 如果给下一行的指针赋新值,NSDate *dateFromString = [[NSDate alloc] init];是什么原因???
  • 另一个需要注意的项目 - 如果您的字符串(日期)值列为 05/29/2013,您对 setDateFormat 的调用将需要匹配相同 - 即 [dateFormatter setDateFormat:@"MM /dd/yyyy"] - 我帮助的人在他们的字符串数据有斜杠时一直尝试使用连字符。 - 很好的答案帕万。
【解决方案3】:

字符串到日期

var dateFormatter = DateFormatter()
dateFormatter.format = "dd/MM/yyyy"

var dateFromString: Date? = dateFormatter.date(from: dateString) //pass string here

日期转字符串

 var dateFormatter = DateFormatter()
 dateFormatter.dateFormat = "dd-MM-yyyy"
 let newDate = dateFormatter.string(from: date) //pass Date here

【讨论】:

    【解决方案4】:

    使用固定格式日期时,您需要将日期格式化程序区域设置为"en_US_POSIX"

    取自Data Formatting Guide

    如果您使用的是固定格式的日期,则应首先设置 日期格式化程序的区域设置为适合您的固定 格式。在大多数情况下,选择的最佳语言环境是 en_US_POSIX,一个 专门为产生美国英语结果而设计的语言环境 无论用户和系统偏好如何。 en_US_POSIX 也是 时间不变(如果美国在未来的某个时间点改变 它格式化日期的方式,en_US 将改变以反映新的行为, 但 en_US_POSIX 不会)和平台之间(en_US_POSIX 有效) 在 iPhone OS 上和在 OS X 上一样,和在其他操作系统上一样 平台)。

    Swift 3 或更高版本

    extension Formatter {
        static let customDate: DateFormatter = {
            let formatter = DateFormatter()
            formatter.locale = Locale(identifier: "en_US_POSIX")
            formatter.dateFormat = "dd/MM/yy"
            return formatter
        }()
        static let time: DateFormatter = {
            let formatter = DateFormatter()
            formatter.locale = Locale(identifier: "en_US_POSIX")
            formatter.dateFormat = "HH:mm"
            return formatter
        }()
        static let weekdayName: DateFormatter = {
            let formatter = DateFormatter()
            formatter.dateFormat = "cccc"
            return formatter
        }()
        static let month: DateFormatter = {
            let formatter = DateFormatter()
            formatter.dateFormat = "LLLL"
            return formatter
        }()
    }
    

    extension Date {
        var customDate: String {
            return Formatter.customDate.string(from: self)
        }
        var customTime: String {
            return Formatter.time.string(from: self)
        }
        var weekdayName: String {
            return Formatter.weekdayName.string(from: self)
        }
        var monthName: String {
            return Formatter.month.string(from: self)
        }
    }
    
    extension String {
        var customDate: Date? {
            return Formatter.customDate.date(from: self)
        }
    }
    

    用法:

    // this will be displayed like this regardless of the user and system preferences
    Date().customTime          //  "16:50"
    Date().customDate          //  "06/05/17"
    // this will be displayed according to user and system preferences
    Date().weekdayName         //  "Saturday"
    Date().monthName           //  "May"
    

    解析自定义日期并将日期转换回相同的字符串格式:

    let dateString = "01/02/10"
    
    if let date = dateString.customDate {
        print(date.customDate)   // "01/02/10\n"
        print(date.monthName)    // customDate
    }
    

    这里是您可以根据需要自定义它的所有元素:

    【讨论】:

    • 如果多个线程访问这些方法怎么办?由于重新分配格式化程序的 dateFormat 会不会导致错误?变量(日期/时间/工作日)的使用只是您的偏好,或者它们可能是这样做的优势,还是最佳实践?
    【解决方案5】:

    为什么不给 NSString 添加一个类别呢?

    // NSString+Date.h
    @interface NSString (Date)
    + (NSDate*)stringDateFromString:(NSString*)string;
    + (NSString*)stringDateFromDate:(NSDate*)date;
    @end
    
    
    // NSString+Date.m
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
    [dateFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss ZZZ"];
    
    NSDate *date = [dateFormatter dateFromString:stringDate ];
    [dateFormatter release];
    + (NSDateFormatter*)stringDateFormatter
    {
        static NSDateFormatter* formatter = nil;
        if (formatter == nil)
        {
            formatter = [[NSDateFormatter alloc] init];
            [formatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss ZZZ"];
        }   
        return formatter;
    }
    
    + (NSDate*)stringDateFromString:(NSString*)string
    {
        return [[NSString stringDateFormatter] dateFromString:string];
    }
    
    + (NSString*)stringDateFromDate:(NSDate*)date
    {
        return [[NSString stringDateFormatter] stringFromDate:date];
    }
    
    
    // Usage (#import "NSString+Date.h") or add in "YOUR PROJECT".pch file
    NSString* string = [NSString stringDateFromDate:[NSDate date]];
    NSDate* date = [NSString stringDateFromString:string];
    

    【讨论】:

    • 发现这真的很有用。谢谢!
    【解决方案6】:

    以上示例并非简单地为 Swift 3.0+ 编写

    更新 - Swift 3.0+ - 将日期转换为字符串

    let date = Date() // insert your date data here
    var dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd" // add custom format if you'd like 
    var dateString = dateFormatter.string(from: date)
    

    【讨论】:

      【解决方案7】:

      NSString 到 NSDate 或 NSDate 到 NSString

      //This method is used to get NSDate from string 
      //Pass the date formate ex-"dd-MM-yyyy hh:mm a"
      + (NSDate*)getDateFromString:(NSString *)dateString withFormate:(NSString *)formate  {
      
          // Converted date from date string
          NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
          [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
          [dateFormatter setDateFormat:formate];
          NSDate *convertedDate         = [dateFormatter dateFromString:dateString];
          return convertedDate;
      }
      
      //This method is used to get the NSString for NSDate
      //Pass the date formate ex-"dd-MM-yyyy hh:mm a"
      + (NSString *)getDateStringFromDate:(NSDate *)date withFormate:(NSString *)formate {
      
          // Converted date from date string
          NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
          //[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
          [dateFormatter setDateFormat:formate];
          NSString *convertedDate         = [dateFormatter stringFromDate:date];
          return convertedDate;
      }
      

      【讨论】:

        【解决方案8】:

        根据 Swift 2.2

        您可以轻松地从 String 中获取 NSDate,从 NSDate 中获取 String。 例如

        第一次设置日期格式化程序

        let formatter = NSDateFormatter();
        formatter.dateStyle = NSDateFormatterStyle.MediumStyle
        formatter.timeStyle = .NoStyle
        formatter.dateFormat = "MM/dd/yyyy"
        

        现在从字符串中获取日期,反之亦然。

        let strDate = formatter.stringFromDate(NSDate())
        print(strDate)
        let dateFromStr = formatter.dateFromString(strDate)
        print(dateFromStr)
        

        现在享受吧。

        【讨论】:

          【解决方案9】:

          最佳实践是为自己构建一个通用类,在其中放置所有通用使用方法,在几乎所有项目中都有用的方法,并添加@Pavan 建议的代码为:

          + (NSDate *)getDateOutOfString:(NSString *)passedString andDateFormat:(NSString *)dateFormat{
          
              NSString *dateString = passedString;
              NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
              [dateFormatter setDateFormat:dateFormat];
              NSDate *dateFromString = [[NSDate alloc] init];
              dateFromString = [dateFormatter dateFromString:dateString];
              return dateFromString;
          
          }
          

          .. 以此类推所有其他有用的方法

          通过这样做,您开始为您的应用构建干净的可重用代码。 干杯!

          【讨论】:

            【解决方案10】:

            日期到 NSString

            NSString *dateString = [NSString stringWithFormat:@"%@",[NSDate date]];
            NSLog(@"string: %@",dateString ); //2015-03-24 12:28:49 +0000
            

            NSString 到 NSDate

            NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
            [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
            NSDate *date = [formatter dateFromString:dateString];
            NSLog(@"date: %@", date); //015-03-24 12:28:49 +0000
            

            【讨论】:

              【解决方案11】:

              您可以为此使用扩展。

              extension NSDate {
                  //NSString to NSDate
                  convenience
                  init(dateString:String) {
                      let nsDateFormatter = NSDateFormatter()
                      nsDateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
                      // Add the locale if required here
                      let dateObj = nsDateFormatter.dateFromString(dateString)
                      self.init(timeInterval:0, sinceDate:dateObj!)
                  }
              
                  //NSDate to time string
                  func getTime() -> String {
                      let timeFormatter = NSDateFormatter()
                      timeFormatter.dateFormat = "hh:mm"
                      //Can also set the default styles for date or time using .timeStyle or .dateStyle
                      return timeFormatter.stringFromDate(self)
                  }
              
                  //NSDate to date string
                  func getDate() -> String {
                      let dateFormatter = NSDateFormatter()
                      dateFormatter.dateFormat = "dd, MMM"
                      return dateFormatter.stringFromDate(self)
                  }
              
                  //NSDate to String
                  func getString() -> String {
                      let dateFormatter = NSDateFormatter()
                      dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
                      return dateFormatter.stringFromDate(self)
                  }
              }
              

              所以在执行时实际代码如下所示

                  var dateObjFromString = NSDate(dateString: cutDateTime)
                  var dateString = dateObjFromString.getDate()
                  var timeString = dateObjFromString.getTime()
                  var stringFromDate = dateObjFromString.getString()
              

              也有一些默认方法,但我想它可能不适用于您从文档中提供的格式

                  -dateFromString(_:)
                  -stringFromDate(_:)
                  -localizedStringFromDate(_ date: NSDate,
                                   dateStyle dateStyle: NSDateFormatterStyle,
                                   timeStyle timeStyle: NSDateFormatterStyle) -> String
              

              【讨论】:

                【解决方案12】:

                如果最近有人有兴趣在 Swift 中做这样的事情,我有一个开始,虽然它并不完美。

                func detectDate(dateString: NSString) -> NSDate {
                
                    var error: NSError?
                    let detector: NSDataDetector = NSDataDetector.dataDetectorWithTypes(NSTextCheckingType.Date.toRaw(), error: &error)!
                
                    if error == nil {
                        var matches = detector.matchesInString(dateString, options: nil, range: NSMakeRange(0, dateString.length))
                
                        let currentLocale = NSLocale.currentLocale()
                        for match in matches {
                            match.resultType == NSTextCheckingType.Date
                            NSLog("Date: \(match.date.description)")
                            return match.date
                        }
                    }
                    return NSDate()
                }
                

                【讨论】:

                  【解决方案13】:

                  使用此方法将NSString转换为NSdate

                  -(NSDate *)getDateFromString:(NSString *)pstrDate
                  {
                      NSDateFormatter* myFormatter = [[NSDateFormatter alloc] init];
                      [myFormatter setDateFormat:@"dd/MM/yyyy"];
                      NSDate* myDate = [myFormatter dateFromString:pstrDate];
                      return myDate;
                  }
                  

                  【讨论】:

                    【解决方案14】:

                    使用“10”表示年份不好,因为它可以是 1910、1810 等。您可能应该使用 4 位数字。

                    如果您可以将日期更改为类似

                    yyyymmdd
                    

                    那么你可以使用:

                    // Convert string to date object
                    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
                    [dateFormat setDateFormat:@"yyyyMMdd"];
                    NSDate *date = [dateFormat dateFromString:dateStr];  
                    
                    // Convert date object to desired output format
                    [dateFormat setDateFormat:@"EEEE MMMM d, YYYY"];
                    dateStr = [dateFormat stringFromDate:date];  
                    [dateFormat release];
                    

                    【讨论】:

                      【解决方案15】:
                      NSString *mystr=@"Your string date";
                      
                      NSCalendar *cal = [NSCalendar currentCalendar];
                      NSDate *now = [dateFormatter dateFromString:mystr];
                      
                      Nslog(@"%@",now);
                      

                      如果要设置格式,请使用以下代码:

                      NSString *dateString = @"01-02-2010";
                      NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
                      
                      // this is important - we set our input date format to match our input string
                      // if format doesn't match you'll get nil from your string, so be careful
                      [dateFormatter setDateFormat:@"dd-MM-yyyy"];
                      NSDate *dateFromString = [[NSDate alloc] init];
                      
                      // voila!
                      dateFromString = [dateFormatter dateFromString:dateString];
                      Nslog(@"%@",[dateFormatter dateFromString:dateString]);
                      

                      【讨论】:

                        【解决方案16】:
                        NSString *dateStr = @"Tue, 25 May 2010 12:53:58 +0000";
                        
                        // Convert string to date object
                        NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
                        [dateFormat setDateFormat:@"EE, d LLLL yyyy HH:mm:ss Z"];
                        NSDate *date = [dateFormat dateFromString:dateStr]; 
                        [dateFormat release];
                        

                        【讨论】:

                          【解决方案17】:
                          // Convert string to date 
                          
                          NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
                          [dateFormat setDateFormat:@"yyyyMMdd"];
                          NSDate *date = [dateFormat dateFromString:dateStr];  
                          
                          // Convert Date to string
                          
                          [dateFormat setDateFormat:@"EEEE MMMM d, YYYY"];
                          dateStr = [dateFormat stringFromDate:date];  
                          [dateFormat release];
                          

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 2014-08-12
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2011-04-24
                            • 2017-04-23
                            • 2021-09-11
                            相关资源
                            最近更新 更多