Swift 日付操作まとめ集(Date)
こんにちはしまーです。今回は、実際に実務で多様しているDate操作をまとめて紹介していきたいと思います。
コピペで使用するなどで作業効率アップにつなげていただければと思ってます。
Swift のDateとは
Swiftで日付操作はDateを使用して扱います。
Dateは協定世界時(UTC)で扱われます。
iPhoneなどで時刻表示する場合UTC→時間帯(TimeZone)変換し表示します
日本の場合はUTC時刻+9時間となります。
それでは Dateによる日付操作でできる事を順に紹介していきます。
- 1. Swift のDateとは
- 2. Date 作成・取得
- 2.1. 現在の日時を取得する
- 2.2. 特定の日時のDateを作成
- 2.3. 日時の切捨て
- 3. 日時の比較
- 4. 日時の加算・減算
- 4.1. 加算
- 4.2. 減算
- 5. 型変換
- 5.1. Date → String(Dateから文字列Stringへ変換)
- 5.1.1. 現在の時刻を文字列に変換
- 5.1.2. 表現変更
- 5.1.2.1. 歴
- 5.1.2.2. Locale変更
- 5.1.3. 相対的日にち(今日、昨日、一昨日)
- 5.1.4. 期間表示
- 5.1.5. ISO86001形式
- 5.1.6. ちょいカスタム書式
- 5.1.7. カスタム書式
- 5.2. String → Date(文字列StringからDateへ変換)
- 5.3. Locale
- 6. 最後に
Date 作成・取得
現在の日時を取得する
let date = Date()
print(date) // 2023-04-06 21:07:18 +0000
特定の日時のDateを作成
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone(identifier: "Asia/Tokyo") ?? TimeZone.gmt
if let date = calendar.date(
from: DateComponents(
year: 2023,
month: 4,
day: 15,
hour: 9,
minute: 0,
second: 0)) {
print(date) // 2023-04-15 00:00:00 +0000
}
DataComponentsへ渡す日時はTimeZoneで指定した日本時間("Asia/Tokyo")として考慮され世界協定時刻(UTC)へ変換されDateデータが作成される。
日時の切捨て
let calendar = Calendar(identifier: .gregorian)
let date = Date()
// 分・秒切り捨て
let componentsHour = calendar.dateComponents([.year, .month, .day, .hour], from: date)
// 秒切り捨て
let componentsMinute = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: date)
if let hourDate = calendar.date(from: componentsHour),
let minuteData = calendar.date(from: componentsMinute) {
print("date:\(date)") // date:2023-04-08 21:32:34 +0000
print("hourDate:\(hourDate)") // hourDate:2023-04-08 21:00:00 +0000
print("minuteData:\(minuteData)") // minuteData:2023-04-08 21:32:00 +0000
}
日時の比較
let now = Date()
let limit = calendar.date(
from: DateComponents(
year: 2023,
month: 4,
day: 10,
hour: 7,
minute: 0,
second: 0))
let isLimit = now < limit!
print(" now:\(now)\n limit: \(limit!)\n isLimit: \(isLimit)")
/*
now:2023-04-08 22:09:55 +0000
limit: 2023-04-09 22:00:00 +0000
isLimit: true
*/
日時の加算・減算
加算
現在の時刻に加算
// 加算する時間(秒)
let addSec: Double = (60 * 60 * 25) + 60 + 1 // 1日1時間1分1秒 加算
// 現在の日時に指定時間(addSec)加算
let addDateNow = Date(timeIntervalSinceNow: addSec)
// 1970年1月1日 0時0分0秒に指定時間(addSec)加算
let addDate1970 = Date(timeIntervalSince1970: addSec)
// 2001年1月1日 0時0分0秒に指定時間(addSec)加算
let addDateReferenceDate = Date(timeIntervalSinceReferenceDate: addSec)
// 現在の日時
let now = Date()
print(now) // 2023-04-10 21:12:07 +0000
print(addDateNow) // 2023-04-11 22:13:08 +0000
print(addDate1970) // 1970-01-02 01:01:01 +0000
print(addDateReferenceDate) // 2001-01-02 01:01:01 +0000
減算
特定の時刻に減算(加算の処理と同じで時間をマイナス(秒)にするだけ
var date = Date()
let newDate = date.addingTimeInterval(-10)
print("now: \(date), addDate:\(newDate)")
// now: 2023-04-07 20:17:38 +0000, addDate:2023-04-07 20:17:48 +0000
型変換
Date → String(Dateから文字列Stringへ変換)
Dateから文字列への変換はDateFormatterを使用して変換します。
現在の時刻を文字列に変換
let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.calendar = Calendar(identifier: .gregorian)
dateFormatter.locale = Locale(identifier: "ja_JP")
dateFormatter.dateStyle = .full
dateFormatter.timeStyle = .full
let formattedDate = dateFormatter.string(from: date)
print(formattedDate) // 2023年4月15日 土曜日 9時01分25秒 日本標準時
表現変更
歴
Identifier | 表示 |
gregorian | グレゴリオ歴(西暦) |
japanese | 和暦(元号) |
iso8601 | 日付と時刻表記に関するISOの国際規格に準ずる表示 |
その他に指定可能なIdentifierはCalendar.Identifierを参照
Locale変更
その他に指定可能なIdentifierはCalendar.Identifierを参照
let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.calendar = Calendar(identifier: .gregorian)
dateFormatter.locale = Locale(identifier: "en_US")
dateFormatter.dateStyle = .full
dateFormatter.timeStyle = .full
let formattedDate = dateFormatter.string(from: date)
print(formattedDate)
歴 | gregorian | gregorian | japanese | japanese | iso8601 | iso8601 |
Locale | en_US | en_US | ja_JP | ja_JP | en_US | ja_JP |
dateStyle.none | 無し | 無し | 無し | 無し | 無し | 無し |
dateStyle.short | 4/7/23 | 2023/04/07 | 4/7/R5 | R5/04/07 | 4/7/23 | 2023/04/7 |
dateStyle.medium | Apr 7, 2023 | 2023/04/07 | Apr 7, Reiwa 5 | R5/04/07 | Apr 7, 2023 | 2023/04/7 |
dateStyle.long | April 7, 2023 | 2023年4月7日 | April 7, Reiwa 5 | 令和5年4月7日 | April 7, 2023 | 2023年4月7日 |
dateStyle.full | Friday, April 7, 2023 | 2023年4月7日 金曜日 | Thursday, April 7, Reiwa 5 | 令和5年4月7日 金曜日 | Thursday, April 7, 2023 | 2023年4月7日 木曜日 |
歴 | gregorian | gregorian | japanese | japanese | iso8601 | iso8601 |
Locale | en_US | en_US | ja_JP | ja_JP | en_US | ja_JP |
timeStyle.none | 無し | 無し | 無し | 無し | 無し | 無し |
timeStyle.short | 7:15 AM | 7:15 | 7:15 AM | 7:15 | 7:15 AM | 7:15 |
timeStyle.medium | 7:15:38 AM | 7:15:38 | 7:15:38 AM | 7:15:38 | 7:15:38 AM | 7:15:38 |
timeStyle.long | 7:15:38 AM GMT+9 | 7:15:38 JST | 7:15:38 AM GMT+9 | 7:15:38 JST | 7:15:38 AM GMT+9 | 7:15:38 JST |
timeStyle.full | 7:15:38 AM Japan Standard Time | 7時15分38秒 日本標準時 | 7:15:38 AM Japan Standard Time | 7時15分38秒 日本標準時 | 7:15:38 AM Japan Standard Time | 7時15分38秒 日本標準時 |
相対的日にち(今日、昨日、一昨日)
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "ja_JP")
formatter.dateStyle = .full
formatter.timeStyle = .none
formatter.doesRelativeDateFormatting = true
let date = Date()
print(formatter.string(from: date)) // 今日
期間表示
表示)2023年4月12日(水)~14日(金)
let formatterJa = DateIntervalFormatter()
formatterJa.dateTemplate = "ydMMMEEE"
formatterJa.locale = Locale(identifier: "ja_JP")
let formatterEn = DateIntervalFormatter()
formatterEn.dateTemplate = "ydMMMEEE"
formatterEn.locale = Locale(identifier: "en_US")
let now = Date()
let afterTomorrow = Date(timeIntervalSinceNow: 60*60*48)
print(formatterJa.string(from: now, to: afterTomorrow)) // 2023年4月12日(水)~14日(金)
print(formatterEn.string(from: now, to: afterTomorrow)) // Wed, Apr 12 – Fri, Apr 14, 2023
ISO86001形式
ISO8601(日付と時刻に関するISO国際規格)
let formatter = ISO8601DateFormatter()
formatter.timeZone = TimeZone.current
let date = Date()
let strDate = formatter.string(from: date)
print(strDate) // 2023-04-13T05:47:30+09:00
ちょいカスタム書式
setLocalizedDateFormatFromTemplateを使用したカスタム書式
※Localeを設定してからsetLocalizedDateFormatFromTemplateコール
setLocalizedDateFormatFromTemplateに、Unicode Technical Standard #35で定義されたパターンを使用します。詳しくは、Date Format Patternsを参照してください。
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "ja_JP")
formatter.setLocalizedDateFormatFromTemplate("MMyyyyddssmmhh")
let date = Date()
print(date)
let strDate = formatter.string(from: date)
print(strDate) // 04/13/2023, 6:56:35 AM ja_JP:2023/04/13 午前6:55:39
// 04/13/2023, 06:57:47 2023/04/13 7:00:24
カスタム書式
dateStyle/timeStyleで指定できない表示フォーマットへの変換の場合はdateFormatに個別指定を使用する。
let formatter = DateFormatter()
formatter.timeZone = TimeZone.current
formatter.locale = Locale.current
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let date = Date()
print(formatter.string(from: date)) // 2023-04-08 05:28:56
String → Date(文字列StringからDateへ変換)
UIでString型で使用し、データ管理、保持はDate型としている場合などにUIで日付を日付をした場合にDate型へ戻すのに使用したりします。
DateFromatter.dateを使用しdateFormatにStringの日時形式にあったフォオーマットを設定する必要があります。
dateFormatにフォーマットが異なるとdateへの変換はできません。
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "ja_JP")
formatter.dateFormat = "yyyy年MM月dd日 HH時mm分ss秒"
let date = Date()
print(date)
let strDate = formatter.string(from: date)
print(strDate) // 2023年04月15日 06時38分32秒
let strToDate = formatter.date(from: strDate)
print(strToDate!) // 2023-04-14 21:38:32 +0000
Locale
日付・時間の表記、小数点、桁区切り文字、通貨記号などの書式を指定します。
- iPhone端末でのロケール情報変更方法「設定」→「一般的」→「言語と地域」で確認・設定できます。
Swift Localeでは、Unicode language identifier(言語識別子)を設定することができます。これらの識別子は、Unicodeの標準であるBCP 47(Best Current Practice 47)に準拠しています。BCP 47は、RFC 5646とRFC 4647によって定義されており、言語、地域、スクリプトなどの識別子を提供しています。
ANA Language Subtag Registry(言語サブタグ登録簿): IANA(Internet Assigned Numbers Authority)が管理している言語サブタグの公式リストです。ここから最新の言語、地域、スクリプトの識別子を見つけることができます。
“ja_JP” = ”Type: language”_”Type: region”
Type: language
Subtag: ja
Description: Japanese
Added: 2005-10-16
Suppress-Script: Jpan
Type: region
Subtag: JP
Description: Japan
Added: 2005-10-16
指定可能なLocale識別子の一覧取得方法
// 使用可能なIdentifiers一覧取得
let identifiers = Locale.availableIdentifiers
print(identifiers)
// check10 :OK
最後に
以上、Dateを日付を扱いかたのパターンを紹介しました。
最後までお読みいただきありがとうございます。
コーディングの際に少しでもお役に立てましたら嬉しい限りです。