Home > Blockchain >  how to use Date instead dateComponents swift
how to use Date instead dateComponents swift

Time:02-08

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

  •  Tags:  
  • Related