How to get the current time as datetime
Update for Swift 3:
let date = Date()
let calendar = Calendar.current
let hour = calendar.component(.hour, from: date)
let minutes = calendar.component(.minute, from: date)
I do this:
let date = NSDate()
let calendar = NSCalendar.currentCalendar()
let components = calendar.components(.CalendarUnitHour | .CalendarUnitMinute, fromDate: date)
let hour = components.hour
let minutes = components.minute
See the same question in objective-c How do I get hour and minutes from NSDate?
Compared to Nate’s answer, you’ll get numbers with this one, not strings… pick your choice!
Date Format in Swift
You have to declare 2 different NSDateFormatters
, the first to convert the string to a NSDate
and the second to print the date in your format.
Try this code:
let dateFormatterGet = NSDateFormatter()
dateFormatterGet.dateFormat = "yyyy-MM-dd HH:mm:ss"
let dateFormatterPrint = NSDateFormatter()
dateFormatterPrint.dateFormat = "MMM dd,yyyy"
let date: NSDate? = dateFormatterGet.dateFromString("2016-02-29 12:24:26")
print(dateFormatterPrint.stringFromDate(date!))
Swift 3 and higher:
From Swift 3 NSDate
class has been changed to Date
and NSDateFormatter
to DateFormatter
.
let dateFormatterGet = DateFormatter()
dateFormatterGet.dateFormat = "yyyy-MM-dd HH:mm:ss"
let dateFormatterPrint = DateFormatter()
dateFormatterPrint.dateFormat = "MMM dd,yyyy"
if let date = dateFormatterGet.date(from: "2016-02-29 12:24:26") {
print(dateFormatterPrint.string(from: date))
} else {
print("There was an error decoding the string")
}
How to take just the current time (hh:mm:ss format) from Date() in Swift?
You are printing the Date
object directly, which uses a predetermined description
algorithm to display the date.
But one should not try to parse strings out of that. Instead use DateFormatter
to build your date/time strings. So, you might have a date formatter for the date and another for the time:
let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .short
return formatter
}()
let timeFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.timeStyle = .medium
return formatter
}()
Note, I would advise not using hard-coded date format strings and setting the formatter’s dateFormat
string, but rather use these “style” properties to dictate the type of string you want, while still honoring the preferences of the user (e.g. 01-02-21
will be interpreted as January 2nd in the US, but February 1st in many other locales).
Anyway, now that you have those formatter properties, you can use them in your code. E.g., given that you tagged this as swiftui, you might use Text
with formatter
:
var body: some View {
VStack {
Text("Date: \(date, formatter: dateFormatter)")
Text("Time: \(date, formatter: timeFormatter)")
}
}
Or, you can use the DateFormatter
method string(from:)
to manually get the string:
let string = dateFormatter.string(from: date)
print(string) // 5/30/21 in the US; 30/5/21 in many other locales
On the other hand, if this string was not for display in the UI and you really wanted a fixed string format (e.g. you were writing the date string to persistent storage or including it in some web request), you would instead use ISO8601DateFormatter
(which produces ISO8601/RFC3339 date strings, which are fixed format and, by default, in GMT/Zulu), e.g.:
let formatter = ISO8601DateFormatter()
let string = formatter.string(from: date)
print(string) // 2021-05-30T17:27:45Z
Date format in Swift TODAY TOMORROW YESTERDAY
The DateFormatter doesn't behave well when setting doesRelativeDateFormatting = true
and trying to apply a custom format at the same time. So the easiest solution is to use the format given by a Style
and a Locale
let relativeDateFormatter = DateFormatter()
relativeDateFormatter.timeStyle = .none
relativeDateFormatter.dateStyle = .medium
relativeDateFormatter.locale = Locale(identifier: "en_GB")
relativeDateFormatter.doesRelativeDateFormatting = true
Example
let inputFormatter = DateFormatter()
inputFormatter.dateFormat = "yyyy-MM-dd"
let dates = ["2020-09-01", "2020-09-15", "2020-09-16", "2020-09-30"].compactMap { inputFormatter.date(from: $0)}
for date in dates {
print(relativeDateFormatter.string(from: date))
}
1 Sep 2020
Yesterday
Today
30 Sep 2020
Now if you want to apply a custom format I have not found a solution for this when using the same DateFormatter instance so we need to create a new one for the custom format and use it together with a check so we apply the custom format only when it is not Today etc
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE, MMM dd"
for date in dates {
let string = relativeDateFormatter.string(from: date)
if let _ = string.rangeOfCharacter(from: .decimalDigits) {
print(dateFormatter.string(from: date))
} else {
print(string)
}
}
Tuesday, Sep 01
Yesterday
Today
Wednesday, Sep 30
How to do a proper Date formatter in Swift
You don't need two date formatters to convert one date string to another.
My suggestion is to create one persistent date formatter with a fixed locale
let dateFormatter : DateFormatter = {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
return formatter
}()
This could be also an extension
extension DateFormatter {
static let posixFormatter : DateFormatter = {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
return formatter
}()
}
And secondly a function with parameters for input format with a default value and output format
func formatDate(dateString: String, inFormat: String = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", outFormat: String) -> String? {
// let dateFormatter = DateFormatter.posixFormatter
//this is format I get from my response
dateFormatter.dateFormat = inFormat
guard let date = dateFormatter.date(from: dateString) else { return nil }
dateFormatter.dateFormat = outFormat
return dateFormatter.string(from: date)
}
You have to check if a date could be created from the string so the return value is an optional.
Side note:
The Z
in an ISO8601 string is the time zone specifier. It must not be wrapped in single quotes. And the year specifier is always lowercase yyyy
.
How to format date string if the given date format changes
You can create two date formatters, one with time and another without it and use nil coalescing operator to provide a fallback in case the first one fails. Regarding the date format when returning your final string you should respect the user's device locale and settings. Just use dateStyle and timeStyle when displaying a date to the user:
extension Formatter {
static let date: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
static let dateAndTime: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
return formatter
}()
static let localizedDate: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .none
return formatter
}()
}
extension Date {
var localizedDate: String { Formatter.localizedDate.string(from: self) }
}
func formatted(from string: String?) -> String {
guard
let string = string,
let date = Formatter.dateAndTime.date(from: string) ??
Formatter.date.date(from: string)
else { return "" }
return date.localizedDate
}
let strFromApi = "2020-12-22 00:00:00" // "2020-12-22" //
formatted(from: strFromApi) // "Dec 22, 2020"
Related Topics
Saving Custom Swift Class With Nscoding to Userdefaults
Segue and Button Programmatically Swift
How to Use Swift'S Codable to Encode into a Dictionary
Check If 'Any' Value Is Object
Why Constant Constraints the Property from a Structure Instance But Not the Class Instance
How to Display My App Documents in the Files App For Iphone
Is This Response from the Compiler Valid
How to Remove the Left and Right Padding of a List in Swiftui
How to Fix Cocoapod .Modulemap File Not Found
Trying to Understand Asynchronous Operation Subclass
Real Time Nstask Output to Nstextview With Swift
How to Apply the Type to a Nsfetchrequest Instance
Binary Operator * Cannot Be Applied to Operands of Type Int and Double