如何正确扩展 Swift 中的 TimeZone 以初始化随机元素?

How to correctly extend TimeZone in Swift to initialize a random element?

我正在尝试扩展 Swift 中的 TimeZone,以便我可以初始化它以随机给我一个 TimeZone。我已经降落在下面,但有几处似乎是错误的。

   init?(random: Bool = false) {
    if random {
        let randomIdentifier = TimeZone.knownTimeZoneIdentifiers.randomElement()!
        self.init(identifier: String(randomIdentifier))
    } else {
        return nil
    }
}

首先,当我初始化一个随机元素并打印结果时,它似乎在末尾添加了“(fixed)”——请问这是什么原因造成的?

其次,这是解决这个问题的正确方法吗?我什至给出了使用 'false' 进行初始化的选项,这似乎很奇怪,因为其他初始化器提供了所有其他非随机初始化。

如有任何想法,我们将不胜感激!

一个解决方案可能是

extension TimeZone {
    static var random: TimeZone? {
        return TimeZone(identifier: TimeZone.knownTimeZoneIdentifiers.randomElement()!)
    }
}

let random = TimeZone.random
random?.identifier // the name you're looking for

您甚至可以将 random 计算变量更改为 return 非可选变量,因为您可以确定 knownTimeZoneIdentifiers 不为空。

static var random: TimeZone {
    return TimeZone(identifier: TimeZone.knownTimeZoneIdentifiers.randomElement()!)!
}

时区很棘手,因为没有明确的标准,即使看起来有。我不久前遇到了这个问题,并从 Swift 库中生成了这个列表:

"HST": "Pacific/Honolulu", -10
"AKST": "America/Juneau", -9
"AKDT": "America/Juneau", -9
"PDT": "America/Los_Angeles", -8
"PST": "America/Los_Angeles", -8
"MST": "America/Phoenix", -7
"MDT": "America/Denver", -7
"CDT": "America/Chicago", -6
"CST": "America/Chicago", -6
"PET": "America/Lima", -5
"COT": "America/Bogota", -5
"EDT": "America/New_York", -5
"EST": "America/New_York", -5
"AST": "America/Halifax", -4
"ADT": "America/Halifax", -4
"NST": "America/St_Johns", -330
"NDT": "America/St_Johns", -330
"CLST": "America/Santiago", -3
"ART": "America/Argentina/Buenos_Aires", -3
"CLT": "America/Santiago", -3
"BRT": "America/Sao_Paulo", -2
"BRST": "America/Sao_Paulo", -2
"GMT": "GMT", 0
"UTC": "UTC", 0
"WET": "Europe/Lisbon", 0
"BST": "Europe/London", 0
"WEST": "Europe/Lisbon", 0
"CEST": "Europe/Paris", +1
"CET": "Europe/Paris", +1
"WAT": "Africa/Lagos", +1
"EEST": "Europe/Athens", +2
"CAT": "Africa/Harare", +2
"EET": "Europe/Athens", +2
"MSK": "Europe/Moscow", +3
"MSD": "Europe/Moscow", +3
"TRT": "Europe/Istanbul", +3
"EAT": "Africa/Addis_Ababa", +3
"IRST": "Asia/Tehran", +330
"GST": "Asia/Dubai", +4
"PKT": "Asia/Karachi", +5
"IST": "Asia/Kolkata", +530
"BDT": "Asia/Dhaka", +6
"ICT": "Asia/Bangkok", +7
"WIT": "Asia/Jakarta", +7
"SGT": "Asia/Singapore", +8
"PHT": "Asia/Manila", +8
"HKT": "Asia/Hong_Kong", +8
"KST": "Asia/Seoul", +9
"JST": "Asia/Tokyo”, +9
"NZDT": "Pacific/Auckland", +13
"NZST": "Pacific/Auckland", +13

重复项向您展示了 "standard" 这东西是怎样的。您可以根据您认为正确的内容来策划您自己的列表,并从该集合中生成合法的随机发生器。

杰克回答的问题是 Swift 中的时区标识符不均匀;根据 Swift 认为该区域中有多少区域受欢迎,一些区域的人数过多,而另一些区域的人数不足。例如,澳大利亚有 12 个标识符,尽管该国家/地区只有 3 个时区。为了节省时间,您可以随机生成一个介于 -12 小时和 +14 小时之间的秒数和 return 使用 GMT 秒数的时区。

extension TimeZone {
    static var random: TimeZone? {
        return TimeZone(secondsFromGMT: Int.random(in: -43200...50400))
    }
}

if let t = TimeZone.random {
    print(t)
}

如果您想要整齐地划分时区,只需将它们分成块,然后从该组中随机 select。只要意识到也有半时区和四分之一时区;并非每个时区都与邻近时区相差正负 1 小时。如果您采用这种方法,您的数组将有超过 24 个整数,您不必担心。