asheyla
asheyla

Reputation: 3335

Convert string to date in Swift

How can I convert this string "2016-04-14T10:44:00+0000" into an NSDate and keep only the year, month, day, hour?

The T in the middle of it really throws off what I am used to when working with dates.

Upvotes: 235

Views: 424585

Answers (18)

Balaji Ramakrishnan
Balaji Ramakrishnan

Reputation: 1959

Try the following Date Format.

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ssZZZ"
let date = dateFormatter.dateFromString(strDate)

For Swift 4.1:

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ssZZZ"
let date = dateFormatter.date(from: strDate)

Upvotes: 60

vadian
vadian

Reputation: 285260

  • Convert the ISO8601 string to date

      let isoDate = "2016-04-14T10:44:00+0000"
    
      let dateFormatter = DateFormatter()
      dateFormatter.locale = Locale(identifier: "en_US_POSIX") // set locale to reliable US_POSIX
      dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
      let date = dateFormatter.date(from:isoDate)!
    
  • Get the date components for year, month, day and hour from the date

      let calendar = Calendar.current
      let components = calendar.dateComponents([.year, .month, .day, .hour], from: date)
    
  • Finally create a new Date object and strip minutes and seconds

      let finalDate = calendar.date(from:components)
    

Consider also the convenience formatter ISO8601DateFormatter introduced in iOS 10 / macOS 10.12:

let isoDate = "2016-04-14T10:44:00+0000"

let dateFormatter = ISO8601DateFormatter()
let date = dateFormatter.date(from:isoDate)!

Upvotes: 407

Kobi
Kobi

Reputation: 109

Swift 5.6

Here is an easy way to get a string and convert it back to string with Date in structure by String extension

Date String Example "2022-03-15T07:13:49.607+00:00"

If the date is not in the format "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ" It will return 01-01-70

import Foundation

extension String {

  func convertToDate() -> String {
   
      let dateFormatter = DateFormatter()
      dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ"
      if let dt = dateFormatter.date(from: self) {
          dateFormatter.dateFormat = "MM-dd-yy"
          let formatedStringDate = dateFormatter.string(from: dt)
              return formatedStringDate
      }
    
   
      return "01-01-70"
  }
}

Upvotes: 4

Wo_0NDeR ᵀᴹ
Wo_0NDeR ᵀᴹ

Reputation: 633

What about SwiftDate ?. The best Date and Time parsing and manipulation library for Swift.

https://github.com/malcommac/SwiftDate#1-date-parsing

Install using Cocoa Pods: https://github.com/malcommac/SwiftDate/blob/master/Documentation/0.Informations.md#installation

And then:

import SwiftDate

// All default datetime formats (15+) are recognized automatically
let _ = "2010-05-20 15:30:00".toDate()
// You can also provide your own format!
let _ = "2010-05-20 15:30".toDate("yyyy-MM-dd HH:mm")
// All ISO8601 variants are supported too with timezone parsing!
let _ = "2017-09-17T11:59:29+02:00".toISODate()
// RSS, Extended, HTTP, SQL, .NET and all the major variants are supported!
let _ = "19 Nov 2015 22:20:40 +0100".toRSS(alt: true)

Upvotes: 1

Devo
Devo

Reputation: 1124

Since iOS 15.0, we can convert a String to Date in a more swift way:

let strategy = Date.ParseStrategy(format: "\(year: .defaultDigits)-\(month: .twoDigits)-\(day: .twoDigits)T\(hour: .twoDigits(clock: .twentyFourHour, hourCycle: .zeroBased)):\(minute: .twoDigits):\(second: .twoDigits)\(timeZone: .iso8601(.short))", timeZone: .current)
let date = try? Date("2016-04-14T10:44:00+0000", strategy: strategy)

Upvotes: 17

Abishek Thangaraj
Abishek Thangaraj

Reputation: 923

Converting string to Date in swift using the string extension Swift - 5.0

    extension String {
         public enum DateFormatType {
        
        /// The ISO8601 formatted year "yyyy" i.e. 1997
        case isoYear
        
        /// The ISO8601 formatted year and month "yyyy-MM" i.e. 1997-07
        case isoYearMonth
        
        /// The ISO8601 formatted date "yyyy-MM-dd" i.e. 1997-07-16
        case isoDate
        
        /// The ISO8601 formatted date and time "yyyy-MM-dd'T'HH:mmZ" i.e. 1997-07-16T19:20+01:00
        case isoDateTime
        
        /// The ISO8601 formatted date, time and sec "yyyy-MM-dd'T'HH:mm:ssZ" i.e. 1997-07-16T19:20:30+01:00
        case isoDateTimeSec
        
        /// The ISO8601 formatted date, time and millisec "yyyy-MM-dd'T'HH:mm:ss.SSSZ" i.e. 1997-07-16T19:20:30.45+01:00
        case isoDateTimeMilliSec
        
        /// The dotNet formatted date "/Date(%d%d)/" i.e. "/Date(1268123281843)/"
        case dotNet
        
        /// The RSS formatted date "EEE, d MMM yyyy HH:mm:ss ZZZ" i.e. "Fri, 09 Sep 2011 15:26:08 +0200"
        case rss
        
        /// The Alternative RSS formatted date "d MMM yyyy HH:mm:ss ZZZ" i.e. "09 Sep 2011 15:26:08 +0200"
        case altRSS
        
        /// The http header formatted date "EEE, dd MM yyyy HH:mm:ss ZZZ" i.e. "Tue, 15 Nov 1994 12:45:26 GMT"
        case httpHeader
        
        /// A generic standard format date i.e. "EEE MMM dd HH:mm:ss Z yyyy"
        case standard
        
        /// A custom date format string
        case custom(String)
        
        /// The local formatted date and time "yyyy-MM-dd HH:mm:ss" i.e. 1997-07-16 19:20:00
        case localDateTimeSec
        
        /// The local formatted date  "yyyy-MM-dd" i.e. 1997-07-16
        case localDate
        
        /// The local formatted  time "hh:mm a" i.e. 07:20 am
        case localTimeWithNoon
        
        /// The local formatted date and time "yyyyMMddHHmmss" i.e. 19970716192000
        case localPhotoSave
        
        case birthDateFormatOne
        
        case birthDateFormatTwo
        
        ///
        case messageRTetriveFormat
        
        ///
        case emailTimePreview
        
        var stringFormat:String {
          switch self {
          //handle iso Time
          case .birthDateFormatOne: return "dd/MM/YYYY"
          case .birthDateFormatTwo: return "dd-MM-YYYY"
          case .isoYear: return "yyyy"
          case .isoYearMonth: return "yyyy-MM"
          case .isoDate: return "yyyy-MM-dd"
          case .isoDateTime: return "yyyy-MM-dd'T'HH:mmZ"
          case .isoDateTimeSec: return "yyyy-MM-dd'T'HH:mm:ssZ"
          case .isoDateTimeMilliSec: return "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
          case .dotNet: return "/Date(%d%f)/"
          case .rss: return "EEE, d MMM yyyy HH:mm:ss ZZZ"
          case .altRSS: return "d MMM yyyy HH:mm:ss ZZZ"
          case .httpHeader: return "EEE, dd MM yyyy HH:mm:ss ZZZ"
          case .standard: return "EEE MMM dd HH:mm:ss Z yyyy"
          case .custom(let customFormat): return customFormat
            
          //handle local Time
          case .localDateTimeSec: return "yyyy-MM-dd HH:mm:ss"
          case .localTimeWithNoon: return "hh:mm a"
          case .localDate: return "yyyy-MM-dd"
          case .localPhotoSave: return "yyyyMMddHHmmss"
          case .messageRTetriveFormat: return "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
          case .emailTimePreview: return "dd MMM yyyy, h:mm a"
          }
        }  
 }
        
 func toDate(_ format: DateFormatType = .isoDate) -> Date?{
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = format.stringFormat
        let date = dateFormatter.date(from: self)
        return date 
  }
 }

we use like

    string.toDate(.isoDate)
    "1997-05-24".toDate(.isoDate)

Upvotes: 18

Ucdemir
Ucdemir

Reputation: 3098

Sometimes, converting string to Date in swift can result to return nil so that you should add "!" mark to format.date function!

let dateFormatterUK = DateFormatter()
dateFormatterUK.dateFormat = "dd-MM-yyyy"

let stringDate = "11-03-2018"
let date = dateFormatterUK.date(from: stringDate)!

Upvotes: 3

Narendra Jagne
Narendra Jagne

Reputation: 446

make global function

func convertDateFormat(inputDate: String) -> String {

     let olDateFormatter = DateFormatter()
     olDateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"

     let oldDate = olDateFormatter.date(from: inputDate)

     let convertDateFormatter = DateFormatter()
     convertDateFormatter.dateFormat = "MMM dd yyyy h:mm a"

     return convertDateFormatter.string(from: oldDate!)
}

Called function and pass value in it

get_OutputStr = convertDateFormat(inputDate: "2019-03-30T05:30:00+0000")

and here is output

Feb 25 2020 4:51 PM



 

Upvotes: 20

LeoNard
LeoNard

Reputation: 290

Just use SwifterSwift.

stringDate = "2020-04-26T08:56:17.987Z"
let date = Date(iso8601String: stringDate)

Upvotes: 1

Alan Silva
Alan Silva

Reputation: 138

I was getting crazy with this format as well.

See the solution below.

Your String that came from your back or another source:

    let isoDate = "2020-05-06 20:00:00-03"

Identify the date format

    let dateFormatter = DateFormatter()
    dateFormatter.locale = Locale(identifier: "en_US_POSIX")
    dateFormatter.dateFormat = "yyyy-MM-dd' 'HH:mm:ssZ"
    let date = dateFormatter.date(from:isoDate)!

Now that you have the date as Date() you can change to whatever format you want using the formatDate.string

    let formatDate = DateFormatter()
    formatDate.dateFormat = "dd/MM/yyyy HH:mm"
    let drawDate = formatDate.string(from: date)
    print(drawDate)

Output:

    06/05/2020 20:00

Upvotes: 5

Thyselius
Thyselius

Reputation: 954

Swift 5. To see IF A DATE HAS PASSED:

let expiryDate = "2020-01-10" // Jan 10 2020

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"

if Date() < dateFormatter.date(from: expiryDate) ?? Date() {
    print("Not Yet expiryDate")
} else {
    print("expiryDate has passed")
}

Upvotes: 17

Akshay K
Akshay K

Reputation: 91

just Step 1 > get the String value from JSON or dataSource

Step 2 > create a local variable and assign it.

let startDate = CurrentDashBoard.startdate

Step 3> create an instance of DateFormatter.

let dateFormatter = DateFormatter()

step 4> call the dateFormat from dateFormatter and provide saved date dataType.

dateFormatter.dateFormat = "MM-dd-yyyy HH:mm:ss"("may be String formate")

step 5> Assign the Local variable to this variable to convert.

let dateFromStringstartDate : NSDate = dateFormatter.date(from: startDate)! as NSDate

Step 6> provide your required date Formate by the following code.

dateFormatter.dateFormat = "MM/dd/yyyy HH:mm:ss"

Step 6> Assign it to label/text

cell.lblStartDate.text = String(format: "%@", strstartDate)

Code:

let startDate = CurrentDashBoard.startdate let dateFormatter = DateFormatter() 
dateFormatter.dateFormat = "MM-dd-yyyy HH:mm:ss" let dateFromStringstartDate : 
NSDate = dateFormatter.date(from: startDate)! as NSDate
dateFormatter.dateFormat = "MM/dd/yyyy HH:mm:ss"
let strstartDate = dateFormatter.string(from: dateFromStringstartDate as Date)

Upvotes: 4

Fuhad saneen
Fuhad saneen

Reputation: 119

In swift4,

    var Msg_Date_ = "2019-03-30T05:30:00+0000"

    let dateFormatterGet = DateFormatter()
    dateFormatterGet.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
    let dateFormatterPrint = DateFormatter()
    dateFormatterPrint.dateFormat = "MMM dd yyyy h:mm a"  //"MMM d, h:mm a" for  Sep 12, 2:11 PM
    let datee = dateFormatterGet.date(from: Msg_Date_)
    Msg_Date_ =  dateFormatterPrint.string(from: datee ?? Date())

    print(Msg_Date_)

//output :- Mar 30 2019 05:30 PM

Upvotes: 2

Mohammad Razipour
Mohammad Razipour

Reputation: 3711

Swift 3.0 - 4.2

import Foundation

extension String {

    func toDate(withFormat format: String = "yyyy-MM-dd HH:mm:ss")-> Date?{

        let dateFormatter = DateFormatter()
        dateFormatter.timeZone = TimeZone(identifier: "Asia/Tehran")
        dateFormatter.locale = Locale(identifier: "fa-IR")
        dateFormatter.calendar = Calendar(identifier: .gregorian)
        dateFormatter.dateFormat = format
        let date = dateFormatter.date(from: self)

        return date

    }
}

extension Date {

    func toString(withFormat format: String = "EEEE ، d MMMM yyyy") -> String {

        let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale(identifier: "fa-IR")
        dateFormatter.timeZone = TimeZone(identifier: "Asia/Tehran")
        dateFormatter.calendar = Calendar(identifier: .persian)
        dateFormatter.dateFormat = format
        let str = dateFormatter.string(from: self)

        return str
    }
}

Upvotes: 30

thetrutz
thetrutz

Reputation: 1555

Please use an ISO8601 parsing library for doing this. There are too many ways how the string could be encoded. Don't rely on a specific format and don't rely on the server sending always the same. The problems start with the 'Z' at the end and it will extend through all varieties of the standard. A parsing library will handle all cases and will always provide a safe conversion - whereas a fixed formatting string is likely to fail in the future.

You could use one of these libraries. They are also available on CococaPods:

https://github.com/boredzo/iso-8601-date-formatter/

https://github.com/malcommac/SwiftDate

Take a look at the implementations. They are both several hundred lines long - for good reason.

With regards to the question: You can pull out the date components from the date using NSDateComponents. The example on the website covers exactly your case.

https://developer.apple.com/documentation/foundation/nscalendar/1414841-components?language=objc

Please be aware, that converting your date will take into account the time zone. You might want to set the 'locale' of the NSCalendar explicitly.

Upvotes: 0

Paul Spiesberger
Paul Spiesberger

Reputation: 5770

In Swift 4.1 you can do:

func getDate() -> Date? {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
    dateFormatter.timeZone = TimeZone.current
    dateFormatter.locale = Locale.current
    return dateFormatter.date(from: "2015-04-01T11:42:00") // replace Date String
}

Upvotes: 39

Mitul Marsoniya
Mitul Marsoniya

Reputation: 5299

Just your passing your dateformate and your date then you get Year,month,day,hour. Extra info

func GetOnlyDateMonthYearFromFullDate(currentDateFormate:NSString , conVertFormate:NSString , convertDate:NSString ) -> NSString
    {
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = currentDateFormate as String
        let formatter = NSDateFormatter()
        formatter.dateFormat = Key_DATE_FORMATE as String
        let finalDate = formatter.dateFromString(convertDate as String)
        formatter.dateFormat = conVertFormate as String
        let dateString = formatter.stringFromDate(finalDate!)

        return dateString
    }


Get Year

let Year = self.GetOnlyDateMonthYearFromFullDate("yyyy-MM-dd'T'HH:mm:ssZ", conVertFormate: "YYYY", convertDate: "2016-04-14T10:44:00+0000") as String


Get Month

let month = self.GetOnlyDateMonthYearFromFullDate("yyyy-MM-dd'T'HH:mm:ssZ", conVertFormate: "MM", convertDate: "2016-04-14T10:44:00+0000") as String


Get Day

let day = self.GetOnlyDateMonthYearFromFullDate("yyyy-MM-dd'T'HH:mm:ssZ", conVertFormate: "dd", convertDate: "2016-04-14T10:44:00+0000") as String


Get Hour

let hour  = self.GetOnlyDateMonthYearFromFullDate("yyyy-MM-dd'T'HH:mm:ssZ", conVertFormate: "hh", convertDate: "2016-04-14T10:44:00+0000") as String

Upvotes: 6

Arun
Arun

Reputation: 644

Hi You have separate T Format and then convert as you like

// create dateFormatter with UTC time format
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
dateFormatter.timeZone = NSTimeZone(name: "UTC")
let date = dateFormatter.dateFromString("2015-04-01T11:42:00")

// change to a readable time format and change to local time zone
dateFormatter.dateFormat = "EEE, MMM d, yyyy - h:mm a"
dateFormatter.timeZone = NSTimeZone.localTimeZone() 
let timeStamp = dateFormatter.stringFromDate(date!)

Upvotes: 13

Related Questions