| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors |
| // Licensed under Apache License v2.0 with Runtime Library Exception |
| // |
| // See http://swift.org/LICENSE.txt for license information |
| // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| // |
| |
| import CoreFoundation |
| |
| open class DateFormatter : Formatter { |
| typealias CFType = CFDateFormatter |
| private var __cfObject: CFType? |
| private var _cfObject: CFType { |
| guard let obj = __cfObject else { |
| #if os(OSX) || os(iOS) |
| let dateStyle = CFDateFormatterStyle(rawValue: CFIndex(self.dateStyle.rawValue))! |
| let timeStyle = CFDateFormatterStyle(rawValue: CFIndex(self.timeStyle.rawValue))! |
| #else |
| let dateStyle = CFDateFormatterStyle(self.dateStyle.rawValue) |
| let timeStyle = CFDateFormatterStyle(self.timeStyle.rawValue) |
| #endif |
| |
| let obj = CFDateFormatterCreate(kCFAllocatorSystemDefault, locale._cfObject, dateStyle, timeStyle)! |
| _setFormatterAttributes(obj) |
| if let dateFormat = _dateFormat { |
| CFDateFormatterSetFormat(obj, dateFormat._cfObject) |
| } |
| __cfObject = obj |
| return obj |
| } |
| return obj |
| } |
| |
| public override init() { |
| super.init() |
| } |
| |
| public required init?(coder: NSCoder) { |
| super.init(coder: coder) |
| } |
| |
| open var formattingContext: Context = .unknown // default is NSFormattingContextUnknown |
| |
| open func objectValue(_ string: String, range rangep: UnsafeMutablePointer<NSRange>) throws -> AnyObject? { NSUnimplemented() } |
| |
| open override func string(for obj: Any) -> String? { |
| guard let date = obj as? Date else { return nil } |
| return string(from: date) |
| } |
| |
| open func string(from date: Date) -> String { |
| return CFDateFormatterCreateStringWithDate(kCFAllocatorSystemDefault, _cfObject, date._cfObject)._swiftObject |
| } |
| |
| open func date(from string: String) -> Date? { |
| var range = CFRange(location: 0, length: string.length) |
| let date = withUnsafeMutablePointer(to: &range) { (rangep: UnsafeMutablePointer<CFRange>) -> Date? in |
| guard let res = CFDateFormatterCreateDateFromString(kCFAllocatorSystemDefault, _cfObject, string._cfObject, rangep) else { |
| return nil |
| } |
| return res._swiftObject |
| } |
| return date |
| } |
| |
| open class func localizedString(from date: Date, dateStyle dstyle: Style, timeStyle tstyle: Style) -> String { |
| let df = DateFormatter() |
| df.dateStyle = dstyle |
| df.timeStyle = tstyle |
| return df.string(for: date._nsObject)! |
| } |
| |
| open class func dateFormat(fromTemplate tmplate: String, options opts: Int, locale: Locale?) -> String? { |
| guard let res = CFDateFormatterCreateDateFormatFromTemplate(kCFAllocatorSystemDefault, tmplate._cfObject, CFOptionFlags(opts), locale?._cfObject) else { |
| return nil |
| } |
| return res._swiftObject |
| } |
| |
| open func setLocalizedDateFormatFromTemplate(_ dateFormatTemplate: String) { |
| NSUnimplemented() |
| } |
| |
| private func _reset() { |
| __cfObject = nil |
| } |
| |
| internal func _setFormatterAttributes(_ formatter: CFDateFormatter) { |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterIsLenient, value: isLenient._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterTimeZone, value: timeZone?._cfObject) |
| if let ident = _calendar?.identifier { |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterCalendarName, value: Calendar._toNSCalendarIdentifier(ident).rawValue._cfObject) |
| } else { |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterCalendarName, value: nil) |
| } |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterTwoDigitStartDate, value: _twoDigitStartDate?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterDefaultDate, value: defaultDate?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterCalendar, value: _calendar?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterEraSymbols, value: _eraSymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterMonthSymbols, value: _monthSymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterShortMonthSymbols, value: _shortMonthSymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterWeekdaySymbols, value: _weekdaySymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterShortWeekdaySymbols, value: _shortWeekdaySymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterAMSymbol, value: _amSymbol?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterPMSymbol, value: _pmSymbol?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterLongEraSymbols, value: _longEraSymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterVeryShortMonthSymbols, value: _veryShortMonthSymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterStandaloneMonthSymbols, value: _standaloneMonthSymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterShortStandaloneMonthSymbols, value: _shortStandaloneMonthSymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterVeryShortStandaloneMonthSymbols, value: _veryShortStandaloneMonthSymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterVeryShortWeekdaySymbols, value: _veryShortWeekdaySymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterStandaloneWeekdaySymbols, value: _standaloneWeekdaySymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterShortStandaloneWeekdaySymbols, value: _shortStandaloneWeekdaySymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterVeryShortStandaloneWeekdaySymbols, value: _veryShortStandaloneWeekdaySymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterQuarterSymbols, value: _quarterSymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterShortQuarterSymbols, value: _shortQuarterSymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterStandaloneQuarterSymbols, value: _standaloneQuarterSymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterShortStandaloneQuarterSymbols, value: _shortStandaloneQuarterSymbols?._cfObject) |
| _setFormatterAttribute(formatter, attributeName: kCFDateFormatterGregorianStartDate, value: _gregorianStartDate?._cfObject) |
| } |
| |
| internal func _setFormatterAttribute(_ formatter: CFDateFormatter, attributeName: CFString, value: AnyObject?) { |
| if let value = value { |
| CFDateFormatterSetProperty(formatter, attributeName, value) |
| } |
| } |
| |
| private var _dateFormat: String? { willSet { _reset() } } |
| open var dateFormat: String! { |
| get { |
| guard let format = _dateFormat else { |
| return __cfObject.map { CFDateFormatterGetFormat($0)._swiftObject } ?? "" |
| } |
| return format |
| } |
| set { |
| _dateFormat = newValue |
| } |
| } |
| |
| open var dateStyle: Style = .none { willSet { _dateFormat = nil; _reset() } } |
| |
| open var timeStyle: Style = .none { willSet { _dateFormat = nil; _reset() } } |
| |
| /*@NSCopying*/ open var locale: Locale! = .current { willSet { _reset() } } |
| |
| open var generatesCalendarDates = false { willSet { _reset() } } |
| |
| /*@NSCopying*/ open var timeZone: TimeZone! = NSTimeZone.system { willSet { _reset() } } |
| |
| /*@NSCopying*/ internal var _calendar: Calendar! { willSet { _reset() } } |
| open var calendar: Calendar! { |
| get { |
| guard let calendar = _calendar else { |
| return (CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterCalendar) as! NSCalendar)._swiftObject |
| } |
| return calendar |
| } |
| set { |
| _calendar = newValue |
| } |
| } |
| |
| open var isLenient = false { willSet { _reset() } } |
| |
| /*@NSCopying*/ internal var _twoDigitStartDate: Date? { willSet { _reset() } } |
| open var twoDigitStartDate: Date? { |
| get { |
| guard let startDate = _twoDigitStartDate else { |
| return (CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterTwoDigitStartDate) as? NSDate)?._swiftObject |
| } |
| return startDate |
| } |
| set { |
| _twoDigitStartDate = newValue |
| } |
| } |
| |
| /*@NSCopying*/ open var defaultDate: Date? { willSet { _reset() } } |
| |
| internal var _eraSymbols: [String]! { willSet { _reset() } } |
| open var eraSymbols: [String]! { |
| get { |
| guard let symbols = _eraSymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterEraSymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _eraSymbols = newValue |
| } |
| } |
| |
| internal var _monthSymbols: [String]! { willSet { _reset() } } |
| open var monthSymbols: [String]! { |
| get { |
| guard let symbols = _monthSymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterMonthSymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _monthSymbols = newValue |
| } |
| } |
| |
| internal var _shortMonthSymbols: [String]! { willSet { _reset() } } |
| open var shortMonthSymbols: [String]! { |
| get { |
| guard let symbols = _shortMonthSymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterShortMonthSymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _shortMonthSymbols = newValue |
| } |
| } |
| |
| |
| internal var _weekdaySymbols: [String]! { willSet { _reset() } } |
| open var weekdaySymbols: [String]! { |
| get { |
| guard let symbols = _weekdaySymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterWeekdaySymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _weekdaySymbols = newValue |
| } |
| } |
| |
| internal var _shortWeekdaySymbols: [String]! { willSet { _reset() } } |
| open var shortWeekdaySymbols: [String]! { |
| get { |
| guard let symbols = _shortWeekdaySymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterShortWeekdaySymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _shortWeekdaySymbols = newValue |
| } |
| } |
| |
| internal var _amSymbol: String! { willSet { _reset() } } |
| open var amSymbol: String! { |
| get { |
| guard let symbol = _amSymbol else { |
| return (CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterAMSymbol) as! NSString)._swiftObject |
| } |
| return symbol |
| } |
| set { |
| _amSymbol = newValue |
| } |
| } |
| |
| internal var _pmSymbol: String! { willSet { _reset() } } |
| open var pmSymbol: String! { |
| get { |
| guard let symbol = _pmSymbol else { |
| return (CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterPMSymbol) as! NSString)._swiftObject |
| } |
| return symbol |
| } |
| set { |
| _pmSymbol = newValue |
| } |
| } |
| |
| internal var _longEraSymbols: [String]! { willSet { _reset() } } |
| open var longEraSymbols: [String]! { |
| get { |
| guard let symbols = _longEraSymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterLongEraSymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _longEraSymbols = newValue |
| } |
| } |
| |
| internal var _veryShortMonthSymbols: [String]! { willSet { _reset() } } |
| open var veryShortMonthSymbols: [String]! { |
| get { |
| guard let symbols = _veryShortMonthSymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterVeryShortMonthSymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _veryShortMonthSymbols = newValue |
| } |
| } |
| |
| internal var _standaloneMonthSymbols: [String]! { willSet { _reset() } } |
| open var standaloneMonthSymbols: [String]! { |
| get { |
| guard let symbols = _standaloneMonthSymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterStandaloneMonthSymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _standaloneMonthSymbols = newValue |
| } |
| } |
| |
| internal var _shortStandaloneMonthSymbols: [String]! { willSet { _reset() } } |
| open var shortStandaloneMonthSymbols: [String]! { |
| get { |
| guard let symbols = _shortStandaloneMonthSymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterShortStandaloneMonthSymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _shortStandaloneMonthSymbols = newValue |
| } |
| } |
| |
| internal var _veryShortStandaloneMonthSymbols: [String]! { willSet { _reset() } } |
| open var veryShortStandaloneMonthSymbols: [String]! { |
| get { |
| guard let symbols = _veryShortStandaloneMonthSymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterVeryShortStandaloneMonthSymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _veryShortStandaloneMonthSymbols = newValue |
| } |
| } |
| |
| internal var _veryShortWeekdaySymbols: [String]! { willSet { _reset() } } |
| open var veryShortWeekdaySymbols: [String]! { |
| get { |
| guard let symbols = _veryShortWeekdaySymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterVeryShortWeekdaySymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _veryShortWeekdaySymbols = newValue |
| } |
| } |
| |
| internal var _standaloneWeekdaySymbols: [String]! { willSet { _reset() } } |
| open var standaloneWeekdaySymbols: [String]! { |
| get { |
| guard let symbols = _standaloneWeekdaySymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterStandaloneWeekdaySymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _standaloneWeekdaySymbols = newValue |
| } |
| } |
| |
| internal var _shortStandaloneWeekdaySymbols: [String]! { willSet { _reset() } } |
| open var shortStandaloneWeekdaySymbols: [String]! { |
| get { |
| guard let symbols = _shortStandaloneWeekdaySymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterShortStandaloneWeekdaySymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _shortStandaloneWeekdaySymbols = newValue |
| } |
| } |
| |
| internal var _veryShortStandaloneWeekdaySymbols: [String]! { willSet { _reset() } } |
| open var veryShortStandaloneWeekdaySymbols: [String]! { |
| get { |
| guard let symbols = _veryShortStandaloneWeekdaySymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterVeryShortStandaloneWeekdaySymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _veryShortStandaloneWeekdaySymbols = newValue |
| } |
| } |
| |
| internal var _quarterSymbols: [String]! { willSet { _reset() } } |
| open var quarterSymbols: [String]! { |
| get { |
| guard let symbols = _quarterSymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterQuarterSymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _quarterSymbols = newValue |
| } |
| } |
| |
| internal var _shortQuarterSymbols: [String]! { willSet { _reset() } } |
| open var shortQuarterSymbols: [String]! { |
| get { |
| guard let symbols = _shortQuarterSymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterShortQuarterSymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _shortQuarterSymbols = newValue |
| } |
| } |
| |
| internal var _standaloneQuarterSymbols: [String]! { willSet { _reset() } } |
| open var standaloneQuarterSymbols: [String]! { |
| get { |
| guard let symbols = _standaloneQuarterSymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterStandaloneQuarterSymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _standaloneQuarterSymbols = newValue |
| } |
| } |
| |
| internal var _shortStandaloneQuarterSymbols: [String]! { willSet { _reset() } } |
| open var shortStandaloneQuarterSymbols: [String]! { |
| get { |
| guard let symbols = _shortStandaloneQuarterSymbols else { |
| let cfSymbols = CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterShortStandaloneQuarterSymbols) as! NSArray |
| return cfSymbols.allObjects as! [String] |
| } |
| return symbols |
| } |
| set { |
| _shortStandaloneQuarterSymbols = newValue |
| } |
| } |
| |
| internal var _gregorianStartDate: Date? { willSet { _reset() } } |
| open var gregorianStartDate: Date? { |
| get { |
| guard let startDate = _gregorianStartDate else { |
| return (CFDateFormatterCopyProperty(_cfObject, kCFDateFormatterGregorianStartDate) as? NSDate)?._swiftObject |
| } |
| return startDate |
| } |
| set { |
| _gregorianStartDate = newValue |
| } |
| } |
| |
| open var doesRelativeDateFormatting = false { willSet { _reset() } } |
| } |
| |
| extension DateFormatter { |
| public enum Style : UInt { |
| case none |
| case short |
| case medium |
| case long |
| case full |
| } |
| } |