在Swift中创建NSDateFormatter?

Joh*_*ard 23 date objective-c nsdate nsdateformatter swift

我是新手,对Objective-C非常不熟悉.有人可以帮我把它转换成Swift吗?我从Ray Wenderlich最好的iOS实践中获得了这段代码 - http://www.raywenderlich.com/31166/25-ios-app-performance-tips-tricks

你会把这段代码放在哪里?它会进入一个充满全局变量的类文件吗?

- (NSDateFormatter *)formatter {
    static NSDateFormatter *formatter;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _formatter = [[NSDateFormatter alloc] init];
        _formatter.dateFormat = @"EEE MMM dd HH:mm:ss Z yyyy"; // twitter date format
    });
    return formatter;
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*Rob 57

  1. 如果您真的想在问题中直接使用该方法,那么在Swift 3中您可以执行以下操作:

    class MyObject {
    
        // define static variable
    
        private static let formatter: DateFormatter = {
            let formatter = DateFormatter()
            formatter.dateFormat = "EEE MMM dd HH:mm:ss Z yyyy"
            return formatter
        }()
    
        // you could use it like so
    
        func someMethod(date: Date) -> String {
            return MyObject.formatter.string(from: date)
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    或者在Swift 2中:

    class MyObject {
    
        // define static variable
    
        private static let formatter: NSDateFormatter = {
            let formatter = NSDateFormatter()
            formatter.dateFormat = "EEE MMM dd HH:mm:ss Z yyyy"
            return formatter
        }()
    
        // you could use it like so
    
        func someMethod(date: NSDate) -> String {
            return MyObject.formatter.stringFromDate(date)
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    static像globals这样的属性享受dispatch_once默认值的行为.有关更多信息,请参阅Apple Swift博客中文件和初始化条目dispatch_once末尾的讨论.

  2. 关于日期格式化程序的最佳实践,我建议:

    • 是的,谨慎的做法是不要不必要地创建和销毁您可能需要再次使用的格式化程序.在WWDC 2012视频中,iOS App Performance:Responsiveness,Apple明确鼓励我们

      • 每个日期格式缓存一个格式化程序;

      • 如果发生这种情况,NSLocale.currentLocaleDidChangeNotification在Swift 3中添加观察者(NSCurrentLocaleDidChangeNotification在Swift 2中)NSNotificationCenter,并清除/重置缓存的格式化程序; 和

      • 请注意,重置格式与重新创建一样昂贵,因此请避免重复更改格式化程序的格式字符串.

      最重要的是,如果您反复使用相同的日期格式,请尽可能重复使用日期格式化程序.

    • 如果NSDateFormatter用于解析要与Web服务交换的日期字符串(或存储在数据库中),则应使用en_US_POSIX区域设置来避免可能未使用Gregorian日历的国际用户出现问题.请参阅Apple Technical Q&A#1480.(或者在iOS 10和macOS 10.12中,使用ISO8601DateFormatter.)

      但是当dateFormatNSDateFormatter/一起DateFormatter使用时,使用当前语言环境创建要呈现给最终用户的字符串,但en_US_POSIX在创建/解析字符串时使用local,以在应用程序内部使用或与Web服务交换.

    • 如果格式化用户界面的日期字符串,则通过避免使用字符串文字来本地化字符串(dateFormat如果可能).使用dateStyletimeStyle尽可能.如果您必须使用自定义dateFormat,请使用模板来本地化您的字符串.例如,E, MMM d在Swift 3中,您可以使用dateFormat(fromTemplate:options:locale:)以下命令而不是硬编码:

      formatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "EdMMM", options: 0, locale: Locale.current)
      
      Run Code Online (Sandbox Code Playgroud)

      或者在Swift 2中,dateFormatFromTemplate(_:options:locale:):

      formatter.dateFormat = NSDateFormatter.dateFormatFromTemplate("EdMMM", options: 0, locale: NSLocale.currentLocale())
      
      Run Code Online (Sandbox Code Playgroud)

      例如,这将自动显示美国用户的"Mon,Sep 5",但英国用户将显示"Mon 9 Sep".

    • NSDateFormatter现在线程在MacOS 10.9及更高版本运行iOS 7及更高版本和64位应用程序的安全.


Pab*_*loR 20

正如Rob所说,你必须小心创建DateFormatters的性能,使用那个WWDC会话的提示.

我这样做是作为NSDate和NSDateFormatter的扩展(在Swift 2,3和4中测试的代码):

extension NSDate {
    func PR2DateFormatterUTC() -> String {
        return NSDateFormatter.PR2DateFormatterUTC.stringFromDate(self)
    }
    //... more formats
}

extension NSDateFormatter {
    fileprivate static let PR2DateFormatterUTC: NSDateFormatter = {
        let formatter = NSDateFormatter()
        let timeZone = NSTimeZone(name:"UTC")
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        formatter.timeZone = timeZone
        return formatter
    }()
    //... more formats
}
Run Code Online (Sandbox Code Playgroud)

用法:

    let dateStringUTC  = NSDate().PR2DateFormatterUTC()
Run Code Online (Sandbox Code Playgroud)