() is not convertible to String - swift

I'm trying to make a simple clock app and I'm running into an issue.
#IBAction func toggle(sender: UISwitch) {
func formatADate() {
var dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .ShortStyle
dateFormatter.dateFormat = "hh:mm:ss a"
let date = NSDate()
let output = dateFormatter.stringFromDate(date)
println(output)
}
let clockString: String = formatADate()
clockFace.hidden = false
clockFace.text = clockString
}
But I keep getting the error () is not convertible to String. Any idea why is this happening?

The formatADate function is declared as taking no parameters and returning void (i.e. nothing), whereas in this line
let clockString: String = formatADate()
you are assigning its return value (void) to a string.
You just have to declare that function as returning a string:
func formatADate() -> String {
var dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .ShortStyle
dateFormatter.dateFormat = "hh:mm:ss a"
let date = NSDate()
let output = dateFormatter.stringFromDate(date)
println(output)
return output
}
I'm making the assumption that output is what you want it to return - if not, change accordingly.

Your formatADate function should be defined as returning a String
func formatADate()-> String { // use -> to show returned type
var dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .ShortStyle
dateFormatter.dateFormat = "hh:mm:ss a"
let date = NSDate()
let output = dateFormatter.stringFromDate(date)
return output // return string type
}
let clockString: String = formatADate()

Related

DateFormater gives day before swift

when I use DateFormateer it returns me a day before.
nextDayShouldBe = currectDay.addingTimeInterval(24 * 3600)
print(nextDayShouldBe) //prints (2022-07-02 21:58:11 +0000) it's right
let nextDay = nextDayShouldBe?.getFormattedDate(format: format)
try? realm.write({
userData?.nextDay = nextDay
print(nextDayShouldBe?.getFormattedDate(format: format)) // prints "01/07/2022"
})
I tried all methods to fix it (dateformatter.locale, timeZone, calendar).
extension Date {
func getFormattedDate(format: String) -> String {
let dateformat = DateFormatter()
dateformat.dateFormat = format
dateformat.timeZone = TimeZone(secondsFromGMT: 10800)
dateformat.calendar = .current
dateformat.locale = Locale.autoupdatingCurrent
return dateformat.string(from: self)
}
}
How to get 2022-07-02 ??
okey, I did it and it works:
nextDayShouldBe = currectDay.addingTimeInterval(24 * 3600)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"
let fromDateToString = dateFormatter.string(from: nextDayShouldBe!)
print(fromDateToString)

How to format date string if the given date format changes

I'm getting a response from api that is date string, it's format changes sometimes so I need to format it dynamically,
Here's my code
import Foundation
func format(from: String?, fromFormat: String, to: String) -> String {
if from == nil { return "" }
let inputDateFormatter = DateFormatter()
inputDateFormatter.dateFormat = fromFormat
let date = inputDateFormatter.date(from: from ?? "")
let outputDateFormatter = DateFormatter()
outputDateFormatter.dateFormat = to
if let date = date {
return outputDateFormatter.string(from: date)
}
return "not formatted"
}
let strFromApi = "2020-12-22"
print(format(from: strFromApi, fromFormat: "yyyy-MM-dd", to: "d MMM yyyy"))
As you can see, I have a code there that can format successfully, the problem here is that strFromApi variable was came from api, and is changing between 2020-12-22 and 2020-12-22 00:00:00, when it changes to 2020-12-22 00:00:00, my current code can't format it anymore.
Question: How can I format it even the given format from the server has time?
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"

How to convert this string in a date with this format?

Im working with a API, when I ask for a date, this API get my a String like this:
20190717-0300
I want to show that date in a UILabel with this format: "dd '\(preposition)' MMMM"
My attempt was to make a string extension:
extension String {
var toDate: String? {
let dateFormatter = DateFormatter()
let preposition = NSLocalizedString("of", comment: "Preposition of dates formatted")
dateFormatter.dateFormat = "dd '\(preposition)' MMMM"
dateFormatter.locale = Locale.current
if let date = dateFormatter.date(from: self) {
let dateString = dateFormatter.string(from: date)
return dateString
}
return nil
}
}
And then use it:
myLabel.text = thatString.toDate
But .toDate always return nil
Note: The answers I found on the site are cases with ISO format strings.
Expected result:
17 of July
Basically you need an input date format and an output date format.
extension String {
var toDate: String? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMddZ"
if let date = dateFormatter.date(from: self) {
let preposition = NSLocalizedString("of", comment: "Preposition of dates formatted")
dateFormatter.dateFormat = "dd '\(preposition)' MMMM"
let dateString = dateFormatter.string(from: date)
return dateString
}
return nil
}
}
I totally agree with rmaddy's comment to use setLocalizedDateFormatFromTemplate
The source of the date field symbols is unicode.org: Date Format Patterns
Turn this into extension if you like:
// function
func formatDate(_ from:String, preposition:String) -> String? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMddZ"
guard let date = dateFormatter.date(from: from) else {
return nil
}
dateFormatter.dateFormat = "dd '\(preposition)' MMMM"
return dateFormatter.string(from: date)
}
// example usage
let str = "20190717-0300"
if let formatted = formatDate(str, preposition: "of") {
print(formatted)
}

Cannot convert value of type 'String' to expected argument type 'TimeInterval' (aka 'Double')

I am formatting time that is being passed in. I am getting this error, and I'm trying to figure out what's happening here with it. I'm using the most up to date version of Xcode (v. 8) and am programming in Swift 3. What this error means and how to fix it?
I'm piecing in parts of the code that are relevant to the question so it's not a overload of information here.
var date: String {
if _date == nil {
_date = ""
}
return _date
}
init(weatherDict: Dictionary<String, AnyObject>){
if let temp = weatherDict["temp"] as? Dictionary<String, AnyObject>
{
if let min = temp["min"] as? Double{
self._lowTemp = ktof(kelvins: min)
}
if let max = temp["max"] as? Double{
self._highTemp = ktof(kelvins: max)
}
}
let unixConvertedDate = Date(timeIntervalSince1970: date)
if let date = weatherDict["dt"] as? Double {
let unixConvertedDate = Date(timeIntervalSince1970: date)
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .full
//dateFormatter.dateFormat = "EEEE"
dateFormatter.dateStyle = .none
self._date = unixConvertedDate.dayoftheWeek()
}
}
and then outside of the class, which all the above code is inside of, I have this.
extension Date {
func dayoftheWeek() -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE"
return dateFormatter.string(from: self)
}
}
if let date = weatherDict["dt"] as? Double {
let unixConvertedDate = Date(timeIntervalSince1970: date)
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .full
dateFormatter.dateFormat = "EEEE"
dateFormatter.timeStyle = .long
self._date = "\(unixConvertedDate)"
}
}
}
extension Date {
func dayOfTheWeek() -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE"
return dateFormatter.string(from: self)
}
}

Check the date format of string if it's according to required format or not

I have the same question asked here in Java,
is it possible in swift?
func stringToDate(str: String) -> Date{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"
//check validation of str
return date
}
Just same like Java, check if it can parse properly
let dateFormatterGet = DateFormatter()
dateFormatterGet.dateFormat = "yyyy-MM-dd hh:mm:ss"
let someDate = "string date"
if dateFormatterGet.date(from: someDate) != nil {
// valid format
} else {
// invalid format
}
For Swift 4 the syntax have changed a bit:
func isValidDate(dateString: String) -> Bool {
let dateFormatterGet = DateFormatter()
dateFormatterGet.dateFormat = "yyyy-MM-dd hh:mm:ss"
if let _ = dateFormatterGet.date(from: dateString) {
//date parsing succeeded, if you need to do additional logic, replace _ with some variable name i.e date
return true
} else {
// Invalid date
return false
}
}
in swift3 :
func stringToDate(str: String) -> Date{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"
guard let date = dateFormatter.date(from: str){
return Date()
}
return date
}
Swift 5
let dateFormatterGet = DateFormatter()
dateFormatterGet.dateFormat = "yyyy-MM-dd hh:mm:ss"
let someDate = "string date"
if dateFormatterGet.date(from: someDate!) != nil {
} else {
// invalid format
}