【问题标题】:Swift- Get current date with different timezones to compare between timesSwift-获取具有不同时区的当前日期以在时间之间进行比较
【发布时间】:2018-04-27 16:09:56
【问题描述】:

我一直在寻找这个,但找不到与我的需求正确对应的解决方案。我需要获取 NSDate 类型的 Date,而不是 String,其中包含特定时区的当前时间,以便稍后进行比较以查看时间是否在范围之间。

例如,我需要查看商店是否营业。我在 EST 时区,现在是晚上 11:30,所以我看到了一家在 11 点关门但商店在 PST 的商店的时间表,这意味着现在该时区是晚上 10 点并且仍然营业。所以我需要将我的时区更改为商店时区,以显示一个标志,如果它现在是打开还是关闭。

这是我尝试过的一个例子:

guard let tz = model?.timeZone else {return "EST"};    
let tz = TimeZone.init(abbreviation: timeZone);
df.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ";
let dateString = df.string(from:Date()); //time is correct
let date = df.date(from: dateString); //ignore timeZone and transform to a different date.

但是当我转换包含正确设置时区的时间的字符串并将其解析回日期类型时,它只是忽略时区并显示不同的时间。 我想我将不得不做一些事情,比如获取时间之间的差异并添加到当前时间,但我不确定如何完成。因为这也是我一直在尝试做的事情:

let localTimeZoneOffset = myTimeZone.secondsFromGMT(for: Date());
let currentTime = Date().addingTimeInterval(TimeInterval(- 
localTimeZoneOffset));

我仍然可以在任何区域,并且我想查看另一个区域的商店是否在不同的时区营业,即设备的当前时间和商店的开闭时间。我的位置可以在任何地方,我也可以选择商店,所以我想我需要获得两次的差异或类似的东西

假设这是我得到的信息:Now = Date();开放时间 = 2018-04-27 11:00:00 +0000;关闭时间 = 2018-04-28 03:00:00 +0000; StoreTimeZone = "EST" 如果我​​在与商店不同时区的地方,是否可以轻松获取商店是否营业?我已经有了比较功能,时间是在 OpenTime 和 CloseTime 之间,我只需要在商店中传递正确的时间来获取它现在是否打开。

提前致谢。

【问题讨论】:

  • 仅供参考 - 避免使用时区缩写。并非所有都是独一无二的(示例包括 IST 和 CST)。
  • @rmaddy 是的,但这就是它来自 API 的方式,我无法更改,但感谢您的建议
  • 日期没有时区。您无法获得包含时区信息的 Date,因为 Date 不依赖或不包含时区。
  • @TomHarrington 在这种情况下,我需要添加该时区的时间差以获得相似的时间,对吧?如何找到我通过的时区的 currentDate UTC 和 currentDate 之间的差异并将其添加到 currentDate?
  • 听起来您需要将 api 中的字符串转换为 Date,然后您可以只比较它而不是尝试比较字符串。

标签: ios swift timezone


【解决方案1】:

这是我的解决方案。我在一个方便的地方为 JSON 添加了一个时区;您需要进行调整以允许数据中的时区位置。

struct Schedule: Codable {
    var timezone: String
    var storeHours: [DayHours]
}

struct DayHours: Codable {
    var hours: String
    var day: String
    var date: String
}


struct OpeningHours {
    let day: String
    let openTime: Date
    let closeTime: Date

    func isOpen(on date: Date) -> Bool {
        return date >= openTime && date < closeTime
    }
}

struct StoreSchedule {
    let openingHours:[OpeningHours]
    let timezone: TimeZone

    init?(_ schedule: Schedule) {
        guard let timezone = TimeZone(abbreviation:schedule.timezone) else {
            return nil
        }

        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd hh:mm a"
        dateFormatter.timeZone = timezone
        self.timezone = timezone
        var openingHours = [OpeningHours]()
        for dayHours in schedule.storeHours {
            let components = dayHours.hours.components(separatedBy: "-")
            guard components.count == 2 else {
                return nil
            }
            let opening = components[0]
            let closing = components[1]
            guard let openTime = dateFormatter.date(from: "\(dayHours.date) \(opening)"),
                let closeTime = dateFormatter.date(from: "\(dayHours.date) \(closing)") else {
                    return nil
            }
            openingHours.append(OpeningHours(day: dayHours.day, openTime: openTime, closeTime: closeTime))
        }

        self.openingHours = openingHours
    }

    func isOpen(on date: Date) -> Bool{
        for openings in openingHours {
            if openings.isOpen(on: date) {
                return true
            }
        }
        return false
    }
}

let json = """
{
"timezone": "PST",
"storeHours": [{
"hours": "7:00 AM - 11:00 PM",
"day": "Friday",
"date": "2018-04-27"
}, {
"hours": "7:00 AM - 11:00 PM",
"day": "Saturday",
"date": "2018-04-28"
}, {
"hours": "7:00 AM - 11:00 PM",
"day": "Sunday",
"date": "2018-04-29"
}, {
"hours": "7:00 AM - 11:00 PM",
"day": "Monday",
"date": "2018-04-30"
}, {
"hours": "7:00 AM - 11:00 PM",
"day": "Tuesday",
"date": "2018-05-01"
}, {
"hours": "7:00 AM - 11:00 PM",
"day": "Wednesday",
"date": "2018-05-02"
}, {
"hours": "7:00 AM - 11:00 PM",
"day": "Thursday",
"date": "2018-05-03"
}]
}
"""

let schedule = try! JSONDecoder().decode(Schedule.self, from: json.data(using: .utf8)!)

if let storeSchedule = StoreSchedule(schedule) {
    //  print(storeSchedule)
    let openClosed = storeSchedule.isOpen(on: Date()) ? "Open":"Closed"
    print("Store is: \(openClosed)")
} else {
    print("Unable to create schedule")
}

商店是:打开

【讨论】:

  • 我认为这行不通,因为我需要使用我们项目中已经实现的内容。假设这是我得到的信息: Now = Date();开放时间 = 2018-04-27 11:00:00 +0000;关闭时间 = 2018-04-28 03:00:00 +0000; StoreTimeZone = "EST" 如果我​​在与商店不同时区的地方,是否可以轻松获取商店是否营业?我已经有了比较的功能是时间在 OpenTime 和 CloseTime 之间我只需要在商店中传递正确的时间来获取它现在是否开放
  • 但是您所描述的几乎就是我的代码所做的。它创建代表开/关时间的Dates,然后查看商店是否在提供的日期开放。创建日期后,无需添加时间间隔或担心时区。如果您想知道商店是否“现在”营业,您不在乎您所在的时区
  • @keylinwu;我还是不明白你的问题是什么。
猜你喜欢
  • 2015-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-14
  • 1970-01-01
  • 2016-07-24
  • 2012-11-22
  • 1970-01-01
相关资源
最近更新 更多