Вычислить разницу времени в Свифте 4 - PullRequest
0 голосов
/ 26 июня 2018

Если у меня есть две переменные, «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."
}

Это на самом деле не работает так, как я хочу.

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Во-первых, ваша математика неверна.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")
0 голосов
/ 26 июня 2018

Давайте посмотрим на некоторый ваш код и посмотрим, что он дает странные результаты:

let time12 = (String(format: "%02d", time1))

Эта строка не имеет смысла, формат %02d говорит о значении, которое нужно отформатировать (преобразовать в String представление) является целым числом, и преобразование должно быть шириной 2 цифры с начальным нулем.Однако ваш аргумент time1 - это значение String, а не целое число.

К сожалению, Swift не указывает вам на эту ошибку, скорее он просто кусается.Из-за того, как работает String(format:...) - он принимает переменное число аргументов - обычная проверка типов в Swift отменена, и то, что вы получаете, является десятичным представлением (возможно, частью) машинного адреса time1.Запустите свой код несколько раз на игровой площадке, и вы получите разные ответы!

Так что будьте очень осторожными при использовании String(format:...).

Здесь неясно, кто выпытаясь сделать с этой строкой, у вас есть значение String и вы хотите извлечь из него два целочисленных значения, так зачем начинать с производства String (let time12 = String(...time1...))?

let time10 = time12.prefix(2)
let time11 = time1.suffix(2)

Пропусксмешивая, какая переменная (time12, time1) содержит ваш String здесь вы предполагаете, что строка точно соответствует формату;но одна из ваших тестовых строк - "1:20", поэтому даже если эти операторы ссылаются на правильные переменные, в этом случае вы получите "1:" и "20".

Что вы можете сделать, чтобы разделитьСтроки в две части использовать функцию String split(separator:maxSplits:omittingEmptySubsequences:), проверьте документацию для ее полного описания.Здесь вы можете написать:

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) имеет точнодва элемента, которые оставлены в качестве упражнения.

Сделав это, вы можете преобразовать элементы в целые числа без знака (на тот случай, если кто-то введет знак минуса).Например:

let hours1 = UInt(time1parts[0])
let minutes1 = UInt(time1parts[1])

print("\(String(describing: hours1)) | \(String(describing: minutes1))")

Это выводит:

Optional(10) | Optional(30)

Теперь вам нужно проверить, что необязательные (Uint?) значения не равны nil, что каждое значение находится в правильном диапазоне(например, от 0 до 59 в течение нескольких минут, тип Range и его метод contains() могут помочь вам в этом) и сделайте свою математику.

Примечание: у вас есть проблема в том, что вы предполагаете 1:20Это PM, вам нужно обратиться к этому, ваша математика никогда не будет правильной.Может быть, использовать 24-часовые часы (13:20)?

Если вы застряли дальше, задайте новый вопрос, показывающий разработанный вами код, и объясните свою проблему, кто-то, несомненно, поможет вам в этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...