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肯定已经发生了变化。
罗素·塔克斯顿

@ futureelite7回滚到修订版1。该代码出于历史目的,是对我最初想法的简单说明。
理查德·罗斯三世

该代码不再起作用。您可以记下正确的代码吗?
futureelite7'7

@ futureelite7号 该代码表明了我的第一次尝试,但从未尝试过。如果您觉得模棱两可,请随意编辑该代码块周围的上下文,但不要编辑代码本身。如果您对编辑代码本身有强烈的兴趣,请将此内容介绍到meta上,我们将看到其他mod不得不说些什么。
理查德·罗斯三世

8
@mike那就是为什么您阅读答案而不是问题的原因。
理查德·罗斯三世

Answers:


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本身不包含任何参考信息-它们只是包含数字供您访问的简单结构。例如,如果您还想获得一个时代,例如,NSDateComponents要从中获得一个,则必须NSCalendar使用NSCalendarUnitEra标记来提供generator方法。


3
对此的更正,第一行应具有NSDayCalendarUnit而不是NSWeekCalendarUnit。
whitehawk's

@Erik您正在使用哪个日历?码?
Itai Ferber

7
@Jonny您得到的结果取决于您使用的日历。NSCalendar+currentCalendar方法将返回系统日历,因此,如果用户的电话设置为日文或泰文时间模式,则将获得不同的年份。如果要强制使用特定的日历系统,请创建一个日历并使用正确的语言环境对其进行初始化。例如,要强制使用公历,您将需要使用以下内容:[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]
Itai Ferber 2013年

2
枚举NSDayCalendarUnit | NSMonthCalendarUnit | 已弃用NSYearCalendarUnit,请改用NSCalendarUnitDay。
Kunal Balani

2
警告:除非您要向用户显示值,否则请不要使用[NSCalendar currentCalendar]。考虑用户可能遵循佛教历法(现在是2558年左右)或其他任意数量的奇数历法。在这种情况下,您不希望您的应用程序中断。除非有非常特殊的原因,否则请使用公历。很难捕获此错误,因为您和您的测试人员可能都默认使用gregorian。
n13

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 2012年

1
实际上,这并非一直都能按预期100%进行。例如,如果NSDate是2013-12-31 00:00:00 +0000,则格式化的日期将返回2014年,即使该日期中的实际数字是2013
。– margusholland 2014年

我如何获取一年中的某天,例如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日期函数……)

另一件事:永远不要使用<和>比较两个NSDate值。

XCode会很乐意接受这样的代码(没有任何错误或警告),但其结果是彩票。您必须使用“比较”功能来比较NSDate:

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

4
指针比较的结果远非彩票-只要您将它们用于预期目的,它们就有非常明确的结果-比较指针,而不是对象。
理查德·罗斯三世

可能不是抽奖,但是C#的DateTime更加直观。在iOS中,小于运算符确实应该比较两个NSDate ...会有人真的想比较两个NSDate变量的指针吗?至少,XCode节目会显示警告,以询问这是否真的是用户真正的意思。
Mike Gledhill

1
这只是一个懒惰的编码者的标志,他不了解他所写语言的基本原理。而且,在我看来有些情况下ObjC对象必须进行指针比较-特别是在创建自定义容器时(尽管ARC会使事情变得更奇怪)。
理查德·罗斯三世

1
我必须是一个不懂基本知识的懒惰编码人员,但这是迈克的一个很好的提示!
2013年

4
指针比较可能是必要的,但在比较两个日期时,它们是不太常见的用例。99.99%的时间,任何程序员对比较日期而不是指针都将更感兴趣。从根本上讲,C#和.NET框架旨在简化最常见的场景,从而使程序员更加高效,并且在许多情况下,objective-c的感觉就像是故意使事情变得更加艰巨。如果您有时间阅读800本书,了解每种语言的基础知识,那将很高兴,但是我们其余的人都有可以按时且按预算交付的应用程序。
秧鸡

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)

奖励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的新功能

对象

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
太棒了!语法更好!

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];

有关更多信息和示例,请查看iOS 8中的NSDate Manipulation Made Easy。免责声明,我写了这篇文章。


我如何获取一年中的某天,例如4月10日是当前年的第99天?–
iOS开发人员

4

从iOS 8.0(和OS X 10)开始,您可以使用component方法来简化单个日期组件的获取,如下所示:

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。
理查德·罗斯三世

1
理查德·罗斯三世(Richard J. Ross III):我已经解决了,很抱歉,因为我的回答丢失了您的问题。
Linh Nguyen 2014年

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

斯威夫特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

迅速

获得日期的任何元素作为可选String的更简单方法。

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];
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.