I want to show a date as Saturday June 13.
If the date is current day it should display Today like that Tomorrow, Yesterday.
I couldn't achieve both
guard let date = Date(fromString: "16 September 2020",
format: "dd MMMM yyyy") else { return nil }
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.doesRelativeDateFormatting = true
header.titleLabel.text = dateFormatter.string(from: date)
For the above code I can show date as Today Tomorrow Yesterday but other dates are not showing Saturday June 13. I tried to apply date format dateFormatter.dateFormat = "EEEE, MMM d" for the same dateFormatter it returned nothing.
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
You can also use RelativeDateFormatter. Here is an example:
let date = Date().addingTimeInterval(-4 * 24 * 60 * 60)
let formatter = RelativeDateTimeFormatter()
formatter.unitsStyle = .full
let relativeDate = formatter.localizedString(for: date, relativeTo: Date())
print(relativeDate) // 4 days ago
Related
I am getting some date string from server, like "2021-06-25"
If it is today date or yesterday date, I have to show like Today or Yesterday.
Else I have to show 25 June 2021
For Today and Yesterday date its working fine.
But, If its other day, it is showing 25 Jun 2021
How to show 21 June 2021
static func getDay(_ nowDay: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let journalDate = dateFormatter.date(from: nowDay)
if let convertedDate = journalDate {
let relativeDateFormatter = DateFormatter()
relativeDateFormatter.timeStyle = .none
relativeDateFormatter.dateStyle = .medium
relativeDateFormatter.locale = Locale(identifier: "en_GB")
relativeDateFormatter.doesRelativeDateFormatting = true
let inputFormatter = DateFormatter()
inputFormatter.dateFormat = "yyyy-MM-dd"
return relativeDateFormatter.string(from: convertedDate)
}
return ""
}
Any suggestions?
If you want the full name of the month, use .long rather than .medium as the date style:
relativeDateFormatter.dateStyle = .long
Also note that you can use a ISO8601DateFormatter to parse nowDay, since it is in ISO-8601 format:
let dateFormatter = ISO8601DateFormatter()
dateFormatter.formatOptions = [.withFullDate]
let journalDate = dateFormatter.date(from: nowDay)
i get from json the following format, specifically these are two of the ones I get:
"createdAt":"2020-09-21T18:24:36.787Z",
"createdAt":"2020-09-21T18:45:05.250Z",
I used this format:
lazy var formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
formatter.timeZone = TimeZone(abbreviation: "UTC+8")
formatter.locale = Locale.current
formatter.dateStyle = .medium
formatter.timeStyle = .none
return formatter
}()
however, the application only gives me back:
Sep 22, 2020
Sep 22, 2020
why is it not time?
Z in your date string means UTC The "Z" in your dateFormat "yyyy-MM-dd'T'HH:mm:ss.SSSZ" will interprete that as UTC. It doesn't matter which timezone you set your date formatter to. It will only make a difference when getting a string from a Date. Btw You should always set your dateFormatter locale to "en_US_POSIX" before setting the dateFormat when parsing fixed date formats.
Besides that you can not use dateFormat and date/time styles together. It is one or the other.
let formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.locale = .init(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
formatter.timeZone = TimeZone(secondsFromGMT: 0)
return formatter
}()
if let date = formatter.date(from: "2020-09-21T18:24:36.787Z") {
print(date.description(with: .current)) // Monday, 21 September 2020 15:24:36 Brasilia Standard Time
let dateString = formatter.string(from: date)
print("date:", dateString)
}
This will print:
Monday, 21 September 2020 15:24:36 Brasilia Standard Time
date: 2020-09-21T18:24:36.787+0000
If you need to display a localized date to the user check this post
Two options for building and parsing ISO 8601/RFC 3339 date/time strings:
Use DateFormatter with no “styles”, but specify X for the timezone:
let formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSX"
return formatter
}()
Ironically, note the X rather than Z, to make sure that when you are building strings from dates, that the timezone is shown as Z rather +0000.
Use ISO8601DateFormatter:
let formatter: ISO8601DateFormatter = {
let formatter = ISO8601DateFormatter()
formatter.formatOptions.insert(.withFractionalSeconds)
return formatter
}()
The following function takes a dateString and returns the Date equivalent.
However, every time I run the function with any month, it will always return January.
func stringToDate(dateString: String) -> Date {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(identifier: "BST")
formatter.dateFormat = "yyyy/mm/dd hh:mm:ss"
guard let parsedDate = formatter.date(from: date) else {
return Date()
}
return parsedDate
}
stringToDate(date: "2020/11/13 12:42:00") // <-- Prints Jan 12, 2020 at 6:42 PM
stringToDate(date: "2020/07/29 09:41:00") // <-- Prints Jan 29, 2007 at 3:41 AM
How can we fix this to display the correct month?
In order to display the correct month, we have to change the mm from the .dateFormat property to MM
formatter.dateFormat = "yyyy/MM/dd hh:mm:ss"
// UPDATED FUNCTION
func stringToDate(dateString: String) -> Date {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(identifier: "BST")
formatter.dateFormat = "yyyy/mm/dd hh:mm:ss"
guard let parsedDate = formatter.date(from: date) else {
return Date()
}
return parsedDate
}
stringToDate(date: "2020/11/13 12:42:00") // <-- Prints Nov 12, 2020 at 6:42 PM
stringToDate(date: "2020/07/29 09:41:00") // <-- Prints Jul 29, 2007 at 4:41 AM
Check out https://nsdateformatter.com/ where you can play around the different date formats
According to the chart,
mm = two digits of minute
MM = two-digit month
Corrected Code :
formatter.dateFormat = "yyyy/MM/dd hh:mm:ss a" //for 12 hour format
or
formatter.dateFormat = "yyyy/MM/dd HH:mm:ss" // for 24 hour format
I want to get the only date in iOS and not time
my code is
extension Date{
var DateInDate: Date{
let formatter = DateFormatter()
formatter.setLocalizedDateFormatFromTemplate("yyyy-MM-dd")
formatter.locale = Locale(identifier: "en_IN")
let dateInString = formatter.string(from: self)
return formatter.date(from: dateInString)!
}
}
if I am doing by the above format I am getting the answer as "Apr 3, 2019 at 12: 00 AM"
my other code is
extension Date{
var DateInDate: String{
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .none
formatter.setLocalizedDateFormatFromTemplate("yyyy-MM-dd")
formatter.locale = Locale(identifier: "en_IN")
let dateInString = formatter.string(from: self)
}
}
but in this way, I am getting in string format and not a Date format
I want the answer in date format
As mentioned in the comments a Date instance without the time portion is impossible.
In terms of Date a timeless date is midnight, the start of the day.
There is an convenience API in Calendar:
let startOfDay = Calendar.current.startOfDay(for: Date())
You should use DateComponents instead. Date would always have the time.
Try this:
let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.timeStyle = DateFormatter.Style.none
dateFormatter.dateStyle = DateFormatter.Style.short
dateFormatter.string(from: date)
How can i achieve this kind of format?? using "NSDateFormatter"
March 1-2 2016?
Is there a format to get day only, Month only, Year only?
let dateString = self.dateLists[indexPath.row]
let dateFormatter2 = NSDateFormatter()
dateFormatter2.dateFormat = "MMMM"
let date2 = dateFormatter2.dateFromString(dateString as String)
You need the correct dateformat to get everything you want from an Datestring.
If your date is a string, you need to convert it first to an NSDate()
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd" // the format of your string
dateFormatter.timeZone = NSTimeZone(name: "GMT")
if let date = dateFormatter.dateFromString(dateString) {
// conversation to NSDate() was successful
// now convert to anything you want
dateFormatter.dateFormat = "MMMM"
let newDateString = dateFormatter.stringFromDate(date)
}
Here are all available Dateformatters, for example:
Month only (as text):
“MMMM”
Or as 2 digit String:
“MM”
Here is all you need:
http://www.codingexplorer.com/swiftly-getting-human-readable-date-nsdateformatter/
let str1 = "May 12 1968 04:00 PM"
let str2 = "May"
let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
dateFormatter.dateFormat = "MM"
let date1 = dateFormatter.dateFromString(str1) // nil
let date2 = dateFormatter.dateFromString(str2) // May 1, 2000, 12:00 AM
dateFormatter.dateFormat = "MM dd yyyy hh:mm a"
let date3 = dateFormatter.dateFromString(str1) // May 12, 1968, 04:00 PM
let date4 = dateFormatter.dateFromString(str2) // nil
check your input string ... it must conform to you format
check your locale, even though you define your custom format, the
system use the locale (gregorian vs julian calendar ... etc)
if it still doesn't work, parse you string 'manually'