34

I want to get the date from NSDate and do not need time. Example:

NSDate* today = [NSDate date];  // want to give 20-06-2012 only

I want to get the date for today without showing the time and use it in NSDate variable or string variable.

Dheeraj Gupta
  • 372
  • 5
  • 20
Ghass.64
  • 365
  • 1
  • 4
  • 8

4 Answers4

47

In case someone else looks for this. I used the following:

NSDateComponents *components = [[NSCalendar currentCalendar] 
             components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit 
              fromDate:[NSDate date]];
NSDate *startDate = [[NSCalendar currentCalendar] 
             dateFromComponents:components];
mmmmmm
  • 32,227
  • 27
  • 88
  • 117
jody
  • 493
  • 6
  • 5
  • 4
    @KunalBalani, do you have a faster alternative? – Mike Cole Sep 25 '14 at 20:57
  • this returns "null" in case I have a `date` parameter that is NOT `[NSDate date]`. – nightfixed Aug 21 '15 at 10:34
  • just create NSDateFormatter with appropriate format without time and reuse it, guess better for performance – Injectios Mar 08 '16 at 11:37
  • @MikeCole the alternative is to not use NSDate in first place, NSDate represents a snapshot in time not date specifically. If you need to drop time from NSDate probably you are using the wrong data structure. – Kunal Balani Aug 17 '16 at 18:12
9

In terms of performance this approach may be better than using NSDateFormatter or NSCalendar.

Swift 3, 4, 5

let timeInterval = floor(Date().timeIntervalSinceReferenceDate / 86400) * 86400
let newDate = Date(timeIntervalSinceReferenceDate: timeInterval)

Swift 2

let timeInterval = floor(NSDate().timeIntervalSinceReferenceDate / 86400) * 86400
let newDate = NSDate(timeIntervalSinceReferenceDate: timeInterval)

You can also take into account time zone (this function is part of NSDate extension):

Swift 3, 4, 5

extension Date {

    func dateWithoutTime() -> Date {
        let timeZone = TimeZone.current
        let timeIntervalWithTimeZone = self.timeIntervalSinceReferenceDate + Double(timeZone.secondsFromGMT())
        let timeInterval = floor(timeIntervalWithTimeZone / 86400) * 86400
        return Date(timeIntervalSinceReferenceDate: timeInterval)
    }

}

Swift 2

extension NSDate {

    func dateWithoutTime() -> NSDate {
        let timeZone = NSTimeZone.localTimeZone()
        let timeIntervalWithTimeZone = self.timeIntervalSinceReferenceDate + Double(timeZone.secondsFromGMT)
        let timeInterval = floor(timeIntervalWithTimeZone / 86400) * 86400
        return NSDate(timeIntervalSinceReferenceDate: timeInterval)
    }

}
Murlakatam
  • 2,729
  • 2
  • 26
  • 20
  • This seems really dangerous with DST, leap years, etc? How does this account for those adjustments? – Warpling Oct 22 '21 at 08:46
  • @Warpling why do you think DST affects this method? We just get number of seconds, then calculate number of days and convert days back to seconds (and get rid of time part of the date). In the end we convert seconds back to date. What can go wrong? – Murlakatam Oct 26 '21 at 18:51
  • I can't easily give a concrete example but dividing by a "magic" number like 86400 should set off alarm bells. Not every day is exactly 86400 seconds long due to the aforementioned situations such as DST (which may cause a measured day to be shorter or longer) and leap years (in which a single day may be longer, or days fractionally). It's not *if* this won't work but *when* – that *when* is rare and highly specific but exists. – Warpling Nov 14 '21 at 17:20
4

Use This method

- (NSString *)curentDateStringFromDate:(NSDate *)dateTimeInLine withFormat:(NSString *)dateFormat {
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];

    [formatter setDateFormat:dateFormat];

    NSString *convertedString = [formatter stringFromDate:dateTimeInLine];

    return convertedString;
}

Use it Like Below

NSString *dateString = [self curentDateStringFromDate:[NSDate date] withFormat:@"dd-MM-yyyy"];
Muhammad_Awaab
  • 1,578
  • 13
  • 19
1

I implemented a Swift extension if anyone is interested. This will give you the current date (in your timezone) at 00:00:00 UTC, which I think is the meaning of current date without time.

I think it's better than @Murlakatam's answer because it doesn't involve messing with the raw timeIntervalSinceReferenceDate which is why we use date objects in the first place.

extension NSDate
{
    // Calendar objects are expensive to create to it's better to create and reuse only one.
    private static var cachedNoTimeZoneCalendar: NSCalendar = {
        let calendar = NSCalendar.currentCalendar()
        calendar.timeZone = NSTimeZone(forSecondsFromGMT: 0)
        return calendar
    }()

    func dateWithoutTime() -> NSDate?
    {
        let dateComponents = NSCalendar.currentCalendar().components([.Year, .Month, .Day], fromDate: self)
        return NSDate.cachedNoTimeZoneCalendar.dateFromComponents(dateComponents)
    }
}
deadbeef
  • 5,409
  • 2
  • 17
  • 47