0

I want to convert a string to a date, and then return a string again. I did this extension, but when I use it it doesn't work as it should.

For example if I have "2020-12-10" the result should be "10 de Diciembre de 2020", however I always get the same result "22 de Diciembre de 2021" and its not correct.

This is my code:

extension String {
    func dateFormatter(style: DateFormatter.Style) -> String? {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        formatter.timeZone = .current
        formatter.dateStyle = style
        formatter.locale = Locale(identifier: "es_AR")
        return formatter.string(from: Date())
    }
}

let dateExample = "2022-09-08" // This should be "8 de Septiembre de 2022"

let dateFormat = dateExample.dateFormatter(style: .long) // here i get "22 de diciembre de 2021"
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
akitainu22
  • 95
  • 1
  • 8
  • Please see the duplicate. You need to do this in two steps. Get a `Date` from the string (`self`) first, then use `string(from:)` on that date. – Sweeper Dec 22 '21 at 19:56
  • You will need 2 DateFormatters, one for the input format (`inputDateFormatter`) and one for the output format (`outputDateFormatter`.) First convert from a String to a Date using the `inputDateFormatter`. Then convert that Date to a String using the `outputDateFormatter` – Duncan C Dec 22 '21 at 20:48
  • `return formatter.string(from: Date())`, it means clearly: return a String in the format specificied for the `formatter` for the date which is `Date()`, ie "now" (so it's 22 of December). – Larme Dec 24 '21 at 08:40

1 Answers1

1

The main issue in your extension instance method when trying to decode your date string is that you are not using self which represents the string instance which is calling the method. Another problem there is that when parsing a fixed date format string you should set your date formatter's locale to "en_US_POSIX" BEFORE setting the dateFormat. This will make your date formatter ignore the device locale and settings. Note also that if you declare your formatter inside your instance method it will create a new formatter (which is an expensive operation) every time you call this method. Also be careful when using the device's current timezone when parsing a date without time. Make sure it is really what you want. Another issue there is dateStyle. You should use either dateFormat or date/time style. Not both of them. Use dateFormat when parsing a fixed date format and use date/time styles when displaying the date to the user as seen in this post:


extension Formatter {
    static let yyyMMdd: DateFormatter = {
        let formatter = DateFormatter()
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter
    }()
}

extension String {
    var yyyMMddToDate: Date? {
        Formatter.yyyMMdd.date(from: self)
    }
}

let dateExample = "2022-09-08"
if let date = dateExample.yyyMMddToDate {
    print(date.description(with: .current))  //   "Thursday, September 8, 2022 at 12:00:00 AM Brasilia Standard Time\n"
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571