[Swift] TimeZone 覚書

     
⌛️ 4 min.

Swift/Foundation で用意されている TimeZone について改めて確認してみます

環境&対象

以下の環境で動作確認を行なっています。

  • macOS14.3
  • Xcode 15.2
  • iOS 17.2
  • Swift 5.9

TimeZone に関連する用語

TimeZone を説明する前に、関連する用語から説明します。

identifier

個々の TimeZone に割り当てられた ID です。地政学上からの名称です。

具体的には、”Asia/Tokyo” だったり、”America/New_York” だったりです。

abbreviation

英語の “abbreviation” は、日本語にすると “省略形” です。

何を省略したものかというと、その TimeZone の名称です。
例えば、日本であれば、”日本標準時” = “Japan Standard Time” ですが、省略形で “JST” とよく表記されます。

この省略形を指しています。
なお、この abbreviation は、標準化されていないため、abbreviation 自体は、複数の意味を持つことがあり得ます。例えば、”EST” が、アメリカ・オーストラリアでいずれも “Eastern Time” を表す省略形になっています。

MEMO

複数の意味を持つことがあり得るということで “EST” という例が Apple のドキュメントに記載されているのですが、Foundation の TimeZone を “EST” から生成すると、America の TimeZone として生成されます。

UTC offset

協定世界時からの “時差” を UTC offset と呼びます。

UTC は、”Universal Time Coordinated” です。日本語では、”協定世界時” です。
よく聞く”世界標準時” であるグリニッジ標準時とは微妙に違いますが、ここでは説明しません。

実際にも、Foundation 上で UTC と GMT は区別されていないように見えます。

例えば、日本標準時/JST の UTC offset は、”-9″ です。

TimeZone

タイムゾーン を表す TimeZone は、Foundation で定義されています。


参考
TimeZoneApple Developer Documentation

3つの init

TimeZone を生成するために3つの init が用意されています。

いずれも failable initializer であり、init? として定義されています。

MEMO

ここで説明する以外にもう1つ init(from: Decoder) がありますが、説明しません。

init?(identifer:)

TimeZone を identifier (“Asia/Tokyo” 等) から生成する failable initializer です。


参考
init?(identifier:)Apple Developer Documentation

identifier としては、String を与えることができるため、未知の identifier を渡すと nil が返されます。

init?(abbreviation:)

TimeZone を abbreviation (“JST” 等) から生成する failable initializer です。


参考
init?(abbreviation:)Apple Developer Documentation

abbreviation としては、String を与えることができるため、未知の abbreviation を渡すと nil が返されます。

init?(secondsFromGMT:)

TimeZone を UTC offset から生成する failable initializer です。


参考
init?(secondsFromGMT:)Apple Developer Documentation

secondsFromGMT としては、Int を与えることができます。

ドキュメントでは、与えられた値から適切な ZimeZone が生成できないときは nil が返されるとあります。
具体的な値は示されていませんが、少し試すと以下のような動作でした。

let hour12 = 60 * 60 * 12

let plus18 = TimeZone(secondsFromGMT:hour12 + hour12 - 60 * 60 * 6 )
// success to init: GMT+1800

let plus19 = TimeZone(secondsFromGMT:hour12 + hour12 - 60 * 60 * 5 )
// fail to init: GMT+1900

当初、+12を超えると fail するかと思いましたが、境界は、+18 〜 +19 のどこかっぽいです。

TimeZone の理解できる identifier/abbreviation

TimeZone が理解できる(?) identifier や abbreviation は、外部からも確認できるようになっています。

TimeZone の理解できる identifier

TimeZone に static に定義されている knownTimeZoneIdentifiers を使用すると、identifier の一覧を取得できます。


参考
knownTimeZoneIdentifiersApple Developer Documentation

print してみると以下のような出力が得られます。

import Foundation

print(TimeZone.knownTimeZoneIdentifiers)
// print-out
["Africa/Abidjan", "Africa/Accra", "Africa/Addis_Ababa", "Africa/Algiers", "Africa/Asmara", "Africa/Bamako", "Africa/Bangui", "Africa/Banjul", "Africa/Bissau", "Africa/Blantyre", "Africa/Brazzaville", "Africa/Bujumbura", "Africa/Cairo", "Africa/Casablanca", "Africa/Ceuta", "Africa/Conakry", "Africa/Dakar", "Africa/Dar_es_Salaam", "Africa/Djibouti", "Africa/Douala", "Africa/El_Aaiun", "Africa/Freetown", "Africa/Gaborone", "Africa/Harare", "Africa/Johannesburg", "Africa/Juba", "Africa/Kampala", "Africa/Khartoum", "Africa/Kigali", "Africa/Kinshasa", "Africa/Lagos", "Africa/Libreville", "Africa/Lome", "Africa/Luanda", "Africa/Lubumbashi", "Africa/Lusaka", "Africa/Malabo", "Africa/Maputo", "Africa/Maseru", "Africa/Mbabane", "Africa/Mogadishu", "Africa/Monrovia", "Africa/Nairobi", "Africa/Ndjamena", "Africa/Niamey", "Africa/Nouakchott", "Africa/Ouagadougou", "Africa/Porto-Novo", "Africa/Sao_Tome", "Africa/Tripoli", "Africa/Tunis", "Africa/Windhoek", "America/Adak", "America/Anchorage", "America/Anguilla", "America/Antigua", "America/Araguaina", "America/Argentina/Buenos_Aires", "America/Argentina/Catamarca", "America/Argentina/Cordoba", "America/Argentina/Jujuy", "America/Argentina/La_Rioja", "America/Argentina/Mendoza", "America/Argentina/Rio_Gallegos", "America/Argentina/Salta", "America/Argentina/San_Juan", "America/Argentina/San_Luis", "America/Argentina/Tucuman", "America/Argentina/Ushuaia", "America/Aruba", "America/Asuncion", "America/Atikokan", "America/Bahia", "America/Bahia_Banderas", "America/Barbados", "America/Belem", "America/Belize", "America/Blanc-Sablon", "America/Boa_Vista", "America/Bogota", "America/Boise", "America/Cambridge_Bay", "America/Campo_Grande", "America/Cancun", "America/Caracas", "America/Cayenne", "America/Cayman", "America/Chicago", "America/Chihuahua", "America/Ciudad_Juarez", "America/Costa_Rica", "America/Creston", "America/Cuiaba", "America/Curacao", "America/Danmarkshavn", "America/Dawson", "America/Dawson_Creek", "America/Denver", "America/Detroit", "America/Dominica", "America/Edmonton", "America/Eirunepe", "America/El_Salvador", "America/Fort_Nelson", "America/Fortaleza", "America/Glace_Bay", "America/Godthab", "America/Goose_Bay", "America/Grand_Turk", "America/Grenada", "America/Guadeloupe", "America/Guatemala", "America/Guayaquil", "America/Guyana", "America/Halifax", "America/Havana", "America/Hermosillo", "America/Indiana/Indianapolis", "America/Indiana/Knox", "America/Indiana/Marengo", "America/Indiana/Petersburg", "America/Indiana/Tell_City", "America/Indiana/Vevay", "America/Indiana/Vincennes", "America/Indiana/Winamac", "America/Inuvik", "America/Iqaluit", "America/Jamaica", "America/Juneau", "America/Kentucky/Louisville", "America/Kentucky/Monticello", "America/Kralendijk", "America/La_Paz", "America/Lima", "America/Los_Angeles", "America/Lower_Princes", "America/Maceio", "America/Managua", "America/Manaus", "America/Marigot", "America/Martinique", "America/Matamoros", "America/Mazatlan", "America/Menominee", "America/Merida", "America/Metlakatla", "America/Mexico_City", "America/Miquelon", "America/Moncton", "America/Monterrey", "America/Montevideo", "America/Montreal", "America/Montserrat", "America/Nassau", "America/New_York", "America/Nipigon", "America/Nome", "America/Noronha", "America/North_Dakota/Beulah", "America/North_Dakota/Center", "America/North_Dakota/New_Salem", "America/Nuuk", "America/Ojinaga", "America/Panama", "America/Pangnirtung", "America/Paramaribo", "America/Phoenix", "America/Port-au-Prince", "America/Port_of_Spain", "America/Porto_Velho", "America/Puerto_Rico", "America/Punta_Arenas", "America/Rainy_River", "America/Rankin_Inlet", "America/Recife", "America/Regina", "America/Resolute", "America/Rio_Branco", "America/Santa_Isabel", "America/Santarem", "America/Santiago", "America/Santo_Domingo", "America/Sao_Paulo", "America/Scoresbysund", "America/Shiprock", "America/Sitka", "America/St_Barthelemy", "America/St_Johns", "America/St_Kitts", "America/St_Lucia", "America/St_Thomas", "America/St_Vincent", "America/Swift_Current", "America/Tegucigalpa", "America/Thule", "America/Thunder_Bay", "America/Tijuana", "America/Toronto", "America/Tortola", "America/Vancouver", "America/Whitehorse", "America/Winnipeg", "America/Yakutat", "America/Yellowknife", "Antarctica/Casey", "Antarctica/Davis", "Antarctica/DumontDUrville", "Antarctica/Macquarie", "Antarctica/Mawson", "Antarctica/McMurdo", "Antarctica/Palmer", "Antarctica/Rothera", "Antarctica/South_Pole", "Antarctica/Syowa", "Antarctica/Troll", "Antarctica/Vostok", "Arctic/Longyearbyen", "Asia/Aden", "Asia/Almaty", "Asia/Amman", "Asia/Anadyr", "Asia/Aqtau", "Asia/Aqtobe", "Asia/Ashgabat", "Asia/Atyrau", "Asia/Baghdad", "Asia/Bahrain", "Asia/Baku", "Asia/Bangkok", "Asia/Barnaul", "Asia/Beirut", "Asia/Bishkek", "Asia/Brunei", "Asia/Calcutta", "Asia/Chita", "Asia/Choibalsan", "Asia/Chongqing", "Asia/Colombo", "Asia/Damascus", "Asia/Dhaka", "Asia/Dili", "Asia/Dubai", "Asia/Dushanbe", "Asia/Famagusta", "Asia/Gaza", "Asia/Harbin", "Asia/Hebron", "Asia/Ho_Chi_Minh", "Asia/Hong_Kong", "Asia/Hovd", "Asia/Irkutsk", "Asia/Jakarta", "Asia/Jayapura", "Asia/Jerusalem", "Asia/Kabul", "Asia/Kamchatka", "Asia/Karachi", "Asia/Kashgar", "Asia/Kathmandu", "Asia/Katmandu", "Asia/Khandyga", "Asia/Krasnoyarsk", "Asia/Kuala_Lumpur", "Asia/Kuching", "Asia/Kuwait", "Asia/Macau", "Asia/Magadan", "Asia/Makassar", "Asia/Manila", "Asia/Muscat", "Asia/Nicosia", "Asia/Novokuznetsk", "Asia/Novosibirsk", "Asia/Omsk", "Asia/Oral", "Asia/Phnom_Penh", "Asia/Pontianak", "Asia/Pyongyang", "Asia/Qatar", "Asia/Qostanay", "Asia/Qyzylorda", "Asia/Rangoon", "Asia/Riyadh", "Asia/Sakhalin", "Asia/Samarkand", "Asia/Seoul", "Asia/Shanghai", "Asia/Singapore", "Asia/Srednekolymsk", "Asia/Taipei", "Asia/Tashkent", "Asia/Tbilisi", "Asia/Tehran", "Asia/Thimphu", "Asia/Tokyo", "Asia/Tomsk", "Asia/Ulaanbaatar", "Asia/Urumqi", "Asia/Ust-Nera", "Asia/Vientiane", "Asia/Vladivostok", "Asia/Yakutsk", "Asia/Yangon", "Asia/Yekaterinburg", "Asia/Yerevan", "Atlantic/Azores", "Atlantic/Bermuda", "Atlantic/Canary", "Atlantic/Cape_Verde", "Atlantic/Faroe", "Atlantic/Madeira", "Atlantic/Reykjavik", "Atlantic/South_Georgia", "Atlantic/St_Helena", "Atlantic/Stanley", "Australia/Adelaide", "Australia/Brisbane", "Australia/Broken_Hill", "Australia/Currie", "Australia/Darwin", "Australia/Eucla", "Australia/Hobart", "Australia/Lindeman", "Australia/Lord_Howe", "Australia/Melbourne", "Australia/Perth", "Australia/Sydney", "Europe/Amsterdam", "Europe/Andorra", "Europe/Astrakhan", "Europe/Athens", "Europe/Belgrade", "Europe/Berlin", "Europe/Bratislava", "Europe/Brussels", "Europe/Bucharest", "Europe/Budapest", "Europe/Busingen", "Europe/Chisinau", "Europe/Copenhagen", "Europe/Dublin", "Europe/Gibraltar", "Europe/Guernsey", "Europe/Helsinki", "Europe/Isle_of_Man", "Europe/Istanbul", "Europe/Jersey", "Europe/Kaliningrad", "Europe/Kiev", "Europe/Kirov", "Europe/Kyiv", "Europe/Lisbon", "Europe/Ljubljana", "Europe/London", "Europe/Luxembourg", "Europe/Madrid", "Europe/Malta", "Europe/Mariehamn", "Europe/Minsk", "Europe/Monaco", "Europe/Moscow", "Europe/Oslo", "Europe/Paris", "Europe/Podgorica", "Europe/Prague", "Europe/Riga", "Europe/Rome", "Europe/Samara", "Europe/San_Marino", "Europe/Sarajevo", "Europe/Saratov", "Europe/Simferopol", "Europe/Skopje", "Europe/Sofia", "Europe/Stockholm", "Europe/Tallinn", "Europe/Tirane", "Europe/Ulyanovsk", "Europe/Uzhgorod", "Europe/Vaduz", "Europe/Vatican", "Europe/Vienna", "Europe/Vilnius", "Europe/Volgograd", "Europe/Warsaw", "Europe/Zagreb", "Europe/Zaporozhye", "Europe/Zurich", "GMT", "Indian/Antananarivo", "Indian/Chagos", "Indian/Christmas", "Indian/Cocos", "Indian/Comoro", "Indian/Kerguelen", "Indian/Mahe", "Indian/Maldives", "Indian/Mauritius", "Indian/Mayotte", "Indian/Reunion", "Pacific/Apia", "Pacific/Auckland", "Pacific/Bougainville", "Pacific/Chatham", "Pacific/Chuuk", "Pacific/Easter", "Pacific/Efate", "Pacific/Enderbury", "Pacific/Fakaofo", "Pacific/Fiji", "Pacific/Funafuti", "Pacific/Galapagos", "Pacific/Gambier", "Pacific/Guadalcanal", "Pacific/Guam", "Pacific/Honolulu", "Pacific/Johnston", "Pacific/Kanton", "Pacific/Kiritimati", "Pacific/Kosrae", "Pacific/Kwajalein", "Pacific/Majuro", "Pacific/Marquesas", "Pacific/Midway", "Pacific/Nauru", "Pacific/Niue", "Pacific/Norfolk", "Pacific/Noumea", "Pacific/Pago_Pago", "Pacific/Palau", "Pacific/Pitcairn", "Pacific/Pohnpei", "Pacific/Ponape", "Pacific/Port_Moresby", "Pacific/Rarotonga", "Pacific/Saipan", "Pacific/Tahiti", "Pacific/Tarawa", "Pacific/Tongatapu", "Pacific/Truk", "Pacific/Wake", "Pacific/Wallis"]

TimeZone の理解できる abbreviation

TimeZone に static に定義されている abbreviationDictionary を使用すると、abbreviation と 対応する identifier を Dictionary 型で取得することができます。


参考
knownTimeZoneIdentifiersApple Developer Documentation

print してみると 以下のような出力が得られます。

import Foundation

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

knownTimeZoneIdentifiers や abbreviationDictionary は、ユーザーがリストから選択するとき等の選択肢表示にも使用すると便利です。

まとめ

Foundation の提供する TimeZone

Foundation の提供する TimeZone
  • Foundation の TimeZone は、タイムゾーンを表すデータ型
  • TimeZone は、identifier/ abbreviation/ GMT からの差異を指定して生成することができる
  • TimeZone の持つ identifier/abbrevitaion は、knownTimeZoneIdentifiers/ abbreviationDictionary から取得できる

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

SwiftUI おすすめ本

SwiftUI を理解するには、以下の本がおすすめです。

SwiftUI ViewMatery

SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。

英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。

View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。

超便利です

SwiftUIViewsMastery

販売元のページは、こちらです。

SwiftUI 徹底入門

# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。

Swift学習におすすめの本

詳解Swift

Swift の学習には、詳解 Swift という書籍が、おすすめです。

著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。

最新版を購入するのがおすすめです。

現時点では、上記の Swift 5 に対応した第5版が最新版です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です