在Swift中把小数时间转换为小时和分钟。

问题描述 投票:3回答:4

我是编程新手,这是我的第一个程序和问题。我想写一个函数,简单地将十进制时间转换为小时& 分钟。我正在删除小时,并将十进制分钟乘以60,然后将两者相加为一个字符串。我需要在我的程序中多次使用这个功能,因此使用了这个函数。使用这个函数的计算很简单,但我得到了奇怪的结果。如果我将'plannedStartFuel'保持为450,并调整'minLandAllowance',我得到以下结果。

185 returns 1:28
182 returns 1:29
181 returns 1:30
180 returns 2:30
179 returns 2:30
175 returns 2:32

正确答案是1:00的数字。我不明白为什么程序在180点的时候似乎要给结果加一个小时。我相信有比我使用的更好的方法来完成这个计算,但如果你能帮助我,我会很感激,知道是哪个部分导致了错误,为什么。我试了什么......什么都试过了! 如果你把你的答案投给一个7岁的孩子,我也许有机会理解。谢谢你。

import UIKit
import Foundation

func decimalHoursConv (hours : Double) -> (_hrs:String, mins:String) {

    let remainder = hours.truncatingRemainder(dividingBy: 1) * 60
    let mins = (String(format: "%.0f", remainder))

    let hrs = (String(format: "%.0f", hours))

    return (hrs, mins)
}
var plannedStartFuel = Double (0)
var minLandAllowance = Double (0)
var flyingTimeToMLA = Double(0)

plannedStartFuel = 450
minLandAllowance = 180

flyingTimeToMLA = ((plannedStartFuel - minLandAllowance) / 3)/60

let MLAtime = (decimalHoursConv(hours: flyingTimeToMLA))

print ("Flight Time To MLA =", MLAtime.0,"hrs",MLAtime.1,"mins")
swift function calculation
4个回答
1
投票

我可能会建议不要费心去计算小时和分钟,而是让它来计算小时和分钟。DateComponentsFormatter 这样做,为你创建最终的字符串。

比如说。

let formatter: DateComponentsFormatter = {
    let formatter = DateComponentsFormatter()
    formatter.unitsStyle = .full
    formatter.allowedUnits = [.hour, .minute]
    return formatter
}()

然后向这个格式化器提供以秒为单位的经过时间(a) TimeInterval的别称,它只是 Double):

let remaining: TimeInterval = 90 * 60 // e.g. 90 minutes represented in seconds

if let result = formatter.string(from: remaining) {
    print(result)
}

在英语设备上,将产生:

1小时30分钟

这种方法的优点是,它不仅让你摆脱了自己手动计算小时和分钟的业务,而且结果很容易本地化。因此,如果你要对你的应用进行本地化,这个字符串也会自动为你进行本地化,你无需再做任何工作。例如,如果您将德语添加到您的应用程序本地化中,那么美国用户仍将看到上述内容,但在德国设备上,它将产生。

1小时30分钟


如果你想让它显示剩余的时间,请设置 includesTimeRemainingPhrase:

let formatter: DateComponentsFormatter = {
    let formatter = DateComponentsFormatter()
    formatter.unitsStyle = .full
    formatter.includesTimeRemainingPhrase = true
    formatter.allowedUnits = [.hour, .minute]
    return formatter
}()

这将产生。

剩余1小时30分钟

如果你想用 "hh:mm "的方式表示。

let formatter: DateComponentsFormatter = {
    let formatter = DateComponentsFormatter()
    formatter.unitsStyle = .positional
    formatter.zeroFormattingBehavior = .pad
    formatter.allowedUnits = [.hour, .minute]
    return formatter
}()

会产生:

01:30


一句话,如果你真的想计算分和秒,请随意,但如果只是为了创建一个字符串表示法,请让 DateComponentFormatter 为你做这个。


1
投票

编辑我知道你想知道你的方法有什么不妥.这是个四舍五入的问题,你可以试试roundind hours 再传给 String(format:) :

func decimalHoursConv (hours : Double) -> (_hrs:String, mins:String) {
    let remainder = hours.truncatingRemainder(dividingBy: 1) * 60
    let mins = (String(format: "%.0f", remainder))

    let hours = hours.rounded(.towardZero)
    let hrs = (String(format: "%.0f", hours))

    return (hrs, mins)
}

它给:

var value = (450.0-185.0)/3
decimalHoursConv(hours: value/60) // (_hrs "1", mins "28")
value = (450.0-182.0)/3
decimalHoursConv(hours: value/60) // (_hrs "1", mins "29")
value = (450.0-181.0)/3
decimalHoursConv(hours: value/60) // (_hrs "1", mins "30")
value = (450.0-180.0)/3
decimalHoursConv(hours: value/60) // (_hrs "1", mins "30")
value = (450.0-179.0)/3
decimalHoursConv(hours: value/60) // (_hrs "1", mins "30")
value = (450.0-175.0)/3
decimalHoursConv(hours: value/60) // (_hrs "1", mins "32")

但仍然 如果你使用的是Swift,你可以 使用 计量

func convertToHoursAndMinutes(_ value: Double) -> DateComponents {
    let unitMeasurement = Measurement(value: value, unit: UnitDuration.minutes)
    let hours = unitMeasurement.converted(to: .hours).value
    let decimalPart = hours.truncatingRemainder(dividingBy: 1)
    let decimalPartMeasurement = Measurement(value: decimalPart, unit: UnitDuration.hours)
    let decimalPartMeasurementInMinutes = decimalPartMeasurement.converted(to: .minutes)
    let minutes = decimalPartMeasurementInMinutes.value.rounded(.toNearestOrEven)
    return DateComponents(hour: Int(hours), minute: Int(minutes))
}

的用法。

var value = (450.0-185.0)/3 // 88.33333333333333
convertToHoursAndMinutes(value) // hour: 1 minute: 28 isLeapMonth: false 
value = (450.0-182.0)/3 // 89.33333333333333
convertToHoursAndMinutes(value) // hour: 1 minute: 29 isLeapMonth: false 
value = (450.0-181.0)/3 // 89.66666666666667
convertToHoursAndMinutes(value) // hour: 1 minute: 30 isLeapMonth: false 
value = (450.0-180.0)/3 // 90
convertToHoursAndMinutes(value) // hour: 1 minute: 30 isLeapMonth: false 
value = (450.0-179.0)/3 // 90.33333333333333
convertToHoursAndMinutes(value) // hour: 1 minute: 30 isLeapMonth: false 
value = (450.0-175.0)/3 // 91.66666666666667
convertToHoursAndMinutes(value) // hour: 1 minute: 32 isLeapMonth: false

请注意,您可以使用元组来代替 DateComponents 如果你喜欢。


1
投票

String 格式化轮次 .

您可以使用 .rounded(.down) 关于 Double的来舍弃它们。(或用其他你需要的规则)

let number = (179.0/60.0) // 2.983333333333333

String(format: "%.0f", number) // returns 3
number.rounded(.up) // returns 3

number.rounded(.down) // returns 2


1
投票

首先,你应该结构化你的数据。其次,如果你不打算显示分数,你不需要将你的值格式化为Double。所以你可以简单地将你的Double转换为整数。


struct FlightPlan {
    let plannedStartFuel: Double
    let minimumLandAllowance: Double
}

extension FlightPlan {
    var mlaTime: (hours: Int, minutes: Int) {
        let hours = (plannedStartFuel - minimumLandAllowance) / 180
        return (Int(hours), Int(modf(hours).1 * 60))
    }
}

而且你应该使用 DateComponentsFormatter 向用户显示时间时。

extension Formatter {
    static let time: DateComponentsFormatter = {
        let formatter = DateComponentsFormatter()
        formatter.calendar?.locale = .init(identifier: "en_US_POSIX")
        formatter.unitsStyle = .brief
        formatter.allowedUnits = [.hour,.minute]
        return formatter
    }()
}

extension FlightPlan {
    var mlaTimeDescrition: String {
        return "Flight Time To MLA = " + Formatter.time.string(from: .init(hour: mlaTime.hours, minute: mlaTime.minutes))!
    }
}

let flightPlan = FlightPlan(plannedStartFuel: 450,
                            minimumLandAllowance: 180)

flightPlan.mlaTime            // (hours 1, minutes 30)
flightPlan.mlaTime.hours      // 1
flightPlan.mlaTime.minutes    // 30
flightPlan.mlaTimeDescrition  // "Flight Time To MLA = 1hr 30min"
© www.soinside.com 2019 - 2024. All rights reserved.