Swift Date Formatting returning Nil - swift

I'm trying to set a label to a formatted date string on Sign Out press.
let dateFormatterUK = DateFormatter()
let dateString : String = String(describing: Date())
dateFormatterUK.dateFormat = "dd-MM-yyyy"
let currentDateTime = dateFormatterUK.date(from: dateString)
Above is my code formatting the Date. When I set my label to the currentDateTime variable however, it is set as Nil.

Try this one:
let dateFormatterUK = DateFormatter()
dateFormatterUK.dateFormat = "dd-MM-yyyy"
let currentDateTime = dateFormatterUK.string(from: Date())
And If your date is in String and want to change format:
let dateFormatterUK = DateFormatter()
dateFormatterUK.dateFormat = "dd-MM-yyyy"
let stringDate = "11-03-2018"
let date = dateFormatterUK.date(from: stringDate)!
// set new format
dateFormatterUK.dateFormat = "yyyy-MM-dd"
let currentDateTime = dateFormatterUK.string(from: date)

Related

Creating Date object from timestamp in Swift [duplicate]

I get a crash when running and it points at the dateFormmater.timezone.
The error in the console is:
Could not cast value of type 'Swift.Optional' (0x1192bf4a8) to 'NSTimeZone' (0x1192c0270).
the value of rowEvents.date is "1480134638.0"
Im trying to pull out a Unix timestamp from Firebase saved as a string. Convert it to Date and again save it as a string so I can post it on a cell label.
I got this code from StackOverflow. I plugged in my data and everything is all good until I run it. I guess everything is not all good...
if let lastUpdated : String = rowEvents.date {
let epocTime = TimeInterval(lastUpdated)! / 1000 // convert it from milliseconds dividing it by 1000
let unixTimestamp = NSDate(timeIntervalSince1970: epocTime) //convert unix timestamp to Date
let dateFormatter = DateFormatter()
dateFormatter.timeZone = NSTimeZone() as TimeZone!
dateFormatter.locale = NSLocale.current // NSLocale(localeIdentifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
dateFormatter.date(from: String(describing: unixTimestamp))
let updatedTimeStamp = unixTimestamp
let cellDate = DateFormatter.localizedString(from: updatedTimeStamp as Date, dateStyle: DateFormatter.Style.full, timeStyle: DateFormatter.Style.medium)
cell.subtitleLabel.text = cellDate
}
The result came from this code here:
let myTimeStamp = self.datePicker?.date.timeIntervalSince1970
let calendarDate = String(describing: myTimeStamp! /** 1000*/)
You can convert unixTimestamp to date using Date(timeIntervalSince1970:).
let unixTimestamp = 1480134638.0
let date = Date(timeIntervalSince1970: unixTimestamp)
If you want to display date in string with specific formate than you can use DateFormatter like this way.
let date = Date(timeIntervalSince1970: unixtimeInterval)
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(abbreviation: "GMT") //Set timezone that you want
dateFormatter.locale = NSLocale.current
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm" //Specify your format that you want
let strDate = dateFormatter.string(from: date)
The problem is the line dateFormatter.timeZone = NSTimeZone() as TimeZone!.
Simply use TimeZone instead of NSTimeZone like
dateFormatter.timeZone = TimeZone.current and your code will work.
You might also remove your / 1000 because 1480134638.0 looks more like seconds than milliseconds (since 1970).
Swift 4.1. I created a function. Just pass you timeStamp in function param and function will return data in string data type. You can add more properties to DateFormatter object.
func getDateFromTimeStamp(timeStamp : Double) -> String {
let date = NSDate(timeIntervalSince1970: timeStamp / 1000)
let dayTimePeriodFormatter = DateFormatter()
dayTimePeriodFormatter.dateFormat = "dd MMM YY, hh:mm a"
// UnComment below to get only time
// dayTimePeriodFormatter.dateFormat = "hh:mm a"
let dateString = dayTimePeriodFormatter.string(from: date as Date)
return dateString
}
Using playground all I did was this.
let epochTime = 1547855446
let newTime = Date(timeIntervalSince1970: TimeInterval(epochTime))
print(newTime)
Returns this - 2019-01-18 23:50:46 +0000
extension Double{
func convertDate(formate: String) -> String {
let date = (timeIntervalSince1970: self)
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone.current
dateFormatter.locale = NSLocale(localeIdentifier: "(your localization language)" ) as Locale //localization language
dateFormatter.dateFormat = formate //Specify your format that you want let
strDate = dateFormatter.string(from: date)
return strDate
}
}
//usage
let timeStamp:Double = Double(1595407043)
print(timeStamp.convertDate(formate: "EEEE dd/MM/YYY"))
This solution is valid for swift 3 -> 4.2 :
you can add an extension on the Double that returns the date formatted:
extension Double {
// returns the date formatted.
var dateFormatted : String? {
let date = Date(timeIntervalSince1970: self)
let dateFormatter = DateFormatter()
dateFormatter.timeStyle = DateFormatter.Style.none //Set time style
dateFormatter.dateStyle = DateFormatter.Style.short //Set date style
return dateFormatter.string(from: date)
}
// returns the date formatted according to the format string provided.
func dateFormatted(withFormat format : String) -> String{
let date = Date(timeIntervalSince1970: self)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
return dateFormatter.string(from: date)
}
}
example on the above :
let timeStamp = 82749029.0
print(timeStamp. dateFormatted)
//output
//12/11/1994
let timeStamp = 82749029.0
print(timeStamp. dateFormatted(withFormat : "MM-dd-yyyy HH:mm"))
//output
//12-11-1994 13:04

Trying to get the current time but it gives me the wrong time SWIFT 5

I'm trying to get the current date. Current Date and time is 2019-12-16 05:12:59 but I get 2019-12-16 10:12:59.
let dateAdded = itemDict["time"] as! String
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd hh:mm:ss"
let currentTime = df.date(from: dateAdded)
let dateTime = currentTime!.addingTimeInterval(60.0 * 60.0)
let currentDate = Date()
Try this:
Date().toCurrentTimezone()
extension Date {
func toCurrentTimezone() -> Date {
let timeZoneDifference =
TimeInterval(TimeZone.current.secondsFromGMT())
return self.addingTimeInterval(timeZoneDifference)
}
}
To get the current time without a format you can simply just add this:
let currentDateTime = Date()
print(currentDateTime)
But if you would like to retrieve a "string" and convert it into a date you can do:
let dateAdded = itemDict["time"] as! String
//Convert string to date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
let date = dateFormatter.date(from: dateAdded!)
If you're still getting wrong time, you should add timezone. In that case the code will be something like this:
let dateAdded = itemDict["time"] as! String
//Convert string to date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let date = dateFormatter.date(from: dateAdded!)
If you're using uppercase "HH" that means you're using the 24h clock. Otherwise use small case "hh".
You need to set your local time zone in date formator.
//Get local time Zone
var localTimeZoneIdentifier: String { return TimeZone.current.identifier }
print("local Time zone: " + localTimeZoneIdentifier)
let inputdateString: String = "2019-12-16 05:12:59"
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: localTimeZoneIdentifier)
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
let inputDate = dateFormatter.date(from: inputdateString )!
print("Output date: \(String(describing: inputDate))")
out put:-
local Time zone:-Asia/Kolkata
Output date: 2019-12-15 23:42:59 +0000

How to extract date and time from standard datetime format?

I am getting a string from API containing date and time as:
createdAt = "2019-08-12T10:34:05.000Z"
I need to extract date from this string and time also.
And how can I get difference as time between two given date strings?
e.g. If I have two strings as:
StartedOn = "2019-08-12T10:32:18.000Z"
StopedOn = "2019-08-12T10:34:05.000Z".
How to get time from start to stop.
swift 4, Xcode 10
Use DateFormatter to get the Date instance from the String, i.e.
let str = "2019-08-12T10:34:05.000Z"
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let date = formatter.date(from: str)
Now, to get the time difference use timeIntervalSince(_:) with the 2 Date objects, i.e.
let startedOn = "2019-08-12T10:32:18.000Z"
let stoppedOn = "2019-08-12T10:34:05.000Z"
if let startedOnDate = formatter.date(from: startedOn), let stoppedOnDate = formatter.date(from: stoppedOn) {
let timeInterval = stoppedOnDate.timeIntervalSince(startedOnDate)
print(timeInterval)
}
In case you need more detailed components between 2 Date objects, use Calendar object like so,
if let startedOnDate = formatter.date(from: startedOn), let stoppedOnDate = formatter.date(from: stoppedOn) {
let calendar = Calendar(identifier: .gregorian)
let components = calendar.dateComponents([.hour, .minute, .second], from: startedOnDate, to: stoppedOnDate)
print(components) //hour: 0 minute: 1 second: 47
}
Edit:
To get the date and time separately from Date object,
let str = "2019-08-12T10:34:05.000Z"
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
if let date = formatter.date(from: str) {
formatter.dateFormat = "hh:mm:ss a"
let timeStr = formatter.string(from: date)
print(timeStr) //add timeStr to your timeLabel here...
formatter.dateFormat = "yyyy-MM-dd"
let dateStr = formatter.string(from: date)
print(dateStr) //add dateStr to your dateLabel here...
}
Try with this :D
import datetime
StartedOn = "2019-08-12T10:32:18.000Z"
StopedOn = "2019-08-12T10:34:05.000Z"
StartedOn = datetime.datetime.fromisoformat(StartedOn[:-1])
StoppedOn = datetime.datetime.fromisoformat(StopedOn[:-1])
print(StoppedOn - StartedOn)
There are two dedicated date formatters for that purpose, ISO8601DateFormatter to convert the ISO8601 string to Date
let isoFormatter = ISO8601DateFormatter()
isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let createdAtDate = isoFormatter.date(from: "2019-08-12T10:34:05.000Z")
let startedOn = "2019-08-12T10:32:18.000Z"
let stopedOn = "2019-08-12T10:34:05.000Z"
let startedOnDate = isoFormatter.date(from: startedOn)!
let stopedOnDate = isoFormatter.date(from: stopedOn)!
and DateComponentsFormatter to get a m:ss string from the difference between start and end date
let componentsFormatter = DateComponentsFormatter()
componentsFormatter.allowedUnits = [.minute, .second]
let duration = componentsFormatter.string(from: startedOnDate, to: stopedOnDate)

Parsing a Swift String to Date, then Components

I have a date "2017-12-31" as a String.
What I want to get finally is only the month: "12" as a String.
So I thought that I can change it to Date using a date formatter
let formatter = DateFormatter()
formatter.dateFormat = "MM"
What do I do next?
let dateString = "2017-12-31"
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: Calendar.Identifier.iso8601) formatter.timeZone = TimeZone(identifier: TimeZone.autoupdatingCurrent.identifier)
formatter.dateFormat = "yyyy-MM-dd"
let localDate = formatter.date(from: dateString)
formatter.dateFormat = "MM"
let strMonth = formatter.string(from: localDate!)
print("Month is:",strMonth)
Another way
let dateString = "2017-12-31"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
let localDate = formatter.date(from: dateString)
let month = String(NSCalendar.current.component(.month, from: localDate!))
print(month)
First you have to use the DateFormatter to create a temporary Date object from your source String object. Then you have to use it to create your final String from the temporary Date object.
let dateString = "2017-12-31"
let dateFormatter = DateFormatter()
// set the dateFormatter's dateFormat to the dateString's format
dateFormatter.dateFormat = "yyyy-MM-dd"
// create date object
guard let tempDate = dateFormatter.date(from: dateString) else {
fatalError("wrong dateFormat")
}
// set the dateFormatter's dateFormat to the output format you wish to receive
dateFormatter.dateFormat = "LL" // LL is the stand-alone month
let month = dateFormatter.string(from: tempDate)
Use below function for getting month from string file of date
func getMonthFromDateString(strDate: String) -> String {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
let date = formatter.date(from: strDate) // Convert String File To Date
formatter.dateFormat = "MM"
let strMM = formatter.string(from: date!) // Convert date to string
return strMM
}

Convert long month name to int

I understand how to use an NSDateFormatter to convert a month component into a long name string, but how does one convert a month name to an int?
I've been using a switch statement to convert, but I'm thinking there must be a simpler way.
For example, I'd like to convert "May" to 5.
You can use DateFormatter custom format "LLLL" to parse your date string (Month). If you are only parsing dates in english you should set the date formatter locale to "en_US_POSIX":
let df = DateFormatter()
df.locale = Locale(identifier: "en_US_POSIX")
df.dateFormat = "LLLL" // if you need 3 letter month just use "LLL"
if let date = df.date(from: "May") {
let month = Calendar.current.component(.month, from: date)
print(month) // 5
}
Thanks Josh. I've converted the Obj-C code and posted it below for future reference:
let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
let components = NSDateComponents()
let formatter = NSDateFormatter()
formatter.dateFormat = "MMMM"
let aDate = formatter.dateFromString("May")
let components1 = calendar!.components(.CalendarUnitMonth , fromDate: aDate!)
let monthInt = components.month
Use MM for the month format. Use stringFromDate to convert your NSDate to a String. Then convert your string to an Int with .toInt()
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM"
let monthString = dateFormatter.stringFromDate(NSDate()) // "05"
let monthInt = monthString.toInt() // 5
NSDateFormatter has monthSymbols property. Try:
let formatter = NSDateFormatter()
formatter.calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
let monthString = "September"
let month = find(formatter.monthSymbols as! [String], monthString).map { $0 + 1 }
// -> Optional(9)
let monthString2 = "Foobar"
let month2 = find(formatter.monthSymbols as! [String], monthString2).map { $0 + 1 }
// -> nil