Swift - iOS - Dates and times in different format - ios

I am working for an application written in swift and i want to manipulate dates and times
let timestamp = NSDateFormatter.localizedStringFromDate(
NSDate(),
dateStyle: .ShortStyle,
timeStyle: .ShortStyle
)
returns
2/12/15, 11:27 PM
if I want date and time in a different format, for example the date in a European format like dd/mm/yy and the hours in the 24h format without AM and PM. Is there some function that i can use or i have to use N Strings to reorder the various elements?

func convertDateFormater(date: String) -> String {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
dateFormatter.timeZone = NSTimeZone(name: "UTC")
guard let date = dateFormatter.dateFromString(date) else {
assert(false, "no date from string")
return ""
}
dateFormatter.dateFormat = "yyyy MMM EEEE HH:mm"
dateFormatter.timeZone = NSTimeZone(name: "UTC")
let timeStamp = dateFormatter.stringFromDate(date)
return timeStamp
}
Edit for Swift 4
func convertDateFormatter(date: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"//this your string date format
dateFormatter.timeZone = NSTimeZone(name: "UTC") as TimeZone!
dateFormatter.locale = Locale(identifier: "your_loc_id")
let convertedDate = dateFormatter.date(from: date)
guard dateFormatter.date(from: date) != nil else {
assert(false, "no date from string")
return ""
}
dateFormatter.dateFormat = "yyyy MMM HH:mm EEEE"///this is what you want to convert format
dateFormatter.timeZone = NSTimeZone(name: "UTC") as TimeZone!
let timeStamp = dateFormatter.string(from: convertedDate!)
return timeStamp
}

As already mentioned you have to use DateFormatter to format your Date objects. The easiest way to do it is creating a read-only computed property Date extension.
Read-Only Computed Properties
A computed property with a getter but no setter is known as a
read-only computed property. A read-only computed property always
returns a value, and can be accessed through dot syntax, but cannot be
set to a different value.
Note:
You must declare computed properties—including read-only computed
properties—as variable properties with the var keyword, because their
value is not fixed. The let keyword is only used for constant
properties, to indicate that their values cannot be changed once they
are set as part of instance initialization.
You can simplify the declaration of a read-only computed property by
removing the get keyword and its braces:
extension Formatter {
static let date = DateFormatter()
}
extension Date {
var europeanFormattedEn_US : String {
Formatter.date.calendar = Calendar(identifier: .iso8601)
Formatter.date.locale = Locale(identifier: "en_US_POSIX")
Formatter.date.timeZone = .current
Formatter.date.dateFormat = "dd/M/yyyy, H:mm"
return Formatter.date.string(from: self)
}
}
To convert it back you can create another read-only computed property but as a string extension:
extension String {
var date: Date? {
return Formatter.date.date(from: self)
}
func dateFormatted(with dateFormat: String = "dd/M/yyyy, H:mm", calendar: Calendar = Calendar(identifier: .iso8601), defaultDate: Date? = nil, locale: Locale = Locale(identifier: "en_US_POSIX"), timeZone: TimeZone = .current) -> Date? {
Formatter.date.calendar = calendar
Formatter.date.defaultDate = defaultDate ?? calendar.date(bySettingHour: 12, minute: 0, second: 0, of: Date())
Formatter.date.locale = locale
Formatter.date.timeZone = timeZone
Formatter.date.dateFormat = dateFormat
return Formatter.date.date(from: self)
}
}
Usage:
let dateFormatted = Date().europeanFormattedEn_US //"29/9/2018, 16:16"
if let date = dateFormatted.date {
print(date.description(with:.current)) // Saturday, September 29, 2018 at 4:16:00 PM Brasilia Standard Time\n"\
date.europeanFormattedEn_US // "29/9/2018, 16:27"
}
let dateString = "14/7/2016"
if let date = dateString.toDateFormatted(with: "dd/M/yyyy") {
print(date.description(with: .current))
// Thursday, July 14, 2016 at 12:00:00 PM Brasilia Standard Time\n"
}

As Zaph stated, you need to follow the documentation. Admittedly it may not be the most straightforward when compared to other class references. The short answer is, you use Date Field Symbol Table to figure out what format you want. Once you do:
let dateFormatter = NSDateFormatter()
//the "M/d/yy, H:mm" is put together from the Symbol Table
dateFormatter.dateFormat = "M/d/yy, H:mm"
dateFormatter.stringFromDate(NSDate())
You'll also need to be able to use the table if you need to convert a date that is a string into an NSDate.
let dateAsString = "02/12/15, 16:48"
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "M/d/yyyy, H:mm"
let date = dateFormatter.dateFromString(dateAsString)

Current date time to formated string:
let currentDate = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy hh:mm:ss a"
let convertedDate: String = dateFormatter.string(from: currentDate) //08/10/2016 01:42:22 AM
More Date Time Formats

You have already found NSDateFormatter, just read the documentation on it.
NSDateFormatter Class Reference
For format character definitions
See: ICU Formatting Dates and Times
Also: Date Field SymbolTable..

If you want to use protocol oriented programming (Swift 3)
1) Create a Dateable protocol
protocol Dateable {
func userFriendlyFullDate() -> String
func userFriendlyHours() -> String
}
2) Extend Date class and implement the Dateable protocol
extension Date: Dateable {
var formatter: DateFormatter { return DateFormatter() }
/** Return a user friendly hour */
func userFriendlyFullDate() -> String {
// Customize a date formatter
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
formatter.timeZone = TimeZone(abbreviation: "UTC")
return formatter.string(from: self)
}
/** Return a user friendly hour */
func userFriendlyHours() -> String {
// Customize a date formatter
formatter.dateFormat = "HH:mm"
formatter.timeZone = TimeZone(abbreviation: "UTC")
return formatter.string(from: self)
}
// You can add many cases you need like string to date formatter
}
3) Use it
let currentDate: Date = Date()
let stringDate: String = currentDate.userFriendlyHours()
// Print 15:16

I used the a similar approach as #iod07, but as an extension.
Also, I added some explanations in the comments to understand how it works.
Basically, just add this at the top or bottom of your view controller.
extension NSString {
class func convertFormatOfDate(date: String, originalFormat: String, destinationFormat: String) -> String! {
// Orginal format :
let dateOriginalFormat = NSDateFormatter()
dateOriginalFormat.dateFormat = originalFormat // in the example it'll take "yy MM dd" (from our call)
// Destination format :
let dateDestinationFormat = NSDateFormatter()
dateDestinationFormat.dateFormat = destinationFormat // in the example it'll take "EEEE dd MMMM yyyy" (from our call)
// Convert current String Date to NSDate
let dateFromString = dateOriginalFormat.dateFromString(date)
// Convert new NSDate created above to String with the good format
let dateFormated = dateDestinationFormat.stringFromDate(dateFromString!)
return dateFormated
}
}
Example
Let's say you want to convert "16 05 05" to "Thursday 05 May 2016" and your date is declared as follow let date = "16 06 05"
Then simply call call it with :
let newDate = NSString.convertFormatOfDate(date, originalFormat: "yy MM dd", destinationFormat: "EEEE dd MMMM yyyy")
Hope it helps !

Here is a solution that works with Xcode 10.1 (FEB 23 2019) :
func getCurrentDateTime() {
let now = Date()
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "fr_FR")
formatter.dateFormat = "EEEE dd MMMM YYYY"
labelDate.text = formatter.string(from: now)
labelDate.font = UIFont(name: "HelveticaNeue-Bold", size: 12)
labelDate.textColor = UIColor.lightGray
let text = formatter.string(from: now)
labelDate.text = text.uppercased()
}
The "Accueil" Label is not connected to the code.

iOS 8+
It is cumbersome and difficult to specify locale explicitly. You never know where your app will be used. So I think, it is better to set locale to Calender.current.locale and use DateFormatter's
setLocalizedDateFormatFromTemplate method.
setLocalizedDateFormatFromTemplate(_:)
Sets the date format from a template using the specified locale for the receiver. - developer.apple.com
extension Date {
func convertToLocaleDate(template: String) -> String {
let dateFormatter = DateFormatter()
let calender = Calendar.current
dateFormatter.timeZone = calender.timeZone
dateFormatter.locale = calender.locale
dateFormatter.setLocalizedDateFormatFromTemplate(template)
return dateFormatter.string(from: self)
}
}
Date().convertToLocaleDate(template: "dd MMMM YYYY")

Swift 3:
//This gives month as three letters (Jun, Dec, etc)
let justMonth = DateFormatter()
justMonth.dateFormat = "MMM"
myFirstLabel.text = justMonth.string(from: myDate)
//This gives the day of month, with no preceding 0s (6,14,29)
let justDay = DateFormatter()
justDay.dateFormat = "d"
mySecondLabel.text = justDay.string(from: myDate)
//This gives year as two digits, preceded by an apostrophe ('09, '16, etc)
let justYear = DateFormatter()
justYear.dateFormat = "yy"
myThirdLabel.text = "'\(justYear.string(from: lastCompDate))"
For more formats, check out this link to a codingExplorer table with all the available formats. Each date component has several options, for example:
Year:
"y" - 2016 (early dates like year 1 would be: "1")
"yy" - 16 (year 1: "01"
"yyy" - 2016 (year 1: "001")
"yyyy" - 2016 (year 1: "0001")
Pretty much every component has 2-4 options, using the first letter to express the format (day is "d", hour is "h", etc). However, month is a capital "M", because the lower case "m" is reserved for minute. There are some other exceptions though, so check out the link!

let usDateFormat = DateFormatter.dateFormat(FromTemplate: "MMddyyyy", options: 0, locale: Locale(identifier: "en-US"))
//usDateFormat now contains an optional string "MM/dd/yyyy"
let gbDateFormat = DateFormatter.dateFormat(FromTemplate: "MMddyyyy", options: 0, locale: Locale(identifier: "en-GB"))
//gbDateFormat now contains an optional string "dd/MM/yyyy"
let geDateFormat = DateFormatter.dateFormat(FromTemplate: "MMddyyyy", options: 0, locale: Locale(identifier: "de-DE"))
//geDateFormat now contains an optional string "dd.MM.yyyy"
You can use it in following way to get the current format from device:
let currentDateFormat = DateFormatter.dateFormat(fromTemplate: "MMddyyyy", options: 0, locale: Locale.current)

Added some formats in one place. Hope someone get help.
Xcode 12 - Swift 5.3
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm:ss"
var dateFromStr = dateFormatter.date(from: "12:16:45")!
dateFormatter.dateFormat = "hh:mm:ss a 'on' MMMM dd, yyyy"
//Output: 12:16:45 PM on January 01, 2000
dateFormatter.dateFormat = "E, d MMM yyyy HH:mm:ss Z"
//Output: Sat, 1 Jan 2000 12:16:45 +0600
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
//Output: 2000-01-01T12:16:45+0600
dateFormatter.dateFormat = "EEEE, MMM d, yyyy"
//Output: Saturday, Jan 1, 2000
dateFormatter.dateFormat = "MM-dd-yyyy HH:mm"
//Output: 01-01-2000 12:16
dateFormatter.dateFormat = "MMM d, h:mm a"
//Output: Jan 1, 12:16 PM
dateFormatter.dateFormat = "HH:mm:ss.SSS"
//Output: 12:16:45.000
dateFormatter.dateFormat = "MMM d, yyyy"
//Output: Jan 1, 2000
dateFormatter.dateFormat = "MM/dd/yyyy"
//Output: 01/01/2000
dateFormatter.dateFormat = "hh:mm:ss a"
//Output: 12:16:45 PM
dateFormatter.dateFormat = "MMMM yyyy"
//Output: January 2000
dateFormatter.dateFormat = "dd.MM.yy"
//Output: 01.01.00
//Output: Customisable AP/PM symbols
dateFormatter.amSymbol = "am"
dateFormatter.pmSymbol = "Pm"
dateFormatter.dateFormat = "a"
//Output: Pm
// Usage
var timeFromDate = dateFormatter.string(from: dateFromStr)
print(timeFromDate)

let dateString = "1970-01-01T13:30:00.000Z"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
let date = formatter.date(from: String(dateString.dropLast(5)))!
formatter.dateFormat = "hh.mma"
print(formatter.string(from: date))
if You notice I have set .dateFormat = "hh.mma"by this you will get time only.
Result:01.30PM

extension String {
func convertDatetring_TopreferredFormat(currentFormat: String, toFormat : String) -> String {
let dateFormator = DateFormatter()
dateFormator.dateFormat = currentFormat
let resultDate = dateFormator.date(from: self)
dateFormator.dateFormat = toFormat
return dateFormator.string(from: resultDate!)
}
}
Call from your view controller file as below.
"your_date_string".convertDatetring_TopreferredFormat(currentFormat: "yyyy-MM-dd HH:mm:ss.s", toFormat: "dd-MMM-yyyy h:mm a")

This is possibly an old thread but I was working on datetimes recently and was stuck with similar issue so I ended up creating a utility of mine which looks like this,
This utility would take a string date and would return an optional date object
func toDate(dateFormat: DateFormatType) -> Date? {
let formatter = DateFormatter()
formatter.timeZone = NSTimeZone(name: "UTC") as TimeZone?
formatter.dateFormat = dateFormat.rawValue
let temp = formatter.date(from: self)
return formatter.date(from: self)
}
the DateFormatType enum looks like this
enum DateFormatType : String {
case type1 = "yyyy-MM-dd - HH:mm:ss"
case type2 = "dd/MM/yyyy"
case type3 = "yyyy/MM/dd"
}
One important thing I would like to mention here is the line
formatter.timeZone = NSTimeZone(name: "UTC") as TimeZone?
it's very important that you add this line because without this the DateFormatter would use it's default conversions to convert the date and you might end up seeing different dates if you are working with a remote team and get all sorts of issues with data depending on dates.
Hope this helps

Time Picker In swift
class ViewController: UIViewController {
//timePicker
#IBOutlet weak var lblTime: UILabel!
#IBOutlet weak var timePicker: UIDatePicker!
#IBOutlet weak var cancelTime_Btn: UIBarButtonItem!
#IBOutlet weak var donetime_Btn: UIBarButtonItem!
#IBOutlet weak var toolBar: UIToolbar!
//Date picker
// #IBOutlet weak var datePicker: UIDatePicker!
override func viewDidLoad() {
super.viewDidLoad()
ishidden(bool: true)
let dateFormatter2 = DateFormatter()
dateFormatter2.dateFormat = "HH:mm a" //"hh:mm a"
lblTime.text = dateFormatter2.string(from: timePicker.date)
}
#IBAction func selectTime_Action(_ sender: Any) {
timePicker.datePickerMode = .time
ishidden(bool: false)
}
#IBAction func timeCancel_Action(_ sender: Any) {
ishidden(bool: true)
}
#IBAction func timeDoneBtn(_ sender: Any) {
let dateFormatter1 = DateFormatter()
dateFormatter1.dateFormat = "HH:mm a"//"hh:mm"
let str = dateFormatter1.string(from: timePicker.date)
lblTime.text = str
ishidden(bool: true)
}
func ishidden(bool:Bool){
timePicker.isHidden = bool
toolBar.isHidden = bool
}
}

new Date(year,month,day,0,0,0,0) is local time (as input)
new Date(year,month,day) is UTC
I was using a function to attain YYYY-MM-DD format to be compatible on iOS web, but that is also UTC when used in comparisons (not chained by getFullYear or similar) I've found it is best to use only the above with strong (hours,minutes,seconds,milliseconds) building a calendar, calculating with a Date objects and local references
export const zeroPad = (num) => {
var res = "0";
if (String(num).length === 1) {
res = `0${num}`;
} else {
res = num;
}
return res;
};

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"
}

Convert NSDate to String in iOS Swift [duplicate]

This question already has answers here:
Convert NSDate to NSString
(19 answers)
Closed 5 years ago.
I am trying to convert a NSDate to a String and then Change Format. But when I pass NSDate to String it is producing whitespace.
let formatter = DateFormatter()
let myString = (String(describing: date))
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let yourDate: Date? = formatter.date(from: myString)
formatter.dateFormat = "dd-MMM-yyyy"
print(yourDate)
you get the detail information from Apple Dateformatter Document.If you want to set the dateformat for your dateString, see this link , the detail dateformat you can get here
for e.g , do like
let formatter = DateFormatter()
// initially set the format based on your datepicker date / server String
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let myString = formatter.string(from: Date()) // string purpose I add here
// convert your string to date
let yourDate = formatter.date(from: myString)
//then again set the date format whhich type of output you need
formatter.dateFormat = "dd-MMM-yyyy"
// again convert your date to string
let myStringDate = formatter.string(from: yourDate!)
print(myStringDate)
you get the output as
I always use this code while converting Date to String . (Swift 3)
extension Date
{
func toString( dateFormat format : String ) -> String
{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
return dateFormatter.string(from: self)
}
}
and call like this . .
let today = Date()
today.toString(dateFormat: "dd-MM")
DateFormatter has some factory date styles for those too lazy to tinker with formatting strings. If you don't need a custom style, here's another option:
extension Date {
func asString(style: DateFormatter.Style) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = style
return dateFormatter.string(from: self)
}
}
This gives you the following styles:
short, medium, long, full
Example usage:
let myDate = Date()
myDate.asString(style: .full) // Wednesday, January 10, 2018
myDate.asString(style: .long) // January 10, 2018
myDate.asString(style: .medium) // Jan 10, 2018
myDate.asString(style: .short) // 1/10/18
Your updated code.update it.
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let myString = formatter.string(from: date as Date)
let yourDate: Date? = formatter.date(from: myString)
formatter.dateFormat = "dd-MMM-yyyy"
print(yourDate!)
Something to keep in mind when creating formatters is to try to reuse the same instance if you can, as formatters are fairly computationally expensive to create. The following is a pattern I frequently use for apps where I can share the same formatter app-wide, adapted from NSHipster.
extension DateFormatter {
static var sharedDateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
// Add your formatter configuration here
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
return dateFormatter
}()
}
Usage:
let dateString = DateFormatter.sharedDateFormatter.string(from: Date())
After allocating DateFormatter you need to give the formatted string
then you can convert as string like this way
var date = Date()
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let myString = formatter.string(from: date)
let yourDate: Date? = formatter.date(from: myString)
formatter.dateFormat = "dd-MMM-yyyy"
let updatedString = formatter.string(from: yourDate!)
print(updatedString)
OutPut
01-Mar-2017
You can use this extension:
extension Date {
func toString(withFormat format: String) -> String {
let formatter = DateFormatter()
formatter.dateFormat = format
let myString = formatter.string(from: self)
let yourDate = formatter.date(from: myString)
formatter.dateFormat = format
return formatter.string(from: yourDate!)
}
}
And use it in your view controller like this (replace <"yyyy"> with your format):
yourString = yourDate.toString(withFormat: "yyyy")

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)

Date picker shows a different date (1 day behined) from when picked

I have a UIDatePicker that is connected to a UILabel. I want the user to pick a birthday that is more than 18 years ago (age restriction). So I have this line to set the maximumDate value:
datePicker.maximumDate = NSCalendar.currentCalendar().dateByAddingUnit(.Year, value: -18, toDate: NSDate(), options: [])
This line however causes the picker to show a 1 day behind the selected date. for example if I choose September 27, 1956 on the picker the label shows September 26, 1956 I believe it has to do with NSDate() using a different timezone one that is behind my local timezone.
switch dequeueFrom[indexPath.row] {
case .Birthday:
if let pickedBday = pickedBday,
let bday = NSDate.dateFromISOString(pickedBday) {
(cell as! RegisterTextFieldCell).content(bday.longFormattedString())
}
// dateFromISOSString is declared in an extension.swift
class func dateFromComponents(components: NSDateComponents) -> NSDate? {
let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
return calendar?.dateFromComponents(components)
}
class func dateFromString(string: String) -> NSDate? {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss-SSS"
if let stringDate = dateFormatter.dateFromString(string) {
return stringDate
} else {
return nil
}
}
func ISOStringFromDate() -> String {
let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"
return dateFormatter.stringFromDate(self).stringByAppendingString("Z")
}
class func dateFromISOString(string: String) -> NSDate? {
let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
if let stringDate = dateFormatter.dateFromString(string) {
return stringDate
} else {
return nil
}
}
Any help with how I can make NSDate() be my local timezone so this one day behind issue can go away? Any help is greatly appreciated :)
The problem is in your method ISOStringFromDate because you are getting the local time and manually adding the Z (Z means UTC) to the string. Try like this when creating your iso8601:
extension NSDate {
var iso8601: String {
let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
dateFormatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
return dateFormatter.stringFromDate(self)
}
}
and your code should be:
pickedDate.iso8601 // to get your date iso8601 string

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