I'm trying to create model object which has Date but I can't find out how to init in terms of converting to String.
This is the date structure.
let date = NSDate()
let format = DateFormatter()
format.dateFormat = "yyyy-MM/dd HH:mm"
let strDate = format.string(from: date as Date)
Model
import UIKit
struct Post {
var Date: Date!
var Text: String
init(dictionary: [String:Any]) {
self.Date = dictionary["Date"] as? Date
self.Text = dictionary["Text"] as? String ?? ""
}
}
After I fetch data from firebase, I would like to do like below but error says
Cannot assign value of type 'Date.Type' to type 'String?'
var post: Post? {
didSet {
dateLabel.text = post?.Date
caprionLabel.text = post?.Text
}
}
Does anyone know how can I fix this?
Thank you in advance!
You are getting confused with Date and String, both are different Objects, You can't assign to each other.
There are two solutions to the same
If you want to show exactly the same date that is coming,
import UIKit
struct Post {
var dateString:String!
var Text: String
init(dictionary: [String:Any]) {
self.dateString = dictionary["Date"] as? String
self.Text = dictionary["Text"] as? String ?? ""
}
}
ALSO , Label can only Accept String to save
var post: Post? {
didSet {
dateLabel.text = post?.dateString
caprionLabel.text = post?.Text
}
}
Save both Date and String in your model
struct Post {
var dateString:String!
var date:Date!
var Text: String
init(dictionary: [String:Any]) {
self.dateString = dictionary["Date"] as? String
let format = DateFormatter()
format.dateFormat = "yyyy-MM/dd HH:mm"
// If dateString doesn't match your date Format Provided
self.date = format.date(from: dateString) ?? Date()
self.Text = dictionary["Text"] as? String ?? ""
}
}
ALSO , Label can only Accept String to save
var post: Post? {
didSet {
let format = DateFormatter()
// Assign to any format you want
format.dateFormat = "yyyy-MM/dd HH:mm"
dateLabel.text = format.string(from: post!.date)
caprionLabel.text = post?.Text
}
}
The error occurs because Date (uppercase) is a reserved struct type in Swift. The error message
Cannot assign value of type 'Date.Type' to type 'String?'
clearly states it.
Conform to the naming convention that variable names start with a lowercase letter. It avoids this kind of silly type errors.
And never ever declare variables in a struct as implicit unwrapped optional which are initialized in an init method. If they are supposed to be optional declare them as regular optional (?).
And put the code to format the date as string in the struct.
import UIKit
struct Post {
var date: Date?
var text: String
init(dictionary: [String:Any]) {
self.date = dictionary["Date"] as? Date
self.text = dictionary["Text"] as? String ?? ""
}
var formattedDate : String {
let format = DateFormatter()
format.dateFormat = "yyyy-MM/dd HH:mm"
return format.string(from: date)
}
}
var post: Post? {
didSet {
dateLabel.text = post?.formattedDate
caprionLabel.text = post?.text
}
}
Related
How do I format this date so that it is readable. I want it to show for example: "January 7th, 2018 7:30am". I tried to look at other answers but wasn't sure where to add the extension.
let date = Date(timeIntervalSince1970: request.timestamp / 1000)
dateCell.textLabel?.text = date.description
class Request {
var key:String
var sender:String
var recipient:String
var name:String
var location:String
var when:String
var whereStr:String
var message:String
var timestamp:Double
var status:String
init(dict: [String: Any]) {
self.key = dict["key"] as? String ?? ""
self.sender = dict["sender"] as? String ?? ""
self.recipient = dict["recipient"] as? String ?? ""
self.name = dict["name"] as? String ?? ""
self.location = dict["location"] as? String ?? ""
self.when = dict["when"] as? String ?? ""
self.whereStr = dict["where"] as? String ?? ""
self.message = dict["message"] as? String ?? ""
self.timestamp = dict["timestamp"] as? Double ?? 0.0
self.status = dict["status"] as? String ?? ""
}
Try This
func getCurrentDateTimeFromTimeStamp(timeStapm:String)->String{
let date = NSDate(timeIntervalSince1970:Double(timeStapm)!/1000)
let formatter = DateFormatter()
formatter.dateFormat = "MMMM d, yyyy HH:mm a"
return formatter.string(from: date as Date)
}
pass timestamp and get as date in string format as per your requirement just pass dateFormat.
use like this
dateCell.textLabel?.text = self.getCurrentDateTimeFromTimeStamp(timeStapm:"pass your timestamp")
You should use DateFormatter:
let formatter = DateFormatter()
formatter.format = "MMMM d, yyyy HH:mm a"
let dateString = formatter.string(from: date)
Use a dateFormatter object to style the date however you want
let format = DateFormatter()
format.format = "MM/dd/yyyy"
//get your date in string like this
let dateInString = format.string(from: date)
// this will give you "10/02/2018"
You can visit date format examples to see different format and how to get them.
You can add extension anywhere in the app and one (same name) extension for comlpete app. look below
import UIKit
class ViewControllerHellBoy: UIViewController
{
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
dateCell.textLabel?.text = self.userFriendlyFullDate()
}
}
extension Date: Dateable {
var formatter: DateFormatter { return DateFormatter() }
/** Return a user friendly hour */
func userFriendlyFullDate() -> String {
// Customize a date formatter
formatter.dateFormat = ""MMMM d, yyyy HH:mm a"" //Use format you want to
formatter.timeZone = TimeZone(abbreviation: "UTC") . // Time zone you wishes to provide
return formatter.string(from: self)
}
That is how you can use extensions. You can also create separate class and keep all extensions there.
I can get it to work fine using just Strings but if I try to use Doubles or NSDates then I get an error:
"Cannot assign value of type "NSDate?" to type "String?"
"Cannot assign value of type "Double?" to type "String?"
#IBAction func save(_ sender: Any) {
if item != nil {
item?.startdate = startDate.text
item?.pickup = pickup.text
item?.miles = miles.text
item?.company = company.text
item?.destination = destination.text
item?.enddate = endDate.text
} else {
let entitydescription = NSEntityDescription.entity(forEntityName: "Entity", in: pc)
let item = Entity(entity: entitydescription!, insertInto: pc)
item.startdate = startDate.text
item.pickup = pickup.text
item.miles = miles.text
item.company = company.text
item.destination = destination.text
item.enddate = endDate.text
}
do {
try pc.save()
} catch {
print(error)
return
}
navigationController!.popViewController(animated: true)
}
Here is what type each field is:
#NSManaged public var startdate: NSDate?
#NSManaged public var pickup: String?
#NSManaged public var miles: Double
#NSManaged public var company: String?
#NSManaged public var destination: String?
#NSManaged public var enddate: NSDate?
You need to convert miles.text, startdate.text and enddate.text to Double, NSDate and NSDate, respectively.
For startdate.text / enddate.text:
I'm not sure how what limit you have set for these values when the item is saved, but you should use a default value just incase the conversion fails. For this example, assume the dates are formatted "5/15/17" which takes the format M/d/y
let defaultDate = NSDate() //current date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "M/d/y"
if let startDateText = startdate.text, let startDate = dateFormatter.string(from: startDateText) as? NSDate {
item?.startdate = startDate
} else {
item?.startdate = defaultDate
}
if let endDateText = startdate.text, let endDate = dateFormatter.string(from: endDateText) as? NSDate {
item?.startdate = endDate
} else {
item?.startdate = defaultDate
}
For miles.text:
Same idea, use a default value incase the conversion failed based on what the text will be for item.miles
if let milesText = miles.text {
item?.miles = Double(miles.text) ?? 0.0 //default is 0.0
} else {
item?.miles = 0.0
}
or an easy one-liner—
item?.miles = Double(miles.text ?? "0.0")
if there's a specific default value you have in mind, just declare it before you assign the item's property,
let defaultMilesStr = "0.432"
item?.miles = Double(miles.text ?? defaultMiles)
Also, just a tip, it's good practice to not leave optionals wrapped when assigning values. So even though there was check to make sure item != nil, it's overall better to safely unwrap item with a "guard" or "if-let". Since you are creating a new item if one doesn't exist, id go with if-let in this case:
if let item = item {
// assign values to item's prop's
// item.startdate = .....
} else if let entityDescription = NSEntityDescription.entity(forEntityName: "Entity", in: pc), let item = Entity(entity: entityDescription, insertInto: pc) {
// assign values to item's prop's
// item.startdate = .....
}
//further execution
Convert your date string to NSdate then you are able to save that
Try this code i have provide my date string you mat change with your format
let dateString = "Thu, 22 Oct 2015 07:45:17 +0000"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEE, dd MMM yyyy hh:mm:ss +zzzz"
dateFormatter.locale = Locale.init(identifier: "en_GB")
let dateObj = dateFormatter.date(from: dateString)
dateFormatter.dateFormat = "MM-dd-yyyy"
Try this :
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = /* date_format_you_want_in_string from
* http://userguide.icu-project.org/formatparse/datetime
*/
let date = dateFormatter.date(from: /* your_date_string */)
and set it as :
item?.date = date
For miles you can use :
if let dMiles = Double(miles.text!) {
item?.miles.text = dMiles
} else {
print("Not a valid Double: \(textField.text!)")
}
Hope it Helps!!
I am able to get NSDate to appear as date only and to show it in textfields to add and edit to core data but in the tableviewcell when using the subtitle style it comes out with both the date and time which I don't need thee time.
Any help is appreciated.
the following code is my NSDateFormatter
import Foundation
extension NSDate{
var stringValue: String{
return self.toString()
}
func toString() -> String {
let formatter = NSDateFormatter()
formatter.dateFormat = "dd-MMM-YYYY"
let str = formatter.stringFromDate(self)
return str
}
}
extension String{
var dateValue: NSDate?{
return self.toDate()
}
func toDate() -> NSDate? {
let formatter = NSDateFormatter()
formatter.dateFormat = "dd-MMM-YYYY"
if let date = formatter.dateFromString(self) {
return date
}else{
// if format failed, Put some code here
return nil // an example
}
}
}
the following code is the subtitle style. date is called from cordite
cell.detailTextLabel!.text = "(ddate)"
OK, Found out what I was doing wrong. I added the following line above the cell.detail.textLabel and it works
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MMM-dd-yyy"
let dateForText = ddate as? NSDate
cell.detailTextLabel!.text = dateFormatter.stringFromDate(dateForText!)
There's an exception when I run it.
self.year = value as! NSString
Exception:
Could not cast value of type '__NSDate' (0x1051bd6a0) to 'NSString' (0x10564d8e0).
What am I missing ?
var datePicker = ActionSheetDatePicker(title: "Date:",datePickerMode: UIDatePickerMode.Date, selectedDate: NSDate(),doneBlock: {
picker, value, index in
self.year = value as! NSString
println("year = \(year)")
println("value = \(value)")
return
}, cancelBlock: { ActionStringCancelBlock in return }, origin: sender.superview!.superview)
I think you have to convert date to string via your selected value
let formatter: DateFormatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd-HH-mm-ss"
let dateStr: String = formatter.string(from: value as! Date)
You can use any other format like : "yyyy" or "HH:mm:ss" etc.
and set it to your year variable
self.year = dateStr
beginner alert
I'm trying to query for a date from PFUser and then format it to NSDate so it is more useful. The trouble begins when I try to convert the object to a NSString so I can format it with NSDateFormatter()
var user = PFUser.query()
user.whereKey("username", equalTo: PFUser.currentUser().username)
user.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if error == nil {
for object in objects {
var lastActive = object["lastActive"]
if lastActive != nil {
let newLastActive = lastActive as String //problem starts here!!
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSS'Z'"
let date = dateFormatter.dateFromString(newLastActive)
println("new date \(date)")
}
}
}
}
What is the correct way of doing this? Also, if I don't specify the variable type as AnyObject, it keeps coming out as a optional. How do I get rid of the optional while converting it to String?
edit: the object "lastActive" is a date set by parse cloud, not a string.
If your lastActive cell returns a date you could use:
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSS'Z'"
let date = dateFormatter.stringFromDate(lastActive as NSDate)
You dont have to cast your date to string, you will create a date string via the dateformatter.
But if you do so, you could use lastActive as! String insted of lastActive as String
UPDATED
for object in objects {
var lastActive = object["lastActive"]
if lastActive != nil {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSS'Z'"
let date = dateFormatter.stringFromDate(lastActive as NSDate)
println(date)
}
}
I tried with this code above and if you've set your column in parse to date, it should work.