I'm very new to the world of programming. I've started work as intern, where I need to learn Swift. I have an exercise to create a class of soccer players.
I have this code below and I'm using DateComponents to get the birthday, there is a way to just use the Date instead?
I was told to convert the Date to DateComponents but I couldn't figure it out.
Here's the code I tried:
let dateFormater = DateFormatter()
dateFormater.dateFormat = "MM/dd/yyyy"
dateFormater.string(from: birthday)
But I can't define the Date in my object
import UIKit
import Darwin
import Foundation
class SoccerPlayer {
let name: String
var position: String
var birthday: DateComponents
let nationality: String
var height: Double
var weight: Int
init(name: String, position: String, birthday: DateComponents, nationality: String, height: Double, weight: Int) {
self.name = name
self.position = position
self.birthday = birthday
self.nationality = nationality
self.height = height
self.weight = weight
}
func printInfo() {
let printOut: String = "name:\(name), position:\(position), birthday:\(birthday), nationality:\(nationality),height:\(height),weight:\(weight)"
print(printOut)
}
func calculationAge() -> Int {
let calendar = Calendar.current
let now = calendar.dateComponents([.year, .month, .day], from: Date())
let ageComponents = calendar.dateComponents([.year], from: birthday, to: now)
let age = ageComponents.year!
return age
}
func calculateRetire() -> Int {
var yearsToRetire = 0
if (self.position == "defense") {
yearsToRetire = 40 - self.calculationAge()
}
else if(self.position == "halfField") {
yearsToRetire = 38 - self.calculationAge()
}
else if(self.position == "attacker") {
yearsToRetire = 35 - self.calculationAge()
}
return yearsToRetire
}
}
enum PlayerPosition: String {
case attacker = "Attacker"
case halfField = "HalfField"
case defense = "Defense"
var description: String {
get {
return self.rawValue
}
}
}
var player1: SoccerPlayer = SoccerPlayer(name: "Andre", position: PlayerPosition.defense.description, birthday: DateComponents(year: 1998, month: 7, day: 1), nationality: "Brazilian", height: 1.70, weight: 70)
player1.printInfo()
It prints:
name:Andre, position:Defense, birthday:year: 1998 month: 7 day: 1 isLeapMonth: false , nationality:Brazilian,height:1.7,weight:70
CodePudding user response:
If you need to create a date using date components you need to pass the calendar component as well:
DateComponents(calendar: Calendar(identifier: .iso8601), year: 1998, month: 7, day: 1).date!
Besides that there is many points to improve in your code. Position property should be your existing enumeration. You can move the age calculation method to an instance computed property of Date. I would also create a DateFormatter to display the birthday. Note also that if you would like to create a custom description to the player you can make it conform to CustomStringConvertible and it already does when you add a description to your model/class.
You would need to add those extensions to your project:
extension Formatter {
static let birthday: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = .current
formatter.locale = .init(identifier: "pt_BR") // or en_US or current if you want to localize your date description
formatter.setLocalizedDateFormatFromTemplate("MMMMd") // if you would like to include the year use yyyyMMMMd
return formatter
}()
}
extension Date {
var age: Int {
Calendar(identifier: .iso8601).dateComponents([.year], from: self, to: Date()).year ?? .zero
}
var birthday: String {
Formatter.birthday.string(from: self)
}
}
And your code should look something like:
class SoccerPlayer {
let name: String
var position: Position
var dob: Date
let nationality: String
var height: Double
var weight: Int
init(name: String, position: Position, dob: Date, nationality: String, height: Double, weight: Int) {
self.name = name
self.position = position
self.dob = dob
self.nationality = nationality
self.height = height
self.weight = weight
}
var yearsToRetire: Int {
switch position {
case .defense:
return 40 - dob.age
case .halfField:
return 38 - dob.age
case .attacker:
return 35 - dob.age
}
}
}
extension SoccerPlayer: CustomStringConvertible {
var description: String {
"Name: \(name), Position: \(position), Birthday: \(dob.birthday), Nationality: \(nationality), Height: \(height), Weight: \(weight)"
}
}
extension SoccerPlayer {
enum Position: String {
case attacker, halfField, defense
}
}
extension SoccerPlayer.Position: CustomStringConvertible {
var description: String { rawValue.capitalized }
}
Usage:
let player1Dob = DateComponents(calendar: Calendar(identifier: .iso8601), year: 1998, month: 7, day: 1).date!
var player1: SoccerPlayer = .init(
name: "Andre",
position: .defense,
dob: player1Dob,
nationality: "Brazilian",
height: 1.7,
weight: 70
)
player1.yearsToRetire // 17
print(player1)
This will print:
Name: Andre, Position: Defense, Birthday: 1 de julho, Nationality: Brazilian, Height: 1.7, Weight: 70
