Getting wrong time from dateformatter [duplicate] - ios

This question already has answers here:
Dateformatter gives wrong time on conversation [duplicate]
(4 answers)
Closed 5 years ago.
I'm converting date fields from a XML file and these dates are stored in "yyyyMMddHHmmss" format. When I use date function of DateFormmater, I'm not getting the correct time. So for dateString "20150909093700", it returns "2015-09-09 13:37:00 UTC" instead of "2015-09-09 09:37:00". I'm doing this conversion before storing inside Core Data NSDate fields.
This is my code :
static func stringToDate(DateString dateString: String) -> NSDate? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMddHHmmss"
dateFormatter.locale = Locale.init(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(abbreviation: "EST")
if let date = dateFormatter.date(from: dateString) {
return date as NSDate?
}
return nil
}

#user30646 -- see if this makes sense. Using your exact function:
func stringToDate(DateString dateString: String) -> NSDate? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMddHHmmss"
dateFormatter.locale = Locale.init(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(abbreviation: "EST")
if let date = dateFormatter.date(from: dateString) {
return date as NSDate?
}
return nil
}
let dateString = "20150909093700"
let returnedDate = stringToDate(DateString: dateString)
print("Date without formatting or Time Zone: [", returnedDate ?? "return was nil", "]")
let dFormatter = DateFormatter()
dFormatter.timeZone = TimeZone(abbreviation: "EST")
dFormatter.dateStyle = .full
dFormatter.timeStyle = .full
print("Result with formatting and Time Zone: [", dFormatter.string(from: returnedDate as! Date), "]")
You are getting the "correct time" ... you just think you're not because you're looking at the wrong string representation of that date/time.

Related

Convert Date from one format to another

I trying to convert date from one format to another. But the date in the below code is coming as nil. Can you guys help me out below is the code.
func eventTimeDate() -> Date {
let dtf = DateFormatter()
dtf.timeZone = TimeZone.current
dtf.dateFormat = "yyyy-MM-dd HH:mm:ss z"
/// "2020-05-28 00:20:00 GMT+5:30"
let stringDate = dtf.string(from: self)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy/MM/dd HH:mm:ss z"
/// nil
let date = dateFormatter.date(from: stringDate)
return date!
}
If you need to convert from one formatted date string to another formatted date string, you can use two DateFormatters: one - an input formatter to convert a String to an intermediary Date object, and then - using an output formatter - convert from Date to String.
func reFormat(from dateStr: String) -> String? {
let fromFormatter = DateFormatter()
fromFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss z"
let toFormatter = DateFormatter()
toFormatter.dateFormat = "yyyy/MM/dd HH:mm:ss z"
guard let date = fromFormatter.date(from: dateStr) else { return nil }
return toFormatter.string(from: date)
}
If you just need to return a Date object, then it's a simpler function using just one DateFormatter:
func toDate(from dateStr: String) -> Date? {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss z"
return formatter.date(from: dateStr)
}
Date object itself has no formatting - it's a pure representation of a date & time, which you can convert to/from using different formatters.
A swift class Date has no format.
In your code your stringDate is in "yyyy-MM-dd HH:mm:ss z" format. If you need to convert String to Date you must use the same format otherwise it will return nil.
If you want to change a format of a string then first convert it to a Swift 'Date' then again convert it to a string with the use of new Formatter.
func eventTimeDate(dateString : String, currentFormat : String, newFormat : String) -> String? {
let currentDateFormatter = DateFormatter()
currentDateFormatter.calendar = Calendar(identifier: Calendar.Identifier.gregorian)
currentDateFormatter.locale = Locale(identifier: "en_IN")
currentDateFormatter.dateFormat = currentFormat
let date = currentDateFormatter.date(from: dateString)
let newDateFormatter = DateFormatter()
newDateFormatter.calendar = Calendar(identifier: Calendar.Identifier.gregorian)
newDateFormatter.locale = Locale(identifier: "en_IN")
newDateFormatter.dateFormat = newFormat
if let date = date {
let newDateString = newDateFormatter.string(from: date)
return newDateString
}
return nil
}
You have three problems in your code. First when parsing a fixed date format you should always set the date formatter's locale to "en_US_POSIX". Second you need to escape the GMT of your date string. Last but not least important you need to fix your timezone string which it is missing the leading zero for your timezone hour:
let dateStr = "2020-05-28 00:20:00 GMT+5:30"
let formatter = DateFormatter()
// set the date formatter's locale to "en_US_POSIX"
formatter.locale = .init(identifier: "en_US_POSIX")
// escape the GMT of your date string
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss 'GMT'Z"
// add the leading zero for your timezone hour
let string = dateStr.replacingOccurrences(of: "(GMT[+-])(\\d:)", with: "$10$2", options: .regularExpression)
if let date = formatter.date(from: string) {
print(date) // "2020-05-27 18:50:00 +0000\n"
}

swift 5 - String to Date conversion results in nil [duplicate]

This question already has an answer here:
DateFormatter doesn't return date for "HH:mm:ss"
(1 answer)
Closed 2 years ago.
Has something changed in Swift 5.x? Not sure what I'm doing wrong here.
extension String {
var dateValue: Date? {
let dateAsString = "13:15"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
let date = dateFormatter.date(from: dateAsString) //date is being nil here
let Date24 = dateFormatter.string(from: date!)
print("24 hour formatted Date:",Date24)
return date
}
}
Change your code to :
let dateAsString = "13:15"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT+00:00")//Add this
let date = dateFormatter.date(from: dateAsString)
print(date!)
My result is :
2000-01-01 13:15:00 +0000
Hope it helps...

Convert string to DATE type in swift 3 [duplicate]

This question already has answers here:
Dateformatter to get Date From String
(4 answers)
Closed 4 years ago.
I have this structure:
struct message {
var id: String = "0"
var text: String = ""
var date: Date!
var status: String = ""
}
I have to load this structure from dbase, that it export in String format also date.
So I write this code to convert String to Date type:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = NSTimeZone(abbreviation: "UTC") as TimeZone!
let dataDate = dateFormatter.date(from: elemMessage["date"] as! String)!
And I load it in structure:
message(id: elemMessage["id"] as! String, text: elemMessage["text"] as! String, date: dataDate as! Date, status: elemMessage["status"] as! String)
But I have this warning: "Cast from Date to unrelated type Date always fails"
So if I run app it will fails.
How Can I fix this, the date var in structure have to be Date type.
Thank you.
You can convert String Date into Date/NSDate like below code: -
Swift 3.2 & Swift 4.2
String to Date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy" //Your date format
dateFormatter.timeZone = TimeZone(abbreviation: "GMT+0:00") //Current time zone
//according to date format your date string
guard let date = dateFormatter.date(from: "01-01-2017") else {
fatalError()
}
print(date) //Convert String to Date
Date to String
dateFormatter.dateFormat = "MMM d, yyyy" //Your New Date format as per requirement change it own
let newDate = dateFormatter.string(from: date) //pass Date here
print(newDate) //New formatted Date string
Output: -
2017-01-11 00:07:00 +0000
Jan 11, 2017
Swift 4 ISO
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone.autoupdatingCurrent
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
func getDateFromString(dateStr: String) -> (date: Date?,conversion: Bool)
{
let calendar = Calendar(identifier: Calendar.Identifier.gregorian)
let dateComponentArray = dateStr.components(separatedBy: "/")
if dateComponentArray.count == 3 {
var components = DateComponents()
components.year = Int(dateComponentArray[2])
components.month = Int(dateComponentArray[1])
components.day = Int(dateComponentArray[0])
components.timeZone = TimeZone(abbreviation: "GMT+0:00")
guard let date = calendar.date(from: components) else {
return (nil , false)
}
return (date,true)
} else {
return (nil,false)
}
}
//Input: "23/02/2017"
//Output: (2017-02-23 18:30:00 +0000, true)

Date in Swift 3 conversion

I want this date "2016-10-18 22:06:20 +0000" to "18-10-2016", is this possible? I managed to get the date as follows:
var formatter = DateFormatter()
formatter.dateFormat = "yyy-MM-dd'HH:mm:ss.SSSZ"
let stringDate = formatter.string(from: currentDate)
The above gives me "10/18/16", but how can I get "18-10-2016"?
Solution in Swift 3
extension Foundation.Date {
func dashedStringFromDate() -> String {
let dateFormatter = DateFormatter()
let date = self
dateFormatter.dateFormat = "dd-MM-yyyy"
return dateFormatter.string(from: date)
}
}
Example
let date = Foundation.Date()
let formatedDate = date.dashedStringFromDate()
Little about what you put in your question makes a lot of sense. You don't have a date as 2016-10-18 22:06:20 +0000. The code you posted converts a current Date into a string. But you claim you want that string to be in the format 18-10-2016 but your code uses a completely different format.
Why not just do:
var formatter = DateFormatter()
formatter.dateFormat = "dd-MM-yyyy"
let stringDate = formatter.string(from: currentDate)
This will convert the currentDate to a string in the format you mention in your question.
If you really have a string in the format of 2016-10-18 22:06:20 +0000 and you want to convert it to 18-10-2016, then you want two date formatters.
The first convert that original string to a date:
let string = "2016-10-18 22:06:20 +0000"
let formatter1 = DateFormatter()
formatter1.locale = Locale(identifier: "en_US_POSIX") // if this string was from web service or a database, you should set the locale
formatter1.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
guard let date = formatter1.date(from: string) else {
fatalError("Couldn't parse original date string")
}
If you then want to build a new string in the format of 18-10-2016, then you'd use a second formatter:
let formatter2 = DateFormatter()
formatter2.dateFormat = "dd-MM-yyyy"
let result = formatter2.string(from: date)

How can I convert string date to NSDate?

I want to convert "2014-07-15 06:55:14.198000+00:00" this string date to NSDate in Swift.
try this:
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = /* find out and place date format from
* http://userguide.icu-project.org/formatparse/datetime
*/
let date = dateFormatter.dateFromString(/* your_date_string */)
For further query, check NSDateFormatter and DateFormatter classes of Foundation framework for Objective-C and Swift, respectively.
Swift 3 and later
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = /* date_format_you_want_in_string from
* http://userguide.icu-project.org/formatparse/datetime
*/
guard let date = dateFormatter.date(from: /* your_date_string */) else {
fatalError("ERROR: Date conversion failed due to mismatched format.")
}
// use date constant here
Edit:
Alternative date time format reference
https://unicode-org.github.io/icu/userguide/format_parse/datetime/
Swift 4
import Foundation
let dateString = "2014-07-15" // change to your date format
var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let date = dateFormatter.date(from: dateString)
println(date)
Swift 3
import Foundation
var dateString = "2014-07-15" // change to your date format
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
var date = dateFormatter.dateFromString(dateString)
println(date)
I can do it with this code.
func convertDateFormatter(date: String) -> String
{
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"//this your string date format
dateFormatter.timeZone = NSTimeZone(name: "UTC")
let date = dateFormatter.dateFromString(date)
dateFormatter.dateFormat = "yyyy MMM EEEE HH:mm"///this is what you want to convert format
dateFormatter.timeZone = NSTimeZone(name: "UTC")
let timeStamp = dateFormatter.stringFromDate(date!)
return timeStamp
}
Updated for Swift 3.
func convertDateFormatter(date: String) -> String
{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"//this your string date format
dateFormatter.timeZone = NSTimeZone(name: "UTC") as TimeZone!
let date = dateFormatter.date(from: date)
dateFormatter.dateFormat = "yyyy MMM EEEE HH:mm"///this is what you want to convert format
dateFormatter.timeZone = NSTimeZone(name: "UTC") as TimeZone!
let timeStamp = dateFormatter.string(from: date!)
return timeStamp
}
Details
Swift 4, Xcode 9.2
Swift 5, Xcode 10.2 (10E125)
Solution
import Foundation
extension DateFormatter {
convenience init (format: String) {
self.init()
dateFormat = format
locale = Locale.current
}
}
extension String {
func toDate (dateFormatter: DateFormatter) -> Date? {
return dateFormatter.date(from: self)
}
func toDateString (dateFormatter: DateFormatter, outputFormat: String) -> String? {
guard let date = toDate(dateFormatter: dateFormatter) else { return nil }
return DateFormatter(format: outputFormat).string(from: date)
}
}
extension Date {
func toString (dateFormatter: DateFormatter) -> String? {
return dateFormatter.string(from: self)
}
}
Usage
var dateString = "14.01.2017T14:54:00"
let dateFormatter = DateFormatter(format: "dd.MM.yyyy'T'HH:mm:ss")
let date = Date()
print("original String with date: \(dateString)")
print("date String() to Date(): \(dateString.toDate(dateFormatter: dateFormatter)!)")
print("date String() to formated date String(): \(dateString.toDateString(dateFormatter: dateFormatter, outputFormat: "dd MMMM")!)")
let dateFormatter2 = DateFormatter(format: "dd MMM HH:mm")
print("format Date(): \(date.toString(dateFormatter: dateFormatter2)!)")
Result
More information
About date format
If you're going to need to parse the string into a date often, you may want to move the functionality into an extension. I created a sharedCode.swift file and put my extensions there:
extension String
{
func toDateTime() -> NSDate
{
//Create Date Formatter
let dateFormatter = NSDateFormatter()
//Specify Format of String to Parse
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss.SSSSxxx"
//Parse into NSDate
let dateFromString : NSDate = dateFormatter.dateFromString(self)!
//Return Parsed Date
return dateFromString
}
}
Then if you want to convert your string into a NSDate you can just write something like:
var myDate = myDateString.toDateTime()
For Swift 3
func stringToDate(_ str: String)->Date{
let formatter = DateFormatter()
formatter.dateFormat="yyyy-MM-dd hh:mm:ss Z"
return formatter.date(from: str)!
}
func dateToString(_ str: Date)->String{
var dateFormatter = DateFormatter()
dateFormatter.timeStyle=DateFormatter.Style.short
return dateFormatter.string(from: str)
}
The code fragments on this QA page are "upside down"...
The first thing Apple mentions is that you cache your formatter...
Link to Apple doco stating exactly how to do this:
Cache Formatters for Efficiency
Creating a date formatter is not a cheap operation. ...cache a single instance...
Use a global...
let df : DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
Then simply use that formatter anywhere...
let s = df.string(from: someDate)
or
let d = df.date(from: someString)
Or use any of the other many, many convenient methods on DateFormatter.
It is that simple.
(If you write an extension on String, your code is completely "upside down" - you can't use any dateFormatter calls!)
Note that usually you will have a few of those globals .. such as "formatForClient" "formatForPubNub" "formatForDisplayOnInvoiceScreen" .. etc.
Swift support extensions, with extension you can add a new functionality to an existing class, structure, enumeration, or protocol type.
You can add a new init function to NSDate object by extenging the object using the extension keyword.
extension NSDate
{
convenience
init(dateString:String) {
let dateStringFormatter = NSDateFormatter()
dateStringFormatter.dateFormat = "yyyyMMdd"
dateStringFormatter.locale = NSLocale(localeIdentifier: "fr_CH_POSIX")
let d = dateStringFormatter.dateFromString(dateString)!
self.init(timeInterval:0, sinceDate:d)
}
}
Now you can init a NSDate object using:
let myDateObject = NSDate(dateString:"2010-12-15 06:00:00")
Since Swift 3, many of the NS prefixes have been dropped.
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
/* date format string rules
* http://userguide.icu-project.org/formatparse/datetime
*/
let date = dateFormatter.date(from: dateString)
Swift 3,4:
2 useful conversions:
string(from: Date) // to convert from Date to a String
date(from: String) // to convert from String to Date
Usage:
1.
let date = Date() //gives today's date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd.MM.yyyy"
let todaysDateInUKFormat = dateFormatter.string(from: date)
2.
let someDateInString = "23.06.2017"
var getDateFromString = dateFormatter.date(from: someDateInString)
FOR SWIFT 3.1
func convertDateStringToDate(longDate: String) -> String{
/* INPUT: longDate = "2017-01-27T05:00:00.000Z"
* OUTPUT: "1/26/17"
* date_format_you_want_in_string from
* http://userguide.icu-project.org/formatparse/datetime
*/
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let date = dateFormatter.date(from: longDate)
if date != nil {
let formatter = DateFormatter()
formatter.dateStyle = .short
let dateShort = formatter.string(from: date!)
return dateShort
} else {
return longDate
}
}
NOTE: THIS WILL RETURN THE ORIGINAL STRING IF ERROR
To add String within Date Format in Swift, I did this
var dataFormatter:NSDateFormatter = NSDateFormatter()
dataFormatter.dateFormat = "dd-MMMM 'at' HH:mm a"
cell.timeStamplbl.text = dataFormatter.stringFromDate(object.createdAt)
This work for me..
import Foundation
import UIKit
//dateString = "01/07/2017"
private func parseDate(_ dateStr: String) -> String {
let simpleDateFormat = DateFormatter()
simpleDateFormat.dateFormat = "dd/MM/yyyy" //format our date String
let dateFormat = DateFormatter()
dateFormat.dateFormat = "dd 'de' MMMM 'de' yyyy" //format return
let date = simpleDateFormat.date(from: dateStr)
return dateFormat.string(from: date!)
}
You can try this swift code
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"//same as strDate date formator
dateFormatter.timeZone = TimeZone(abbreviation: "GMT+0:00")//Must used if you get one day less in conversion
let convertedDateObject = dateFormatter.date(from: strDate)
Below are some string to date format converting options can be usedin swift iOS.
Thursday, Dec 27, 2018 format= EEEE, MMM d, yyyy
12/27/2018 format= MM/dd/yyyy
12-27-2018 09:59 format= MM-dd-yyyy HH:mm
Dec 27, 9:59 AM format= MMM d, h:mm a
December 2018 format= MMMM yyyy
Dec 27, 2018 format= MMM d, yyyy
Thu, 27 Dec 2018 09:59:19 +0000 format= E, d MMM yyyy HH:mm:ss Z
2018-12-27T09:59:19+0000 format= yyyy-MM-dd'T'HH:mm:ssZ
27.12.18 format= dd.MM.yy
09:59:19.815 format= HH:mm:ss.SSS
SWIFT 5, Xcode 11.0
Pass your (date in string) in "dateString" and in "dateFormat" pass format you want. To choose format, use NDateFormatter website.
func getDateFrom(dateString: String, dateFormat: String) -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = dateFormat
dateFormatter.locale = Locale(identifier: "en_US")
guard let date = dateFormatter.date(from: dateString) else {return nil}
return date
}
Swift: iOS
if we have string, convert it to NSDate,
var dataString = profileValue["dob"] as String
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
// convert string into date
let dateValue:NSDate? = dateFormatter.dateFromString(dataString)
if you have and date picker parse date like this
// to avoid any nil value
if let isDate = dateValue {
self.datePicker.date = isDate
}
import Foundation
let now : String = "2014-07-16 03:03:34 PDT"
var date : NSDate
var dateFormatter : NSDateFormatter
date = dateFormatter.dateFromString(now)
date // $R6: __NSDate = 2014-07-16 03:03:34 PDT
https://developer.apple.com/library/prerelease/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/index.html#//apple_ref/doc/uid/20000447-SW32

Resources