0

I'm trying to format a Date object in Swift using DateFormatter. I'm grabbing a Date object from a UIDatePicker in the format 2020-09-04T10:19:26+0000, and I want to reformat it to 2020-09-04 10:19.

From what I understand, DateFormatter can only create a Date object from a string using the date(from: String) method, or a string from a Date object using string(from: Date). Thus, for my seemingly simple use case, I would need two DateFormatters: One for converting my original date to a string, and a second one to format that string to my desired format and returning it as a Date object.

Is this really the "smart" way to re-format a Date object in Swift, or am I missing something?

edit:

I'm saving projects (which can have a due date) to a database. Later on, I plan on reading specific projects from the db based on their due date. The UIDatePicker returns an unformatted Date object (with seconds, offset and so on), but I only need the date, hour and minutes (exact to a 15 minute interval).

Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
hwollersheim
  • 81
  • 1
  • 5
  • Date data type is not mean to be reformatted, because represent a point in time, and is universal, so Date object is always well formatted, you need to use one date format or another depending of what format of date you want to show – Reinier Melian Sep 04 '20 at 10:30
  • 1
    A Date object has no format it's just holds data for date and time. Keep your Date object from the DatePicker as a Date until you need to show it in the UI then you use a formatter to format it into string – Joakim Danielson Sep 04 '20 at 10:30
  • How do you plan to use this "reformatted date"? That would be a good step to a good answer. – Roman Ryzhiy Sep 04 '20 at 10:35
  • 1
    @RomanRyzhiy Reformatting the date is pointless in this context. And to clarify to OP, the format you get when doing `print` or viewing a date object in the debugger is just a Date that has been formatted using a default format. – Joakim Danielson Sep 04 '20 at 10:36
  • @JoakimDanielson I do agree with you, but let's get the OP's answer. – Roman Ryzhiy Sep 04 '20 at 10:41
  • use case: I'm saving projects (which can have a due date) to a database. Later on, I plan on reading specific projects from the db based on their due date. The UIDatePicker returns an unformatted Date object (with seconds, offset and so on), but I only need the date, hour and minutes (exact to a 15 minute interval). – hwollersheim Sep 04 '20 at 11:29
  • @hwollersheim possible duplicate of https://stackoverflow.com/a/60084423/2303865 – Leo Dabus Sep 04 '20 at 12:49

2 Answers2

1

You are thinking about dates in the wrong way. The date is not a representation, but a fixed point in time, which can be represented in many ways, depending on how you write a date, and what timezone you're in. E.g. all of these can represent the exactly same point in time:

YYYY (eg 2020)
YYYY-MM (eg 2020-07)
YYYY-MM-DD (eg 2020-07-16)
YYYY-MM-DDThh:mmTZD (eg 2020-07-16T19:20+01:00)
YYYY-MM-DDThh:mm:ssTZD (eg 2020-07-16T19:20:30+01:00)
YYYY-MM-DDThh:mm:ss.sTZD (eg 2020-07-16T19:20:30.45+01:00)

So, if you would convert a Date to String, and then back to Date, you would usually get the same object back.

You need to note here that when starting from just a string, e.g. 2020-07-16T19:20, this represents a different information depending on the current timeZone, the calendar etc on each different device. If you store this info in the database, you will cause a lot of time-based bugs, so you should avoid it at all costs.

The Date object returned from the datePicker is a point in time, and can be formatted to show that time in whatever format you prefer, so use that for representation purposes, and store the actual Date object in the database.

Adis
  • 4,512
  • 2
  • 33
  • 40
0

Use like this:

let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

guard let inputTimeStamp = formatter.date(from: yourInputDate)?.timeIntervalSince1970 else { return }
let date = Date(timeIntervalSince1970: inputTimeStamp)
formatter.dateFormat = "yyyy-MM-dd HH:mm"
let string = formatter.string(from: date)
Dharman
  • 30,962
  • 25
  • 85
  • 135
Abhishek Mitra
  • 3,335
  • 4
  • 25
  • 46