NSDateは年/月/日を取得します


291

NSDate他の情報がない場合、オブジェクトの年/月/日を取得するにはどうすればよいですか?私はおそらくこれに似た何かでこれを行うことができると思います:

NSCalendar *cal = [[NSCalendar alloc] init];
NSDateComponents *components = [cal components:0 fromDate:date];
int year = [components year];
int month = [components month];
int day = [components day];

しかし、それはNSDateの年/月/日を取得するのと同じくらい簡単なことにはかなりの手間がかかるようです。他の解決策はありますか?


4
最初の行を「NSCalendar * cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];」に変更するまで、このコードの使用に少し問題がありました。この質問が出されてから、APIに変更があったはずです。
Russell Thackston、2012

@ futureelite7はリビジョン1にロールバックしました。そこにあるコードは歴史的な目的のためのものであり、私の最初のアイデアが何であったかを簡単に説明したものです。
リチャードJ.ロスIII

コードは機能しなくなります。正しいコードを書き留めていただけますか?
futureelite7

@ futureelite7いいえ。そのコードは私の最初の試みを示すものであり、機能することを意図したものではありませんでした。それがあいまいだと感じた場合は、そのコードブロックの周囲のコンテキストを自由に編集してください。ただし、コード自体は編集しないでください。コード自体を編集することに非常に強いと感じている場合は、このカバレッジをメタに取り込んでください。他のmodの発言がわかります。
リチャードJ.ロスIII

8
@mikeそれが質問ではなく答えを読む理由です。
リチャードJ.ロスIII

回答:


615

これは明らかに私の最も人気のある回答なので、少しだけ多くの情報が含まれるように編集してみます。

その名前にもかかわらず、NSDateそれ自体は日付ではなく、単にマシン時間のポイントを示します。で指定された時点NSDateと、年、月、または日との間に相関関係はありません。そのためには、カレンダーを参照する必要があります。特定の時点では、表示しているカレンダーに基づいて異なる日付情報が返されます(たとえば、日付はグレゴリオ暦とユダヤ暦の両方で同じではありません)。また、グレゴリオ暦は、世界-私は仮定しています-私たちはNSDate常にそれを使用するべき少し偏見があります。NSDate幸いなことに、超党派的です。


NSCalendarあなたが述べたように、日付と時刻の取得はを通過する必要がありますが、それを行う簡単な方法があります。

NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];

これNSDateComponentsにより、現在のシステムカレンダーから現在の日付の日、月、年を含むオブジェクトが生成されます。(注:これは必ずしも現在のユーザー指定のカレンダーではなく、デフォルトのシステムカレンダーにすぎません。)

もちろん、別のカレンダーや日付を使用している場合は、簡単に変更できます。利用可能なカレンダーとカレンダーユニットのリストは、NSCalendarクラスリファレンスにあります。詳細についてNSDateComponentsは、「NSDateComponentsクラスリファレンス」を参照してください


参考までに、から個々のコンポーネントにアクセスするのNSDateComponentsは簡単です。

NSInteger day = [components day];
NSInteger month = [components month];
NSInteger year = [components year];

注意する必要NSDateComponentsがあるのは、その有効な情報でフィールドを生成した場合(つまりNSCalendar、その情報をNSCalendarUnitsで提供するように要求した場合)を除き、要求したフィールドの有効な情報が含まれないことです。NSDateComponents参照情報自体は含まれていません。これらは、アクセスするための番号を保持する単純な構造です。たとえばから時代を取得したい場合は、フラグNSDateComponentsNSCalendar付けてジェネレータメソッドにフィードする必要がありますNSCalendarUnitEra


3
これに対する修正で、最初の行にはNSWeekCalendarUnitではなくNSDayCalendarUnitが必要です。
ホワイトホーク2010

@Erikどのカレンダーを使用していますか?コード?
Itai Ferber

7
@Jonny取得する結果は、使用しているカレンダーによって異なります。NSCalendar+currentCalendarメソッドはシステムカレンダーを返すため、ユーザーの電話が日本語またはタイの時間モードに設定されている場合は、別の年を取得します。特定のカレンダーシステムを強制する場合は、カレンダーを作成し、適切なロケールで初期化します。たとえば、グレゴリオ暦を強制するには、次のように使用することをお勧めします:[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]
板井ファーバー

2
列挙型NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnitは非推奨です。代わりにNSCalendarUnitDayを使用してください。
Kunal Balani 2013年

2
警告:ユーザーに値を表示する場合を除き、[NSCalendar currentCalendar]は使用しないでください。ユーザーが仏暦(現在の年は2558年かそれ以降)やその他の奇数のカレンダーをフォローしている可能性があることを考慮してください。このような場合にアプリを壊したくない。特別な理由がない限り、グレゴリオ暦を使用してください。このバグは、あなたとあなたのテスターがすべてデフォルトとしてグレゴリオ語を使用する可能性があるため、見つけるのが困難です。
n13 2015

51

NSDateFormatterを使用して、NSDateの個別のコンポーネントを取得できます。

NSDateFormatter *df = [[NSDateFormatter alloc] init];

[df setDateFormat:@"dd"];
myDayString = [df stringFromDate:[NSDate date]];

[df setDateFormat:@"MMM"];
myMonthString = [df stringFromDate:[NSDate date]];

[df setDateFormat:@"yy"];
myYearString = [df stringFromDate:[NSDate date]];

省略形ではなく月数を取得する場合は、「MM」を使用します。整数を取得したい場合は、[myDayString intValue];


1
この要点で彼に拡大した。楽しんでください---これをコードにドロップできます。
DogEatDog 2012年

日付を使用して辞書を検索する際の問題を解決しました:)ありがとうございます!
mlunoe

1
これは実際には常に期待どおりに100%機能するわけではありません。例えば、NSDateは、日付の実際の数は2013年であったとしても、2013年12月31日0時00分00秒0000は、その後、フォーマットされた日付が年2014を返しますであれば
margusholland

どうすればその年の日を取得できますか。たとえば、4月10日は現在の日で99日目ですか?? –
iOS開発者

17

Itaiの優れた(そして機能している!)コードを言い換えると、を返すために、サンプルのヘルパークラスは次のようになります。言い換えると、指定されたNSDate変数の値ます。

ご覧のとおり、このコードを変更して月または日を取得するのは簡単です。

+(int)getYear:(NSDate*)date
{
    NSDateComponents *components = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:date];

    int year = [components year];
    int month = [components month];
    int day = [components day];

    return year;
}

(2013年に、このような独自の基本的なiOS日付関数を作成する必要があるとは信じられません...)

もう1つ、2つのNSDate値を比較するために<と>を使用しないでください。

XCodeはこのようなコードを(エラーや警告なしで)喜んで受け入れますが、その結果は宝くじです。NSDateを比較するには、「比較」関数を使用する必要あります。

if ([date1 compare:date2] == NSOrderedDescending) {
    // date1 is greater than date2        
}

4
ポインター比較の結果は宝くじにはほど遠い-意図された目的(オブジェクトではなくポインターの比較)に使用する限り、非常に明確な結果が得られます。
リチャードJ.ロスIII

宝くじではないかもしれませんが、C#のDateTimeの方がはるかに直感的です。iOSでは、小なり演算子は実際に2つのNSDateを比較する必要があります...本当に2つのNSDate変数のポインターを比較したいですか?少なくとも、XCodeショーは、これが本当にユーザーが何を意味するのかを尋ねる警告を表示します。
Mike Gledhill 2013年

1
それは、彼が書いている言語の基本を理解していない怠惰なコーダーの兆候にすぎません。そして、特にカスタムコンテナーを作成している場合は、ポインターの比較がObjCオブジェクトに必要な状況がありました(ただし、物事はARCで奇妙になります)。
Richard

1
私は基本を理解していない怠惰なコーダーである必要がありますが、それはマイクの素晴らしいヒントです!
Pier-Luc Gendreau 2013年

4
ポインターの比較が必要になる場合がありますが、2つの日付を比較する場合はそれほど一般的ではありません。99.99%の確率で、プログラマーはポインターよりも日付の比較に関心を持ちます。基本的にC#と.NETフレームワークは、最も一般的なシナリオを容易にするように設計されているため、プログラマーの生産性が向上し、多くの場合、objective-cは意図的に困難な作業を行うように感じます。すべての言語の基礎について800ページの本を読む時間があれば、乾杯ですが、残りの人には時間通りに予算どおりに配信するアプリがあります。
2013年

16

Swift 2.0の場合:

    let date = NSDate()
    let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)!
    let components = calendar.components([.Month, .Day], fromDate: date)

    let (month, day) = (components.month, components.day)

11

私がこの答えを書いているのは、NSDateComponent変数からのオプションを返さないか、それらの変数を強制的にアンラップしない(Swift 3の場合も)唯一のアプローチだからです。

スウィフト3

let date = Date()
let cal = Calendar.current
let year = cal.component(.year, from: date)
let month = cal.component(.month, from: date)
let day = cal.component(.day, from: date)

スウィフト2

let date = NSDate()
let cal = NSCalendar.currentCalendar()
let year = cal.component(.Year, fromDate: date)
let month = cal.component(.Month, fromDate: date)
let day = cal.component(.Day, fromDate: date)

Bonus Swift 3楽しいバージョン

let date = Date()
let component = { (unit) in return Calendar.current().component(unit, from: date) }
let year = component(.year)
let month = component(.month)
let day = component(.day)

どうすればその年の日を取得できますか。たとえば、4月10日は現在の日で99日目ですか?? –
iOS開発者

そして、あなたが1桁...日本のカレンダーのリターンを例えばグレゴリオ暦、年間のコンポーネントを使用します
Flovettee

8

iOS 8の新機能

ObjC

NSDate *date = [NSDate date];
NSInteger era, year, month, day;
[[NSCalendar currentCalendar] getEra:&era year:&year month:&month day:&day fromDate:date];

迅速

let date = NSDate.init()
var era = 0, year = 0, month = 0, day = 0
NSCalendar.currentCalendar().getEra(&era, year:&year, month:&month, day:&day, fromDate: date)

2
すごい!@Yuchen Zhong
Lito

1
鮮やかさ !構文がはるかに優れています!
joan

4

iOS 8以降をターゲットにしている場合は、新しいNSCalendar簡易メソッドを使用して、これをより簡潔な形式で実現できます。

最初にを作成し、必要なNSCalendarものを使用しますNSDate

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *date = [NSDate date];

コンポーネントを個別に抽出できます component:fromDate:

NSInteger year = [calendar component:NSCalendarUnitYear fromDate:date];
NSInteger month = [calendar component:NSCalendarUnitMonth fromDate:date];
NSInteger day = [calendar component:NSCalendarUnitDay fromDate:date];

または、さらに簡潔に、NSInteger経由でポインタを使用しますgetEra:year:month:day:fromDate:

NSInteger year, month, day;
[calendar getEra:nil year:&year month:&month day:&day fromDate:date];

詳細および例については、NSDate Manipulation Made Easy in iOS 8をご覧ください。免責事項、私は投稿を書きました。


どうすればその年の日を取得できますか。たとえば、4月10日は現在の日で99日目ですか?? –
iOS開発者

4

iOS 8.0(およびOS X 10)以降では、コンポーネントメソッドを使用して、次のように単一の日付コンポーネントを簡単に取得できます。

int year = [[NSCalendar currentCalendar] component:NSCalendarUnitYear fromDate:[NSDate date]];

物事をより簡単にし、うまくいけば、これは効率的に実装されます。



2
    NSDate *currDate = [NSDate date];
    NSCalendar*       calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents* components = [calendar components:NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:currDate];
    NSInteger         day = [components day];
    NSInteger         month = [components month];
    NSInteger         year = [components year];
    NSLog(@"%d/%d/%d", day, month, year);

それははっきりと私に年、月、日を整数として与えません、それは私がOPで要求したものです。-1。
リチャードJ.ロスIII 14

1
リチャードJ.ロスIII:私はちょうどそれを修正しました。申し訳ありませんが、私の答えがあなたの質問を失いました。
Linh Nguyen 14

2

これがSwiftのソリューションです:

let todayDate = NSDate()
let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)!

// Use a mask to extract the required components. Extract only the required components, since it'll be expensive to compute all available values.
let components = calendar.components(.CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay, fromDate: todayDate)

var (year, month, date) = (components.year, components.month, components.day) 

2

これを試して 。。。

コードスニペット:

 NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];
 int year = [components year];
 int month = [components month];
 int day = [components day];

現在の年、月、日を示します


1

以下を試してください:

    NSString *birthday = @"06/15/1977";
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"MM/dd/yyyy"];
    NSDate *date = [formatter dateFromString:birthday];
    if(date!=nil) {
        NSInteger age = [date timeIntervalSinceNow]/31556926;
        NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:date];
        NSInteger day = [components day];
        NSInteger month = [components month];
        NSInteger year = [components year];

        NSLog(@"Day:%d Month:%d Year:%d Age:%d",day,month,year,age);
    }
    [formatter release];

1

Swift 2.x

extension NSDate {
    func currentDateInDayMonthYear() -> String {
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "d LLLL yyyy"
        return dateFormatter.stringFromDate(self)
    }
}

次のように使用できます

NSDate().currentDateInDayMonthYear()

出力

6 March 2016

1

迅速

オプションの文字列として日付の要素を取得する簡単な方法。

extension Date {

  // Year 
  var currentYear: String? {
    return getDateComponent(dateFormat: "yy")
    //return getDateComponent(dateFormat: "yyyy")
  }

  // Month 
  var currentMonth: String? {
    return getDateComponent(dateFormat: "M")
    //return getDateComponent(dateFormat: "MM")
    //return getDateComponent(dateFormat: "MMM")
    //return getDateComponent(dateFormat: "MMMM")
  }


  // Day
  var currentDay: String? {
    return getDateComponent(dateFormat: "dd")
    //return getDateComponent(dateFormat: "d")
  }


  func getDateComponent(dateFormat: String) -> String? {
    let format = DateFormatter()
    format.dateFormat = dateFormat
    return format.string(from: self)
  }


}

let today = Date()
print("Current Year - \(today.currentYear)")  // result Current Year - Optional("2017")
print("Current Month - \(today.currentMonth)")  // result Current Month - Optional("7")
print("Current Day - \(today.currentDay)")  // result Current Day - Optional("10")

0

私はこのようにしています...

NSDate * mydate = [NSDate date];

NSCalendar * mycalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSCalendarUnit units = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;

NSDateComponents * myComponents  = [mycalendar components:units fromDate:mydate];

NSLog(@"%d-%d-%d",myComponents.day,myComponents.month,myComponents.year);

0

人間が読める文字列(日、月、年)を取得するには、次のようにします。

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *string = [dateFormatter stringFromDate:dateEndDate];
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.