読み込み中...

【Objective-C】NSDateFormatterで日時を自在に操る5つのコード

Objective-C言語でのNSDateFormatterを使った日時操作のイメージ Objctive-C
この記事は約25分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

プログラミング言語とは、人間とコンピュータの間でのコミュニケーションツールです。

その多種多様な言語の中でObjective-Cは、AppleのOS XやiOSのアプリケーション開発において長年使用されてきた重要な言語の一つです。

Objective-CはC言語にオブジェクト指向機能を加えた上位セットです。

この言語は、Smalltalkのオブジェクト指向概念とC言語の効率の良さを組み合わせたもので、強力なプログラミング手法として利用されてきました。

本稿では、このObjective-Cの基礎知識とその歴史、特徴について掘り下げていきます。

●Objective-Cとは

Objective-Cは、C言語をベースとし、Smalltalkのオブジェクト指向パラダイムを取り入れたプログラミング言語です。

1980年代にBrad CoxとTom Loveによって開発され、NeXT Computerによって採用された後、Apple Inc.によるNeXTの買収と共に、Mac OS XおよびiOSの開発言語として中心的な役割を果たしてきました。

Objective-Cは、C言語の構文を拡張し、クラス、継承、ポリモーフィズム、インターフェースなどのオブジェクト指向概念をサポートすることで、ソフトウェア開発における再利用性とメンテナンス性を向上させています。

○Objective-Cの歴史と特徴

Objective-Cの歴史は、1980年代に遡ります。

この言語は、Brad CoxとTom Loveによって開発され、最初の商用利用はNeXTのワークステーションでした。

Objective-Cは、その後AppleによるNeXTの買収を経て、Mac OS XやiOSの開発言語として広く普及しました。

この言語の特徴的な点は、強力なランタイムとオブジェクト指向の機能をC言語のシンタックスに統合していることです。

これにより、開発者はC言語の速度と効率を損なうことなく、オブジェクト指向設計の利点を享受できます。

Objective-Cは、動的タイピングを採用しているため、オブジェクトの型はコンパイル時ではなく実行時に決定されます。

これにより柔軟なコーディングが可能となり、実行時の挙動の変更や拡張がしやすくなっています。

また、メッセージパッシングに基づくメソッドの呼び出し方式は、Smalltalkからの影響を強く受けており、プログラムの流れを理解しやすくしています。

Objective-Cの特徴としては、次の3点が挙げられます。

  1. クラスベースのオブジェクト指向をサポートし、継承、カプセル化、多態性を使用して、コードのモジュール性と再利用性を高める。
  2. Objective-CはC言語のスーパーセットであり、任意のCプログラムはObjective-Cコンパイラでそのままコンパイルできる。
  3. 型検査とオブジェクトの振る舞いの決定を実行時に行うことができる。

これらの特徴によりObjective-Cは、特にAppleのプラットフォームでのソフトウェア開発において、長らく重要な位置を占めてきました。

しかし、近年ではAppleがSwiftという新しいプログラミング言語を導入したことにより、徐々にその地位は変わりつつあります。

それでもなお、多くの既存アプリケーションやライブラリがObjective-Cで書かれており、現在でもその知識は価値があると言えるでしょう。

●NSDateFormatterの基本

NSDateFormatterはObjective-Cで日時のフォーマットを変換、表示するためのクラスです。

アプリケーション開発において、ユーザーがさまざまな日時フォーマットを理解しやすくするために非常に重要な機能を果たしています。

Objective-CにおいてNSDateFormatterは日付や時刻を文字列に変換する際、または文字列からNSDateオブジェクトを生成する際に使用されます。

この柔軟性により、世界中の異なる地域やカルチャーで使用される様々な日時フォーマットに対応できるようになっています。

○NSDateFormatterとは

NSDateFormatterクラスはFoundationフレームワークに属しており、日時を表示するための文字列を生成するか、または文字列を日時に変換するためのメソッドを提供します。

このクラスのインスタンスを作成し、設定をカスタマイズすることで、必要な日時フォーマットを容易に実現できます。

○NSDateFormatterの使い方の基本

NSDateFormatterを使用するための基本的な手順は、まずインスタンスを作成し、フォーマットを設定することです。

フォーマット設定には、’dateFormat’プロパティを使用して行います。

次に、このフォーマッタを使用してNSDateオブジェクトを適切な文字列に変換したり、日付の文字列をNSDateオブジェクトに変換したりすることができます。

○サンプルコード1:基本的な日付のフォーマット

NSDateFormatterの使用を始めるには、まずNSDateFormatterのインスタンスを作成します。

次に、日付と時刻のフォーマットに使用するパターン文字列を’dateFormat’プロパティに設定します。

たとえば、下記のコードは年-月-日の形式で日付を表示する一例を表しています。

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd"];
NSDate *today = [NSDate date];
NSString *formattedDate = [formatter stringFromDate:today];
NSLog(@"今日の日付: %@", formattedDate);

このコードでは、NSDateFormatterを使用して現在の日付を取得し、設定したフォーマットに基づいて文字列に変換しています。

この例では、「yyyy-MM-dd」をフォーマットパターンとして使用し、出力される文字列は「今日の日付: 2023-11-06」となります。

NSDateFormatterの使用時には、フォーマット文字列の正確さが非常に重要です。

‘yyyy’は4桁の年を表し、’MM’は2桁の月を表し、’dd’は2桁の日を表します。

設定するフォーマットパターンに誤りがあると、予期しない結果を生じる可能性があります。

そのため、設定する際にはUnicode Technical Standard #35に記載されているパターン文字列を参照することが推奨されます。

●NSDateFormatterの詳細な使い方

NSDateFormatterはObjective-Cで日付や時刻を文字列に変換する際に不可欠なクラスです。

開発者はこのクラスを使用して、様々な日時フォーマットを自由自在に操ることができます。

この記事では、NSDateFormatterのさらに詳しい使い方を紹介し、いくつかの高度な機能を掘り下げます。

○サンプルコード2:ロケールを設定する

ロケールは地域設定を意味し、日付と時刻のフォーマットを国や地域に合わせるために使用されます。

NSDateFormatterを使用するとき、アプリケーションが多言語をサポートしている場合、適切なロケールを設定することが重要です。

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterLongStyle];
[formatter setTimeStyle:NSDateFormatterShortStyle];
[formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"ja_JP"]]; // 日本のロケールを設定
NSDate *date = [NSDate date]; // 現在の日付と時刻を取得
NSString *formattedDate = [formatter stringFromDate:date]; // フォーマットを適用
NSLog(@"フォーマットされた日付: %@", formattedDate);

このコードではNSDateFormatterを使用して現在の日付と時刻を取得し、日本の日時フォーマットに合わせています。

setLocale:メソッドでja_JPを指定することで、日本の日時表示に適した形式で出力することができます。

この例では、日付を長いスタイル、時間を短いスタイルで設定し、日本のロケールでフォーマットを適用した後、結果をコンソールに表示しています。

このコードの実行により、次のような出力結果が得られます。

フォーマットされた日付: 2023年4月28日 13:00

○サンプルコード3:タイムゾーンを設定する

アプリケーションでグローバルユーザーを対象とする場合、異なるタイムゾーンで日時を正確に表示する必要があります。

NSDateFormatterはタイムゾーンの設定もサポートしており、下記のサンプルコードは特定のタイムゾーンで日時をフォーマットする方法を表しています。

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterFullStyle];
[formatter setTimeStyle:NSDateFormatterFullStyle];
[formatter setTimeZone:[NSTimeZone timeZoneWithName:@"America/New_York"]]; // ニューヨークのタイムゾーンを設定
NSDate *date = [NSDate date]; // 現在の日付と時刻を取得
NSString *formattedDate = [formatter stringFromDate:date]; // フォーマットを適用
NSLog(@"ニューヨークのタイムゾーンでフォーマットされた日付と時刻: %@", formattedDate);

このコードでは、setTimeZone:メソッドを使ってAmerica/New_Yorkを設定し、日付と時刻をニューヨークのタイムゾーンに合わせてフォーマットしています。

全スタイルで日付と時刻のスタイルを設定することで、非常に詳細な日時情報を提供しています。

出力結果は次の通りです。

ニューヨークのタイムゾーンでフォーマットされた日付と時刻: 2023年4月28日金曜日 東部夏時間 1時00分00秒

タイムゾーンを指定することで、ユーザーが世界のどこにいても、その地域に適した日時情報を受け取ることが可能になります。

これは特に旅行アプリや国際的なビジネスアプリケーションで有用です。

●NSDateFormatterの応用例

NSDateFormatterはObjective-Cで日付と文字列の相互変換を行う際に非常に便利なクラスです。

このクラスを使用することで、ロケールやタイムゾーンに基づいた日付表現の変換が容易になります。

しかし、その機能をさらに活かすためには、より高度な応用例を理解することが重要です。

ここでは、NSDateFormatterを用いた応用例のいくつかを、具体的なコード例を交えて解説します。

○サンプルコード4:相対的な日付表記を使用する

ユーザーが直感的に日付を理解できるように、例えば「今日」「明日」といった相対的な表記をする場合があります。

このコードではNSDateFormatterとNSCalendarを組み合わせて、相対的な日付表記を生成する方法を表しています。

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateStyle = NSDateFormatterMediumStyle;
formatter.doesRelativeDateFormatting = YES;

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *today = [NSDate date];
NSDate *tomorrow = [calendar dateByAddingUnit:NSCalendarUnitDay value:1 toDate:today options:0];

NSString *relativeDateStringToday = [formatter stringFromDate:today];
NSString *relativeDateStringTomorrow = [formatter stringFromDate:tomorrow];

NSLog(@"今日の日付: %@", relativeDateStringToday);
NSLog(@"明日の日付: %@", relativeDateStringTomorrow);

このコードではNSDateFormatterdoesRelativeDateFormattingプロパティをYESに設定することで、現在の日付に対して相対的な日付を返すようになります。

NSCalendarを用いて明日の日付を計算し、それをNSDateFormatterに渡しています。

この例では、現在の日付が「今日」として、明日の日付が「明日」としてコンソールに出力されます。

○サンプルコード5:カスタムフォーマットを使用する

さらに柔軟に日付を扱いたい場合、カスタムフォーマットパターンを指定することで、特定の書式で日付を表示することができます。

下記のコードは、カスタムフォーマットを用いて日付と時刻を特定の形式で出力する方法を表しています。

NSDateFormatter *customFormatter = [[NSDateFormatter alloc] init];
[customFormatter setDateFormat:@"yyyy年MM月dd日(E) HH時mm分ss秒"];

NSDate *currentDate = [NSDate date];
NSString *formattedDateString = [customFormatter stringFromDate:currentDate];

NSLog(@"カスタムフォーマットの日付: %@", formattedDateString);

このコードでは、setDateFormat:メソッドを使用してカスタムの日付フォーマットを指定しています。

この例では、年月日に続いて曜日、そして時分秒を日本語で表示しています。

NSDateクラスのdateメソッドで現在の日付と時刻のオブジェクトを取得し、それをフォーマッタに渡しています。

実行すると、コンソールには例えば「2023年11月06日(日) 12時34分56秒」という形式で日付が出力されます。

●NSDateFormatterのカスタマイズ方法

Objective-Cでアプリ開発を行う際には、日時の表示をユーザーのロケールや好みに合わせてカスタマイズすることが頻繁に求められます。

NSDateFormatterクラスは日時の文字列を作成・解析する際に不可欠で、そのフォーマットをカスタマイズする方法は多岐にわたります。

ここでは、日時のカスタムフォーマットの作成方法から、特定のニーズを満たすためのカスタマイズ方法までを詳細に解説します。

○カスタムフォーマットパターンの作成

NSDateFormatterを用いて、特定のフォーマットパターンを作成することは、アプリケーションで特殊な日時表記が必要な場合に非常に有用です。

例えば、ユーザーが好む特定の日時形式を実装する場合や、既存のフォーマットオプションでは対応できない形式を作る場合にカスタムフォーマットが役立ちます。

○サンプルコード6:フォーマットパターンをカスタマイズする

下記のサンプルコードでは、「年-月-日 時:分:秒」の形式で日時を表示するカスタムフォーマットを設定しています。

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// カスタムフォーマットパターンを設定
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
// 日時オブジェクトを用意(例として現在時刻を使用)
NSDate *now = [NSDate date];
// 日時オブジェクトをカスタムフォーマットの文字列に変換
NSString *customFormattedDate = [formatter stringFromDate:now];
// ログに出力して確認
NSLog(@"カスタマイズされた日時: %@", customFormattedDate);

このコードではNSDateFormatterを初期化しており、dateFormatプロパティにカスタムのパターン文字列を設定しています。

ここでyyyyは4桁の年を、MMは2桁の月を、ddは2桁の日を表し、HHは2桁の24時間表記の時を、mmは2桁の分を、ssは2桁の秒を表しています。

このパターンをformatterに設定することで、stringFromDate:メソッドを使用してNSDateオブジェクトを指定されたフォーマットの文字列に変換できます。

変換結果はコンソールにカスタマイズされた日時:というメッセージと共に出力されます。

上記のコードを実行すると、次のような出力結果が得られます。

カスタマイズされた日時: 2023-11-06 12:34:56

この結果から、現在の日時が「年-月-日 時:分:秒」という形式で正確に表示されていることがわかります。

このようにNSDateFormatterをカスタマイズすることで、様々な日時表示のニーズに柔軟に対応することが可能です。

●NSDateFormatterを使った時刻の操作

NSDateFormatterは、Objective-Cで日時を文字列に変換したり、文字列から日時に変換する際に使用されるクラスです。

iOSやmacOSのアプリ開発において、ユーザーに親しみやすい形で日時を表示するためや、内部的に日時のデータを処理するために欠かせないツールの一つです。

日時データのローカライズ、すなわち地域や言語に応じた表示にも対応しており、グローバルなアプリケーション開発には特に重要です。

また、NSDateと組み合わせることで、時刻の計算や比較など、複雑な操作も容易に実行可能になります。

○サンプルコード7:時刻の加算と減算

ここでは、NSDateFormatterを用いて現在時刻に一定の時間を加えたり、引いたりする方法を紹介します。

Objective-Cにおいて、日付の加算や減算はNSCalendarとNSDateComponentsを使用して行います。

まず、現在の日付を取得し、それに加算する時間をNSDateComponentsを通じて指定します。

次に、NSCalendarを使用して加算された日付を得ます。

// NSDateFormatterの初期化
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// フォーマットの設定
[formatter setDateFormat:@"yyyy/MM/dd HH:mm:ss"];

// 現在の日付を取得
NSDate *now = [NSDate date];
// 出力用に現在時刻をフォーマット
NSString *formattedDate = [formatter stringFromDate:now];
NSLog(@"現在時刻: %@", formattedDate);

// 日付の加算
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *componentsToAdd = [[NSDateComponents alloc] init];
[componentsToAdd setHour:2]; // 2時間を加算

// 加算した日付を計算
NSDate *newDate = [calendar dateByAddingComponents:componentsToAdd toDate:now options:0];
// 加算後の時刻をフォーマットして出力
NSString *newFormattedDate = [formatter stringFromDate:newDate];
NSLog(@"2時間後: %@", newFormattedDate);

// 日付の減算
NSDateComponents *componentsToSubtract = [[NSDateComponents alloc] init];
[componentsToSubtract setHour:-3]; // 3時間を減算

// 減算した日付を計算
NSDate *previousDate = [calendar dateByAddingComponents:componentsToSubtract toDate:now options:0];
// 減算後の時刻をフォーマットして出力
NSString *previousFormattedDate = [formatter stringFromDate:previousDate];
NSLog(@"3時間前: %@", previousFormattedDate);

このコードでは、まずNSDateFormatterを作成し、フォーマットを”yyyy/MM/dd HH:mm:ss”という形式に設定しています。

現在の日付と時刻はNSDateのdateメソッドによって取得され、formatterを使用して文字列に変換されています。

そしてNSCalendarを使用して、2時間後と3時間前の時刻を計算しています。

出力された日時は、設定したフォーマットに従ってコンソールに表示されます。

このコードを実行すると、現在の時刻とその2時間後、3時間前の時刻がコンソールに表示されることになります。

例えば現在時刻が午後1時であれば、「現在時刻: 2023/04/01 13:00:00」、「2時間後: 2023/04/01 15:00:00」、「3時間前: 2023/04/01 10:00:00」と出力されるでしょう。

○サンプルコード8:時刻の比較

時刻の比較は、アプリケーションにおいて特定のイベントが発生したかどうかを決定するためにしばしば使用されます。

例えば、特定の時間にアラームを設定する機能や、期限内にタスクを完了しているかを確認する機能などがあります。

NSDateFormatterとNSCalendarを使って、2つの異なる時刻を比較する方法を紹介します。

// NSDateFormatterの初期化
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy/MM/dd HH:mm:ss"];

// 比較対象の日時を設定
NSString *dateString1 = @"2023/04/01 14:00:00";
NSString *dateString2 = @"2023/04/01 15:00:00";

// 文字列からNSDateへ変換
NSDate *date1 = [formatter dateFromString:dateString1];
NSDate *date2 = [formatter dateFromString:dateString2];

// 日付を比較
NSComparisonResult result = [date1 compare:date2];

if (result == NSOrderedAscending) {
    NSLog(@"date1はdate2より前の時刻です。");
} else if (result == NSOrderedSame) {
    NSLog(@"date1とdate2は同じ時刻です。");
} else if (result == NSOrderedDescending) {
    NSLog(@"date1はdate2より後の時刻です。");
}

このコードでは、”yyyy/MM/dd HH:mm:ss”の形式で日時を設定し、NSDateFormatterを用いてNSStringからNSDateへと変換しています。

その後、NSDateのcompareメソッドを使用して二つの時刻を比較し、結果に応じて異なるメッセージをログに出力しています。

実行すると、比較結果に基づいて「date1はdate2より前の時刻です。」といったメッセージがコンソールに表示されるでしょう。

これはdate1が14:00でdate2が15:00であるため、date1が先であることを示します。

●注意点と対処法

プログラミングにおいて日時の扱いは非常に重要です。

特に、Objective-Cを用いてiOSアプリを開発する場合、NSDateFormatterクラスは日時を文字列に変換したり、その逆を行う際に欠かせないものです。

しかし、この便利なクラスを使いこなすには、いくつかの注意点があります。

Objective-CのNSDateFormatterは、日時の表示や解析を行う際に、使用者のロケールやタイムゾーンに基づいて振る舞います。

このため、異なるロケールやタイムゾーンを考慮しないと、期待通りの結果が得られないことがあります。

さらに、フォーマットパターンを誤って使うと、認識できない日付が生じたり、意図しない表示になる可能性があります。

○日付フォーマットの問題点と対処法

NSDateFormatterは、デフォルトの設定だけでなく、カスタムのフォーマットを適用することも可能ですが、カスタムフォーマットには注意が必要です。

例えば、”yyyy/MM/dd”のパターンを使いたい場合、年月日の順序や区切り文字が異なる地域では、このパターンが期待通りの動作をしないことがあります。

したがって、国際化を考えたアプリ開発では、ユーザーのロケールに応じてフォーマットを動的に変更する必要があります。

また、日付のフォーマットではなく、実際の日付値に問題がある場合、例えば不正な日付(2月30日など)をパースしようとした時には、エラーハンドリングが重要です。

不正な日付をどのように扱うかは、アプリケーションの性質によって異なりますが、一般的にはユーザーに警告を出すか、自動的に最も近い有効な日付に修正するかのいずれかが選択されます。

○サンプルコード9:年月日が不正な日付のハンドリング

Objective-CでNSDateFormatterを使って不正な日付を処理する方法を見てみましょう。

ここでは、特定の日付フォーマットで日付を解析し、不正な値が入力された場合にそれをハンドリングするコード例を紹介します。

// Objective-Cでの日付フォーマットのハンドリング例
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy/MM/dd"];

NSString *dateString = @"2023/02/30"; // 存在しない日付
NSDate *date = [formatter dateFromString:dateString];

if (!date) {
    // 日付が不正な場合のハンドリング
    NSLog(@"入力された日付は不正です。修正してください。");
} else {
    // 日付が正常に解析された場合の処理
    NSLog(@"解析された日付: %@", date);
}

このコードではNSDateFormatterを使用して文字列からNSDateオブジェクトを生成しています。

この例では”2023/02/30″という存在しない日付を解析しようとしますが、NSDateオブジェクトはnilを返し、エラーメッセージがコンソールに表示されます。

これは、”dateFromString”メソッドが不正な日付を認識したためです。

このようにして、NSDateFormatterを使った際の不正な入力はエラーハンドリングによって対応することができます。

○サンプルコード10:パフォーマンスの注意点

NSDateFormatterの生成と設定は、特にループ処理内で行われる場合、CPUリソースを大量に消費する可能性があります。

なぜなら、フォーマッタの初期化と設定は比較的コストが高い操作であるからです。

したがって、同じ設定を用いる場合は、NSDateFormatterインスタンスを再利用することをお勧めします。

下記の例では、再利用可能なNSDateFormatterを作成し、それを使って複数の日付を処理する方法を表しています。

// NSDateFormatterのインスタンスを再利用する例
static NSDateFormatter *sharedFormatter = nil;
if (!sharedFormatter) {
    sharedFormatter = [[NSDateFormatter alloc] init];
    [sharedFormatter setDateFormat:@"yyyy/MM/dd"];
    // 他の必要な設定...
}

NSArray *dateStrings = @[@"2023/11/01", @"2023/12/24", @"2024/01/01"];
NSMutableArray *dates = [NSMutableArray arrayWithCapacity:[dateStrings count]];

for (NSString *dateString in dateStrings) {
    NSDate *date = [sharedFormatter dateFromString:dateString];
    if (date) {
        [dates addObject:date];
    } else {
        NSLog(@"不正な日付: %@", dateString);
    }
}

NSLog(@"解析された日付: %@", dates);

この例では、staticキーワードを使ってformatter変数を一度だけ初期化し、その後は同じインスタンスをループの各イテレーションで再利用しています。

これにより、各イテレーションでの初期化コストを避け、パフォーマンスを向上させることができます。

まとめ

Objective-Cのプログラミング言語を使ってiOSアプリ開発における日時の管理は重要な要素です。

NSDateFormatterはその中核をなすクラスであり、日時データのフォーマットと解析を柔軟に行うことができます。

この記事では、NSDateFormatterを用いた5つの具体的なコード例を通じて、その強力な機能と使用方法を解説してきました。

日時の扱いはアプリケーションの使い勝手を大きく左右するため、NSDateFormatterは開発の現場で頻繁に使用されます。

今回提供した情報が、読者の皆さんの開発スキルの向上とアプリケーションの品質改善に貢献することを願っています。

そして、Objective-C言語を用いた日時操作の基本から応用、カスタマイズ技法に至るまで、この記事が実用的なガイドとなることを期待しています。