将eBay timeLeft转换为Swift 3.0 TimeInterval

时间:2017-03-19 13:33:32

标签: ios swift3 ebay-api dateinterval

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

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

来自易趣参考:

searchResult.item.sellingStatus.timeLeft    

上市结束前的剩余时间。持续时间以ISO 8601持续时间格式(PnYnMnDTnHnMnS)表示。对于已结束的商品,剩余时间为PT0S(零秒)。查看"持续时间"输入有关此时间格式的信息。

P10DT4H38M16S

这样eBay Time Left Format:

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,以便我可以使用变量类型的本机函数?

1 个答案:

答案 0 :(得分:1)

我认为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)
}