#60 iOS Clock 習作-模仿製作 iOS 內建的 Clock App-1-世界時鐘

專注了大選動態一下,現在大選結束了,再回來認真寫作業。這個專案程式主要是修改『Kyle-#27 模仿 iOS Clock App — 1 :World Clock』。在日期判斷參考『Min-①⓪⑥ 世界時鐘

新增的功能:

  • 城巿時間列表及新增城巿列表,增加了中文城巿名稱的顯示,有中英文對照比較易懂。
  • 點擊中文城巿名稱,可以查看wiki的說明,也方便了解一下城巿的知識。
  • 日期如果不是今天,會有灰色背景強調

操作影片

螢幕截圖

城巿時間列表、新增:可選的城巿列表-分類、編輯模式(移動、刪除)

可選的城巿列表-過濾、左滑刪除、點擊城巿可以查看 wiki

作業說明及參考專案

作業的說明,研究時區知識及這3位同學的 APP,『Min-①⓪⑥ 世界時鐘』、『Kyle-iOS Clock — iOS的里程碑專案』『Kyle-#27 模仿 iOS Clock App — 1 :World Clock』、『Patty-世界時鐘 World Clock

時區相關知識

wiki-時區

國際換日線 (+12|-12)

國際換日線(英語:International Date Line),又名國際日界線國際日期變更線國際日期線,這條子午線由於穿越陸地,而在陸地變更日期既不方便也不可行,故實際使用的國際換日線是一條基本上只經過太平洋表面的折線(見附圖)。

原理是從零度經線所在時區向東每跨1個區間時鐘就撥快1小時,而向西每跨1個區間時鐘就撥慢1小時,如此一來,到了另一端經線180度附近,就會有24小時的落差。為解決日期紊亂問題,大致上以180度經線作為換日線;由於照顧行政區域的統一,因此換日線並不完全沿180°的子午線劃分,而是繞過一些島嶼和海峽:由北往南通過白令海峽阿留申群島薩摩亞斐濟東加等島嶼到達紐西蘭的東邊。

時區表示法

協調世界時

如果時間是以協調世界時(UTC)表示,則在時間後面直接加上一個「Z」(不加空格)。「Z」是協調世界時中0時區的標誌。因此,「09:30 UTC」就寫作「09:30Z」或是「0930Z」。「14:45:15 UTC」則為「14:45:15Z」或「144515Z」。UTC時間也被叫做祖魯時間,因為在北約音標字母中用「Zulu」表示「Z」。

import Foundation

// 獲取所有已知時區的標識符
let knownTimeZones = TimeZone.knownTimeZoneIdentifiers

// 創建一個 DateFormatter 實例
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm:ss"

// 遍歷每個已知時區
for timeZoneIdentifier in knownTimeZones {
if let timeZone = TimeZone(identifier: timeZoneIdentifier) {
// 設定時區
dateFormatter.timeZone = timeZone

// 取得當前時間
let currentDate = Date()

// 格式化時間,並在後面加上 "Z"
let utcTimeString = dateFormatter.string(from: currentDate) + "Z"

// 輸出時區標識符及其對應的協調世界時表示
print("\(timeZoneIdentifier): \(utcTimeString)")
}
}
Africa/Abidjan: 23:12:55Z
...
America/Araguaina: 20:12:55Z
America/Argentina/Buenos_Aires: 20:12:55Z
...
Antarctica/Casey: 10:12:55Z
...
Asia/Taipei: 07:12:55Z
...
Atlantic/Azores: 22:12:55Z
...
Australia/Adelaide: 09:42:55Z
...
Europe/Amsterdam: 00:12:55Z
...
GMT: 23:12:55Z
Indian/Antananarivo: 02:12:55Z
...
Pacific/Apia: 12:12:55Z
...

UTC偏移量

UTC偏移量用以下形式表示:±[hh]:[mm]、±[hh][mm]、或者±[hh]。如果所在區時比協調世界時早1個小時(例如柏林冬季時間),那麼時區標識應為「+01:00」、「+0100」或者直接寫作「+01」。這也同上面的「Z」一樣直接加在時間後面。“UTC+8”表示當協調世界時(UTC)時間為凌晨2點的時候,當地的時間為2+8點,即早上10點。

import Foundation

// 獲取所有已知時區的標識符
let knownTimeZones = TimeZone.knownTimeZoneIdentifiers //["Africa/Abidjan", "Africa/Accra", "Africa/Addis_Ababa", ...]

// 遍歷每個已知時區
for timeZoneIdentifier in knownTimeZones {
// 嘗試使用標識符創建 TimeZone 實例
if let timeZone = TimeZone(identifier: timeZoneIdentifier) {
// 取得時區相對於協調世界時的偏移秒數
let offsetSeconds = timeZone.secondsFromGMT()

// 計算小時部分
let hours = offsetSeconds / 3600

// 計算分鐘部分
let minutes = (offsetSeconds % 3600) / 60

// 將小時和分鐘轉換為指定格式的字串
var offsetString = String(format: "%+.2d:%.2d", hours, minutes)

// 如果分鐘為零,僅顯示小時的部分
if minutes == 0 {
offsetString = String(format: "%+.2d", hours)
}

// 輸出時區標識符及其對應的 UTC 偏移量
print("\(timeZoneIdentifier): \(offsetString)")
}
}

縮寫

時區通常都用字母縮寫形式來表示,例如「EST、WST、CST」等。但是它們並不是ISO 8601標準的一部分,不應單獨用它們作為時區的標識。一些縮寫可能意義模糊,例如「BST」應當是英國夏令時,但在1968年到1971年間被重命名為「英國標準時」,這只是因為立法者不願稱其為中歐時間。在該法案中還確認英國的標準時間仍然為格林威治標準時

import UIKit
print("Time Zone Abbreviation: Time Zone Identifier\n")
print(TimeZone.abbreviationDictionary.map { "\($0): \($1)" }.sorted().joined(separator: "\n"))

參考: List all iOS timezones

參考:#157 用表格顯示世界的時間,國家和語言

提示: 世界的時間

  • TimeZone.knownTimeZoneIdentifiers 可取得世界時區的 id array,比方 Asia/Taipei & Europe/London。
  • 利用 TimeZone.knownTimeZoneIdentifiers 裡的 id 可取得城市名,比方 Asia/Taipei 的 Taipei。
for knownTimeZoneIdentifier in TimeZone.knownTimeZoneIdentifiers {
print(String(knownTimeZoneIdentifier.split(separator: "/").last!).replacingOccurrences(of: "_", with: " "))
}

/*
Abidjan
Accra
Addis Ababa
Algiers
Asmara
Bamako
Bangui
...
*/
  • 利用 TimeZone.knownTimeZoneIdentifiers 裡的 id 可產生 TimeZone,例如以下例子:

參考:SwiftTimeZones.playground

//: Playground - noun: a place where people can play

import UIKit

print("Time Zone Abbreviation: Time Zone Identifier\n")
print(TimeZone.abbreviationDictionary.map { "\($0): \($1)" }.sorted().joined(separator: "\n"))
print("\n\nKnown Time Zone Identifiers:\n")
print(TimeZone.knownTimeZoneIdentifiers.joined(separator: "\n"))

let utc = TimeZone(identifier: "UTC")!
print("\n\nWith identifier UTC: \(utc)")

let gmt = TimeZone(secondsFromGMT: 0)!
print("With seconds from GMT = 0: \(gmt)")

let gmt2 = TimeZone(identifier: "GMT")!
print("With identifier GMT: \(gmt2)")

let london = TimeZone(identifier: "Europe/London")!
print("With identifier Europe/London: \(london)")

研究程式碼:

print(TimeZone.knownTimeZoneIdentifiers)
print(TimeZone.knownTimeZoneIdentifiers.joined(separator: "\n"))

.joined 是一個 Swift 中的方法,它用於將序列(如陣列)中的元素連接在一起,形成一個單一的字串。在這個程式碼中,使用了 TimeZone.knownTimeZoneIdentifiers 這個屬性,它返回一個包含所有已知時區標識符的陣列。接著使用 .joined(separator: "\n") 這個方法,將這個陣列中的元素以換行符 "\n" 連接在一起,形成一個字串。

換句話說,這段程式碼的目的是將所有已知時區的標識符以換行符分隔,合併成一個包含所有時區標識符的字串。這樣的字串可能在調試或顯示所有時區時很有用。

中英城巿名轉換

如果想把城巿名轉成中文,好像沒有直接可以使用的API,要自己做一個映射表,將城市名稱轉換為繁體中文,這個把英文名稱交給 ChatGPT 去翻譯一下就好,感謝 ChatGPT。

// 映射表,將城市名稱轉換為繁體中文
let cityMapping: [String: String] = [
"Abidjan": "阿必尚",
"Accra": "阿克拉",
"Addis Ababa": "亞的斯亞貝巴",
"Algiers": "阿爾及爾",
// ... 其他城市 ...
]

之後也許可以加個城巿的背景圖,如果有適合的 api

城巿照片api

Get Image https://api.teleport.org/api/urban_areas/slug:taipei/images/

/urban_areas/{ua_id}/images/

"image":{
"mobile":"https://d13k13wj6adfdf.cloudfront.net/urban_areas/taipei-f36fb8cb4f.jpg",
"web":"https://d13k13wj6adfdf.cloudfront.net/urban_areas/taipei_web-f5a4807f35.jpg"
}

參考:https://www.timeanddate.com/worldclock/

var timeZoneAbbreviations: [String:String] { return TimeZone.abbreviationDictionary }
timeZoneAbbreviations // ["CEST": "Europe/Paris", "WEST": "Europe/Lisbon", "CDT": "America/Chicago", "EET": "Europe/Istanbul", "BRST": "America/Sao_Paulo", "EEST": "Europe/Istanbul", "CET": "Europe/Paris", "MSD": "Europe/Moscow", "MST": "America/Denver", "KST": "Asia/Seoul", "PET": "America/Lima", "NZDT": "Pacific/Auckland", "CLT": "America/Santiago", "HST": "Pacific/Honolulu", "MDT": "America/Denver", "NZST": "Pacific/Auckland", "COT": "America/Bogota", "CST": "America/Chicago", "SGT": "Asia/Singapore", "CAT": "Africa/Harare", "BRT": "America/Sao_Paulo", "WET": "Europe/Lisbon", "IST": "Asia/Calcutta", "HKT": "Asia/Hong_Kong", "GST": "Asia/Dubai", "EDT": "America/New_York", "WIT": "Asia/Jakarta", "UTC": "UTC", "JST": "Asia/Tokyo", "IRST": "Asia/Tehran", "PHT": "Asia/Manila", "AKDT": "America/Juneau", "BST": "Europe/London", "PST": "America/Los_Angeles", "ART": "America/Argentina/Buenos_Aires", "PDT": "America/Los_Angeles", "WAT": "Africa/Lagos", "EST": "America/New_York", "BDT": "Asia/Dhaka", "CLST": "America/Santiago", "AKST": "America/Juneau", "ADT": "America/Halifax", "AST": "America/Halifax", "PKT": "Asia/Karachi", "GMT": "GMT", "ICT": "Asia/Bangkok", "MSK": "Europe/Moscow", "EAT": "Africa/Addis_Ababa"]

--

--