Swift 4:验证信用卡到期日期



我正在编写代码来检查信用卡是否已过期。

这是我所拥有的

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/yyyy"
let enteredDate = dateFormatter.date(from: expiryDate.text!) /* line 3 - set to first day of month */
let now = Date()
if (enteredDate! < now) {
    //expired
    // does not work if current month and year 
    // is the same as the expiration date, 
    // because expiration day is set to the first day of the month on line 3
} else {
    // valid
    print("valid - now: (now) entered: (enteredDate)")
}

关于如何将初始化日期更改为该月的最后一天而不是第一天的任何想法?

enteredDate将是到期日当月第一天的当地时间午夜。由于您希望整个月有效,因此请将 1 个月添加到该值,然后将Date()与该更新的值进行比较。

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/yyyy"
let enteredDate = dateFormatter.date(from: expiryDate.text!)!
let endOfMonth = Calendar.current.date(byAdding: .month, value: 1, to: enteredDate)!
let now = Date()
if (endOfMonth < now) {
    print("Expired - (enteredDate) - (endOfMonth)")
} else {
    // valid
    print("valid - now: (now) entered: (enteredDate)")
}

请注意,我为读者留下了对可选选项的正确处理。

与其比较日期,不如使用 compare(_:to:toGranularity:( 比较日期的月份

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/yyyy"
if let enteredDate = dateFormatter.date(from: "05/2019") {
    let result = Calendar.current.compare(Date(), to: enteredDate, toGranularity: .month)
    if result == .orderedSame {
        print("valid")
    } else if result == .orderedAscending {
        print("valid")
    } else if result == .orderedDescending {
        print("expired")
    }
}

Rmaddy的答案是完美的。以下是我想使用 Calendar 来处理验证的方式。也许,我以更复杂的方式写了它。

enum ExpiryValidation {
    case valid, invalidInput, expired
}
func validateCreditCardExpiry(_ input: String) -> ExpiryValidation {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "MM/yyyy"
    guard let enteredDate = dateFormatter.date(from: input) else {
        return .invalidInput
    }
    let calendar = Calendar.current
    let components = Set([Calendar.Component.month, Calendar.Component.year])
    let currentDateComponents = calendar.dateComponents(components, from: Date())
    let enteredDateComponents = calendar.dateComponents(components, from: enteredDate)
    guard let eMonth = enteredDateComponents.month, let eYear = enteredDateComponents.year, let cMonth = currentDateComponents.month, let cYear = currentDateComponents.year, eMonth >= cMonth, eYear >= cYear else {
        return .expired
    }
    return .valid
}
let invalidInput = validateCreditCardExpiry("hello")
let validInput = validateCreditCardExpiry("09/2020")
let expiredInput = validateCreditCardExpiry("04/2010")
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/yyyy"
let enteredDate = dateFormatter.date(from: expiryDate.text!)
//Also convert the current date in the entered date format and then checks that the date is valid if enteredDate month or year is greater than current date. 
let currentDate = dateFormatter.date(from: dateFormatter.string(from: Date()))
if enteredDate.compare(now) != ComparisonResult.orderedAscending {
    print("Valid")   
} else {
    print("Not Valid")
}

由于这仅比较月份和年份,因此它将解决您每月的第一个或最后一个日期的问题。

这是从

格式化为 MM/YY 的文本字段计算到期日期的完整答案。在文本字段中使用它应该更改字符在范围方法中

var cleanString = string.replacingOccurrences(of: "/", with: "")
    
    if cleanString.rangeOfCharacter(from: unsupportedCharacterSet) != nil {
        return ""
    }
    
    let dateString: String
    
    if cleanString.count == 0 {
        return string
    } else if cleanString.count > 4 {
        // trim the string down to 4
        
        let reqIndex = cleanString.index(cleanString.startIndex, offsetBy: 4)
        cleanString = String(cleanString[..<reqIndex])
        
    }
    
    if cleanString.hasPrefix("0") == false && cleanString.hasPrefix("1") == false {
        dateString = "0" + cleanString
    } else {
        dateString = cleanString
    }
    let currentYear = Calendar.current.component(.year, from: Date()) % 100   // This will give you current year (i.e. if 2019 then it will be 19)
      let currentMonth = Calendar.current.component(.month, from: Date()) // This will give you current month (i.e if June then it will be 6)
    var newText = ""
    for (index, character) in dateString.enumerated() {
        print("index: (index)")
        if index == 1 {
            let enterdMonth = Int(dateString.prefix(2)) ?? 0  // get first two digit from entered string as month
            print("enterdMonth at 1:(enterdMonth)")
            if (1 ... 12).contains(enterdMonth){
                if enterdMonth < 10 {
                    newText = "0" + "(enterdMonth)" + "/"
                }else {
                    newText = "(enterdMonth)" + "/"
                }
            }else{
                
            }
        }else if index == 2 {
            if (2 ... 99).contains(Int(String(character))!) { // Entered year should be greater than 2019.
                newText.append(character)
            }else{
                
            }
        }else if index == 3 {
            print("index---: (index)")
            let enterdYr = Int(dateString.suffix(2)) ?? 0   // get last two digit from entered string as year
            let enterdMonth = Int(dateString.prefix(2)) ?? 0  // get first two digit from entered string as month
            print("enterdYr: (enterdYr)")
            print("currentYear: (currentYear)")
            if (2 ... 99).contains(enterdYr) { // Entered year should be greater than 2019
                if enterdYr >= currentYear {
                    if (1 ... 12).contains(enterdMonth) {
                        if enterdMonth < 10 {
                            newText = "0" + "(enterdMonth)" + "/" + "(enterdYr)"
                        }else {
                            newText = "(enterdMonth)" + "/" + "(enterdYr)"
                        }
                        return newText
                    }
                }
            }
        }
        else {
            newText.append(character)
        }
    }
    return newText
}
if enteredDate.compare(now) == ComparisonResult.orderedDescending
        {
            print("valid")
        }
else{
      print("not valid")
}

最新更新