如何将“do-try-catch”控件添加到下面的这个函数中?

How can I add `do-try-catch` control in to this function below?

如何将 do-try-catch 控件添加到下面的这个函数中?

self.convertDateFromString("23282019111259318")

func convertDateFromString(stringDateTimeParameter : String)
{
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "MMddyyyyHHmmssSSS"

    guard let myDate = dateFormatter.date(from: stringDateTimeParameter) else {
    fatalError("ERROR: Date conversion failed due to mismatched format.")}

    print("myDate: \(myDate)")
}

正如您在上面看到的示例。我发送 23 值作为一个月得到一个错误。然后应用程序被设备停止。我需要处理这种情况。应用程序不应停止,我应该在 catch 范围内看到 print(error)。

如何将 do-try-catch 控件添加到此函数中?我写了它,但我没有在 catch 范围内看到打印行。这就是我问的原因。

您不能让日期格式化程序抛出错误,但如果需要,您可以从此方法抛出错误,例如

enum DateConversionError: Error {
    case unableToParseString
}

func dateFromString(stringDateTimeParameter: String) throws -> Date {
    let formatter = DateFormatter()
    formatter.dateFormat = "MMddyyyyHHmmssSSS"
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.timeZone = TimeZone(secondsFromGMT: 0)     // or omit to use your current time zone

    guard let date = formatter.date(from: stringDateTimeParameter) else {
        throw DateConversionError.unableToParseString
    }

    return date
}

然后您可以执行以下操作:

do {
    let date = try dateFromString(stringDateTimeParameter: "23282019111259318")
    print(date)
} catch {
    print(error)
}

话虽这么说,但感觉就像我们在扭曲自己来抛出错误。使用可选值更简单:

func dateFromString(stringDateTimeParameter: String) -> Date? {
    let formatter = DateFormatter()
    formatter.dateFormat = "MMddyyyyHHmmssSSS"
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.timeZone = TimeZone(secondsFromGMT: 0)     // or omit to use your current time zone

    return formatter.date(from: stringDateTimeParameter)
}

guard let date = dateFromString(stringDateTimeParameter: "23282019111259318") else {
    print("unable to parse date")
    return
}

// use `date` here

如果您正在解析网络 API 响应,如果该响应在 JSON 中,我倾向于使用 JSONDecoder 并在 [=20] 中指定格式化程序=]:

let decoder = JSONDecoder()

let formatter = DateFormatter()
formatter.dateFormat = "MMddyyyyHHmmssSSS"
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)

decoder.dateDecodingStrategy = .formatted(formatter)

// use `decoder` to parse your JSON and it will handle conversions/errors for you

这引出了一个问题,为什么您使用 MMddyyyyHHmmssSSS 格式,而不是像 yyyy-MM-dd'T'HH:mm:ss.SSSX 这样的标准格式,但这是一个单独的问题。


最后,创建日期格式化程序是一个昂贵的过程。你真的不希望将它埋在你的 dateFromString 方法中,你可能会多次调用它。实例化格式化程序一次,然后让您的 dateFromString 方法使用已创建的格式化程序。

如果您想使用 do-catch 来处理错误,您需要为您的函数创建一个错误类型来抛出:

struct DateConvertError : Error
{
    let description: String
}

格式化程序不会告诉您为什么它无法解析,所以这没有多大意义,但是您的函数可以标记为 throws:

func convertDateFromString(stringDateTimeParameter : String) throws -> Date
{
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "MMddyyyyHHmmssSSS"

    guard let date = dateFormatter.date(from: stringDateTimeParameter) else {
        throw DateConvertError(description: "Could not parse")
    }

    return date
}

然后当你称呼它时你 do a try:

let date: Date
do {
    date = try convertDateFromString(stringDateTimeParameter: "23282019111259318")
} catch {
    // Handle failure
}