Home > Software engineering >  How do I get the total time in hours and minutes from an selected start time to a selected end time?
How do I get the total time in hours and minutes from an selected start time to a selected end time?

Time:03-23

I've created a swiftui form with DatePickers for a startTime and an EndTime. I want to display the total and update it from an empty string to the hour and minute (example 10hrs 30min).

@State private var startTime = Date()
@State private var endTime = Date()
@State private var totalTime = differenceBetweenStartAndEndTimes

Form {
    DatePicker("Start Time", selection: $startTime, displayedComponents: .hourAndMinute)
    DatePicker("End Time", selection: $endTime, displayedComponents: .hourAndMinute)
    Text("Total: \(totalTime)")
}

I tried using Date().offset(from: endTime, to: startTime) and got errors back.

Then I tried this piece of code from stackOverflow:

func differenceBetweenStartAndEndTimes() {
let cal = Calendar.current
let components = cal.dateComponents([.hour], from: endTime, to: startTime)
let diff = components.hour!
}

still can't get it to work... I just started learning how to code with no previous knowledge 2 months ago so it may be something super simple I'm just not thinking about!!

CodePudding user response:

I think you really want to use a date formatter and a time interval. See the comments in the code, but you are trying to hard to make a variable have what you want to display. You can simply cause the display itself to format it the way you want. All you need to save is the actual time interval.

struct DateDifferences: View {
    
    @State private var startTime = Date()
    @State private var endTime = Date()
    var totalTime: TimeInterval {
        // This provides a time interval (difference between 2 dates in seconds as a Double
        endTime.timeIntervalSince(startTime)
    }

    // The DateComponentsFormatter handles how that time interval is displayed
    var dateFormatter: DateComponentsFormatter {
        let df = DateComponentsFormatter()
        // Limits the display to hours and mintues
        df.allowedUnits = [.hour, .minute]
        // Adds short units to hour and minutes as hr & min
        df.unitsStyle = .short
        return df
    }
    
    var body: some View {

        Form {
            DatePicker("Start Time", selection: $startTime, displayedComponents: .hourAndMinute)
            DatePicker("End Time", selection: $endTime, displayedComponents: .hourAndMinute)
            Text("Total: \(totalTime)")
            Text(dateFormatter.string(from: totalTime) ?? "")
        }
    }
}

CodePudding user response:

This is SwiftUI, in SwiftUI 3 there are a lot of convenient native formatters if you can live with hr rather than hrs

Text("Total: "   (startTime..<endTime).formatted(.components(style: .narrow, fields: [.hour, .minute])))
  • Related