用Swift 4计算时差

用Swift 4计算时差,swift,Swift,如果我有两个变量,“10:30”和另一个变量“1:20”,有没有办法得到它们之间的时间差“2小时50分钟”??我在下面试过这个 func calcTime(time1: String,time2: String) -> String { let time12 = (String(format: "%02d", time1)) let time22 = (String(format: "%02d", time2)) let time10 = time12.prefi

如果我有两个变量,“10:30”和另一个变量“1:20”,有没有办法得到它们之间的时间差“2小时50分钟”??我在下面试过这个

func calcTime(time1: String,time2: String) -> String {
    let time12 = (String(format: "%02d", time1))
    let time22 = (String(format: "%02d", time2))

    let time10 = time12.prefix(2)
    let time20 = time22.prefix(2)

    print("hours: \(time12)")
    print("minutes: \(time22)")

    let time11 = time1.suffix(2)
    let time21 = time2.suffix(2)

    var hours = 12 - Int(time10)! + Int(time20)!
    var minutes = Int(time11)! + Int(time21)!

    if minutes > 60 {
        hours += 1
        minutes -= 60
    }

    let newHours = (String(format: "%02d", hours))
    let newMin = (String(format: "%02d", minutes))

   return "\(newHours)hrs. \(newMin)min."
}

这不是我想要的方式

让我们看看您的一些代码,看看它会产生什么奇怪的结果:

let time12 = (String(format: "%02d", time1))
这一行毫无意义,格式
%02d
表示要格式化的值(转换为
字符串
表示)是一个整数,并且转换应为两位数宽,前导为零。但是,您的参数,
time1
是一个
字符串
值,而不是整数

不幸的是,斯威夫特并没有向你指出这个错误,相反,它只会咬人。由于
字符串(格式:…)
的工作方式–它需要可变数量的参数–Swift通常的类型检查被放弃,您得到的是
time1
的机器地址的十进制表示(可能是部分)。在操场上多次运行你的代码,你会得到不同的答案

所以在使用
字符串(格式:…)
时要非常小心

这里不清楚您试图用上面的行做什么,您有一个
字符串
值并希望从中提取两个整数值,那么为什么要从生成
字符串开始(
让time12=String(…time1…

跳过混淆哪个变量(
time12
time1
)包含您的
字符串
,此处假设字符串的格式完全相同;但是您的一个测试字符串是
“1:20”
,因此即使这些语句引用了正确的变量,在这种情况下,您最终也会得到
“1:
“20”

要将字符串拆分为两部分,可以使用
String
split(分隔符:maxplits:ommittingemptysubsequences:)
函数,请查看文档以了解其完整描述。你可以在这里写:

let time1parts = time1.split(separator: ":", omittingEmptySubsequences:false)
let time2parts = time2.split(separator: ":", omittingEmptySubsequences:false)

print("\(time1) -> \(time1parts)")
print("\(time2) -> \(time2parts)")
对于您的两个测试字符串,这将输出:

10:30 -> ["10", "30"]
1:20 -> ["1", "20"]
现在,您应该检查每个数组(
time1parts
time2parts
)是否正好有两个元素,作为练习

完成后,您可以将元素转换为无符号整数(以防有人键入减号)。例如:

这将产生:

Optional(10) | Optional(30)
现在,您需要检查可选(
Uint?
)值是否为
nil
,每个值是否在正确的范围内(例如,0到59分钟,
范围
类型及其方法
包含()
可能有助于您进行计算)

注意:你确实有一个问题,你假设
1:20
是下午,你需要解决这个问题,你的数学永远不会正确。可能使用24小时制(
13:20


如果你在前进中遇到困难,问一个新问题,展示你开发的代码并解释你的问题,毫无疑问会有人帮助你。

首先,你的数学是错误的。10:30->1:20实际上是2小时50分钟。秒,您需要指定AM或PM,或者使用24小时(军事风格)时钟。最后,解决方案是使用
DateFormatter
将字符串转换为
Date
值,并使用这些值获取时差,然后将其转换为小时/分钟

    let time1 = "10:30AM"
    let time2 = "1:20PM"

    let formatter = DateFormatter()
    formatter.dateFormat = "h:mma"

    let date1 = formatter.date(from: time1)!
    let date2 = formatter.date(from: time2)!

    let elapsedTime = date2.timeIntervalSince(date1)

    // convert from seconds to hours, rounding down to the nearest hour
    let hours = floor(elapsedTime / 60 / 60)

    // we have to subtract the number of seconds in hours from minutes to get
    // the remaining minutes, rounding down to the nearest minute (in case you
    // want to get seconds down the road)
    let minutes = floor((elapsedTime - (hours * 60 * 60)) / 60)

    print("\(Int(hours)) hr and \(Int(minutes)) min")

我要做的是将它们转换为时间间隔,然后从另一个时间间隔中减去,然后将差值转换为字符串格式。实际上,差值是2小时50分钟。谢谢你的帮助。我昨天想出了一个办法,但花了我120行代码。这更简单,也没有那么大。如何获得秒数,我想显示mm:ss.let seconds=floor((elapsedTime-(minutes*60)))我尝试了这一点,但这一行让date1=formatter.date(from:time1)!通过零值异常
Optional(10) | Optional(30)
    let time1 = "10:30AM"
    let time2 = "1:20PM"

    let formatter = DateFormatter()
    formatter.dateFormat = "h:mma"

    let date1 = formatter.date(from: time1)!
    let date2 = formatter.date(from: time2)!

    let elapsedTime = date2.timeIntervalSince(date1)

    // convert from seconds to hours, rounding down to the nearest hour
    let hours = floor(elapsedTime / 60 / 60)

    // we have to subtract the number of seconds in hours from minutes to get
    // the remaining minutes, rounding down to the nearest minute (in case you
    // want to get seconds down the road)
    let minutes = floor((elapsedTime - (hours * 60 * 60)) / 60)

    print("\(Int(hours)) hr and \(Int(minutes)) min")