我正在尝试将eBay timeLeft转换为TimeInterval。 timeLeft值从eBay返回为。显然,该值为ISO 8601(请参见下面的链接和问题)。我相信timeLeft是相对于我进行API调用的时间间隔。

http://developer.ebay.com/Devzone/finding/CallRef/findItemsByKeywords.html

从eBay参考:

searchResult.item.sellingStatus.timeLeft

列表结束前剩余的时间。持续时间以ISO 8601持续时间格式(PnYnMnDTnHnMnS)表示。对于已结束的列表,剩余时间为PT0S(零秒)。有关此时间格式的信息,请参见“持续时间”类型。
P10DT4H38M16S

这样的eBay时间剩余格式:
P   = Pending (INDICATOR OF ISO8601 DURATION)
1Y  = 1 Year
2M  = 2 Months
2D  = Two Days
T   = Time Separator (M is ambiguous)
16H = Sixteen hours
2M  = Two minutes
40S = Forty seconds

我可以按如下所示格式化字符串,但是此解决方案并未根据剩余时间的属性为我提供能力处理。例如。如果天数为0,我不想显示“0天”。
Ebay API ISO 8601 Date to timestamp

我的具体问题是,有没有一种方法可以将此timeLeft转换为快速的3.0 DateInterval,以便可以使用变量类型的本机函数?

最佳答案

我认为eBay在使用工期字段方面犯了一个错误。它应该说明拍卖的开始和结束日期,以简化事情。日期计算很难。我还没有阅读完整的API文档,但是我的脑海中浮现出一点:

  • eBay使用什么日历?阳历,中文,波斯语,佛教徒?所有的日期,月份和年份都有不同的概念。
  • 一个月可以持续28到31天。一年可以是365或366天。您如何计算持续时间代表多少秒?

  • 话虽如此,以下是ISO 8601持续时间字符串的可能解析器:
    struct ISO8601Duration {
        var years = 0
        var months = 0
        var weeks = 0
        var days = 0
        var hours = 0
        var minutes = 0
        var seconds = 0
    
        init?(string: String) {
            guard string.hasPrefix("P") else {
                return nil
            }
    
            let regex = try! NSRegularExpression(pattern: "(\\d+)(Y|M|W|D|H|S)|(T)", options: [])
            let matches = regex.matches(in: string, options: [], range: NSMakeRange(0, string.utf16.count))
            guard matches.count > 0 else {
                return nil
            }
    
            var isTime = false
            let nsstr = string as NSString
            for m in matches {
                if nsstr.substring(with: m.range) == "T" {
                    isTime = true
                    continue
                }
    
                guard let value = Int(nsstr.substring(with: m.rangeAt(1))) else {
                    return nil
                }
                let timeUnit = nsstr.substring(with: m.rangeAt(2))
    
                switch timeUnit {
                case "Y":
                    self.years = value
                case "M":
                    if !isTime {
                        self.months = value
                    } else {
                        self.minutes = value
                    }
                case "W":
                    self.weeks = value
                case "D":
                    self.days = value
                case "H":
                    self.hours = value
                case "S":
                    self.seconds = value
                default:
                    return nil
                }
            }
        }
    
        func endDate(from date: Date = Date()) -> Date? {
            var components = DateComponents()
            components.year = self.years
            components.month = self.months
            components.day = self.weeks * 7 + self.days
            components.hour = self.hours
            components.minute = self.minutes
            components.second = self.seconds
    
            return Calendar(identifier: .gregorian).date(byAdding: components, to: date)
        }
    }
    
    let timeLeft = "P1DT13H24M17S"
    if let duration = ISO8601Duration(string: timeLeft),
        let endDate = duration.endDate()
    {
        print(endDate)
    }
    

    关于ios - 将eBay timeLeft转换为Swift 3.0 TimeInterval,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42887207/

    10-12 15:11