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

时间:2019-03-22 16:37:47

标签: ios swift timezone nstimezone

我正在尝试在Swift中扩展TimeZone,以便可以对其进行初始化以随机给我一个TimeZone。我已经进入了下面的内容,但是有些地方似乎错了。

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

首先,当我初始化一个随机元素并打印结果时,似乎在末尾添加了“(固定)”-请问是什么原因引起的?

第二,这是否是解决此问题的正确方法?我什至会提供使用“ false”进行初始化的选项,这似乎很奇怪,因为其他初始化程序提供了所有其他非随机初始化。

任何想法都将不胜感激!

2 个答案:

答案 0 :(得分:3)

一个解决方案可能是

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

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

Result

您甚至可以更改random计算出的变量以返回非可选值,因为可以确保knownTimeZoneIdentifiers不为空。

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

答案 1 :(得分:0)

时区是棘手的,因为没有确定的标准,即使看起来确实存在。我前段时间遇到了这个问题,并从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

重复项向您展示了这些东西的“标准”程度。您可以根据自己认为正确的内容来整理自己的列表,并从该集合中生成合法的随机数。

Jack回答的问题是Swift中的时区标识符不均匀;基于Swift认为该区域受欢迎的区域,一些区域的代表人数过多,而其他区域的代表人数则不足。例如,即使澳大利亚只有3个时区,澳大利亚也有12个标识符。为了节省时间,您可以随机生成一个介于-12个小时到+14个小时之间的数字(以秒为单位),并使用格林尼治标准时间返回以秒为单位的时区。

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

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

如果您希望整齐地划分时区,只需将它们划分为多个块,然后从该集合中随机选择。只要意识到也有一半和四分之一时区;并非每个时区都与其邻居相差一小时左右。如果您采用这种方法,则数组中的整数将超过24个,这不必担心。