How to display date with human language like "Today at xx:xx pm", "Yesterday at xx:xx am"? - ios

I have a date "2014-07-02 20:57:38 +0000" and I want to format it as "Today at 8:57 pm".
I want that if a string is yesterday, then display it as "Yesterday at 9:00 am". If it is neither today or yesterday, just show the actually date like "27/6 at 7:53 pm".
I was able to get the time with format like "8:57 AM" with the code below.
var formatter : NSDateFormatter = NSDateFormatter()
formatter.dateFormat = "h:mm a"
// message.createdAt is the date
let dateString = formatter.stringFromDate(message.createdAt)
println(dateString)
//output = 8:57 AM
However, when I use the following code, it returns a blank string.
var formatter : NSDateFormatter = NSDateFormatter()
formatter.dateFormat = "h:mm a"
formatter.doesRelativeDateFormatting = true //<-- This doesn't work
let dateString = formatter.stringFromDate(message.createdAt)
println(dateString)
//output = (nothing, its a blank string)
How do I make this work and display "Today" or "Yesterday" in Swift?

The reason it's blank is that your date format only has time components. Combined with .doesRelativeDateFormatting that gives you the empty string. If you want that custom time format, I think you need separate formatters for the date and the time:
let now = NSDate()
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .MediumStyle
dateFormatter.doesRelativeDateFormatting = true
let timeFormatter = NSDateFormatter()
timeFormatter.dateFormat = "h:mm a"
let time = "\(dateFormatter.stringFromDate(now)), \(timeFormatter.stringFromDate(now))"
println(time) // prints "Today, 5:10 PM"

With Swift 5.1, Apple Developer API Reference states about DateFormatter's dateFormat property:
You should only set this property when working with fixed format representations, as discussed in Working With Fixed Format Date Representations. For user-visible representations, you should use the dateStyle and timeStyle properties, or the setLocalizedDateFormatFromTemplate(_:) method if your desired format cannot be achieved using the predefined styles; both of these properties and this method provide a localized date representation appropriate for display to the user.
The following Playground sample code shows how to display your dates in the desired format using dateStyle, timeStyle and doesRelativeDateFormatting properties:
import Foundation
let now = Date() // 2019-08-09 12:25:12 +0000
let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: now)! // 2019-08-08 12:25:12 +0000
let aWeekAgo = Calendar.current.date(byAdding: .weekOfMonth, value: -1, to: now)! // 2019-08-02 12:25:12 +0000
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .short
dateFormatter.doesRelativeDateFormatting = true
let nowString = dateFormatter.string(from: now)
print(nowString) // prints: Today at 2:25 PM
let yesterdayString = dateFormatter.string(from: yesterday)
print(yesterdayString) // prints: Yesterday at 2:25 PM
let aWeekAgoString = dateFormatter.string(from: aWeekAgo)
print(aWeekAgoString) // prints: August 2, 2019 at 2:25 PM

Give this a try in Swift:
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short
dateFormatter.doesRelativeDateFormatting = true
let date = Date()
let dateString = dateFormatter.string(from:date)

Related

Not able to convert UTC time

I'm getting this UTC time in string format from the server.."2019-12-18T10:58:40Z"
Now I want to convert it into local time. For that I referred this link. But it's not working..
What I wanted to achieve was to convert UTC time to local time and set a timer based on that time.
This is what I've tried..
var utcTime = "\(json["expirationDate"]!)"
self.dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
let date = self.dateFormatter.date(from: utcTime)
let utcDate = date?.toGlobalTime()
let localDate = utcDate?.toLocalTime()
But I'm getting nil values for the dates..
You don't have milliseconds in your UTC date string example. Your date format should be
self.dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
you have to change this format from
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" to "yyyy-MM-dd'T'HH:mm:ss'Z'"**you have to
let utcTime = "2019-12-18T10:58:40Z"
let dateFormatter = DateFormatter.init()
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")!
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
let date = dateFormatter.date(from: utcTime)
print(date)

DateFormater error only when running on iOS 13

I have a function to convert string to date format. This function works as expected on iOS 12 but on iOS 13. I get this error:
"Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value"
Here is my code:
func ConvertDateAndTimeFormat2() {
let timeDate = "2019-09-24 15:00:00 +0000"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss +zzzz"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT+3:00")
var dateObj:Date!
dateObj = dateFormatter.date(from: timeDate)
dateFormatter.dateFormat = "EEEE, MMM d, yyyy"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT+3:00")
let timeFormatter = DateFormatter()
timeFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss +zzzz"
timeFormatter.timeZone = TimeZone(abbreviation: "GMT+3:00")
var timeObj:Date!
timeObj = timeFormatter.date(from: timeDate)
timeFormatter.dateFormat = "HH:mm"
timeFormatter.timeZone = TimeZone(abbreviation: "GMT+3:00")
let timef = "\(timeFormatter.string(from: timeObj!))"
let Date = "\(dateFormatter.string(from: dateObj!))"
}
Please change your dateformat and use "yyyy-MM-dd HH:mm:ss Z" and try.
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
For more details please visit https://nsdateformatter.com/
If you are trying to convert string time which in 24 hours format (Ex 15:25:00 / HH:mm:ss) then enable your device 24-Hour Time option. It might solve the issue in IOS 13.3
You may find the option here
Settings -> General -> Date & Time
There are many issues with your code. There is no reason to create two Date objects from one string. Just parse the original string once. Then you can create your date string and time string with the desired formats from that one date.
You should also use the special locale of en_US_POSIX when parsing fixed format date strings. There is also no need to set a timezone when parsing the original date string. The string provides its own timezone. The +0000 means it is UTC time.
You may not want to provide a timezone when converting the date to your final strings either. Most likely you want strings in the user's locale timezone, not some hardcoded timezone.
Here's your code cleaned up a lot:
func convertDateAndTimeFormat2() {
let timeDate = "2019-09-24 15:00:00 +0000"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
if let dateObj = dateFormatter.date(from: timeDate) {
dateFormatter.dateFormat = "EEEE, MMM d, yyyy"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT+3:00") // Probably not needed
let timeFormatter = DateFormatter()
timeFormatter.dateFormat = "HH:mm"
timeFormatter.timeZone = TimeZone(abbreviation: "GMT+3:00") // Probably not needed
let timef = timeFormatter.string(from: dateObj)
let datef = dateFormatter.string(from: dateObj)
print("Date: \(datef), time: \(timef)")
}
}
convertDateAndTimeFormat2()
Output:
Date: Tuesday, Sep 24, 2019, time: 18:00

How to get the day of the week from a date in Swift

I can print the date in this format: Mon, Mar 19, 2018, but I am not sure how to get the Day of the week in this format.
Please help
let dateFormatter = DateFormatter()
// uncomment to enforce the US locale
// dateFormatter.locale = Locale(identifier: "en-US")
dateFormatter.setLocalizedDateFormatFromTemplate("EEE MMM d yyyy")
print(dateFormatter.string(from: Date())) // "Tue, Mar 20, 2018" for en-US locale
Note that I am using a template to provide the exact format, therefore the format will be properly localized in every language.
To get the day for a particular date:
let customDateFormatter = DateFormatter()
print(customDateFormatter.weekdaySymbols[Calendar.current.component(.weekday, from: Date())])
// "Wednesday"
source
Rather than needing to spell out a date format. I would simplify it further to:
dateFormatter.dateStyle = .full
Or if you just want the day:
dateFormatter.dateFormat = "EEEE"
With swift 4
func timeStamp()->String {
let dateFormater = DateFormatter()
dateFormater.locale = Locale(identifier: "en-US")
dateFormater.setLocalizedDateFormatFromTemplate("EEE MMM d yyyy")
return dateFormatter.string(from: Date())
}
Use it.
let getTimeStamp = timeStamp()
print(getTimeStamp)
dateFormatter.dateFormat = "EEE, MMM dd, yyyy"
For dat of week in alphabets, you use EEEE or EEE similar to MMM & yyyy for month year.
The best way to change your date is follow this method.
func ChangeDateFormat(date:String,FromFormat: String, ToFormat: String) -> String {
let dateFormatter1 = DateFormatter()
dateFormatter1.dateFormat = FromFormat
let myDate = dateFormatter1.date(from: date)
dateFormatter1.dateFormat = ToFormat
if(myDate != nil){
let Date = dateFormatter1.string(from: myDate!)
return Date
}
else{
return ""
}
}
and then you can use this method like
String(ChangeDateFormat(date: StartDate, FromFormat: "yyyy-MM-dd hh:mm:ss a", ToFormat: "MMM d, yyyy"))
You can pass your date format in which format do you want in your case it should be
String(ChangeDateFormat(date: StartDate, FromFormat: "Pass your date format", ToFormat: "EEE MMM d, yyyy"))

How to extract today, yesterday from Date() and make it localised like weekday and months?

I want to extract today, yesterday from date so it is localised automatically when I change language like which happens with weekdays and month.
Code for localised date that I am using:
let dateFormatter = Foundation.DateFormatter()
dateFormatter.dateFormat = "MMMM dd, yyyy"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(identifier: "UTC")
let dateStr = dateFormatter.string(from: datePickerView.date)
let timeStr = "00:00:00.000"
let dateString = NSString(format:"%# %#",dateStr,timeStr)
let mainDF = Foundation.DateFormatter()
mainDF.dateFormat = "MMMM dd, yyyy hh:mm:ss.SSS"
mainDF.locale = Locale(identifier: "en_US_POSIX")
mainDF.timeZone = TimeZone(identifier: "UTC")
let date = mainDF.date(from: dateString as String)
How to achieve this?
DateFormatter has special flag for that: doesRelativeDateFormatting, which renders dates in relative format, using locale set for this formatter.
… If a date formatter uses relative date formatting, where possible it
replaces the date component of its output with a phrase—such as
“today” or “tomorrow”—that indicates a relative date. The available
phrases depend on the locale for the date formatter; whereas, for
dates in the future, English may only allow “tomorrow,” French may
allow “the day after the day after tomorrow,” …
Example:
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale.autoupdatingCurrent // Using system locale
dateFormatter.doesRelativeDateFormatting = true // Enabling relative date formatting
// other dataFormatter settings here, irrelevant for example
dateFormatter.timeStyle = .none
dateFormatter.dateStyle = .medium
let now = Date()
let dateString: String = dateFormatter.string(from: now)
print("dateString: \(dateString)") // Prints `dateString: <Today in current locale>`

how to convert english date to arabic date ios swift

in my app i am getting date in this format = "2016-02-15 10:49:59" bu i want to display it in this format "الأربعاء, 9 مارس, 2016 10:33 ص" so how can i do this?
i mage showing the format in which i want iot
You can make use of NSDateFormatter and locale "ar_DZ", with a custom format specification to fit your needs: "EEEE, d, MMMM, yyyy HH:mm a".
// input date in given format (as string)
let inputDateAsString = "2016-03-09 10:33:59"
// initialize formatter and set input date format
var formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
// read input date string as NSDate instance
if let date = formatter.dateFromString(inputDateAsString) {
// set locale to "ar_DZ" and format as per your specifications
formatter.locale = NSLocale(localeIdentifier: "ar_DZ")
formatter.dateFormat = "EEEE, d, MMMM, yyyy HH:mm a"
let outputDate = formatter.stringFromDate(date)
print(outputDate) // الأربعاء, 9 مارس, 2016 10:33 ص
}
Note that the above uses the default gregorian calendar (in so not translating e.g. year 2016 to year 1437 (/1438 ~October 2016) in the islamic calendar).
(Edit addition regarding your comment below)
If you change localeIdentifier above from "ar_DZ" to "ar", also numeric values gets written in arabic characters:
print(outputDate) // الأربعاء, ٩ مارس, ٢٠١٦ ١٠:٣٣ ص
However, I don't know arabic, so I can't really say if your image above displays that, and I'm no longer certain what you're trying to achieve; possibly this is not it.
Check this
let morningOfChristmasComponents = NSDateComponents()
morningOfChristmasComponents.year = 2014
morningOfChristmasComponents.month = 12
morningOfChristmasComponents.day = 25
morningOfChristmasComponents.hour = 7
morningOfChristmasComponents.minute = 0
morningOfChristmasComponents.second = 0
let morningOfChristmas = NSCalendar.currentCalendar().dateFromComponents(morningOfChristmasComponents)!
/***** NSDateFormatter Part *****/
let formatter = NSDateFormatter()
formatter.dateStyle = NSDateFormatterStyle.LongStyle
formatter.timeStyle = .MediumStyle
formatter.locale = NSLocale(localeIdentifier: "ar")
let dateString = formatter.stringFromDate(morningOfChristmas)
txtMarks.text = dateString
For solving of youre issue try to use legend way with NSCalendar style:
var today = NSDate()
let islamic = NSCalendar(identifier:NSCalendarIdentifierIslamicCivil)!
let formatter = NSDateFormatter()
formatter.dateStyle = .LongStyle
formatter.timeStyle = .MediumStyle
formatter.calendar = islamic
formatter.locale = NSLocale(localeIdentifier: "ar_DZ")
formatter.stringFromDate(today) // "30 جمادى الأولى، 1437 هـ، 11:22:10 ص"
To configure proper style set yore's dateStyle and timeStyle also set up youre NSLocale.

Resources