0

I have a struct such as :

struct AdData {
    var AdRequest = Int?()
    var Date = NSDate?() // eg: 2015-11-01 04:00:00 +0000
}

And an array of AdData:

var RawDataFromDb = [AdData]()

I want to find the all the items in RawDataFromDb where Date matches today's date. I figured I somehow have to remove the time component of the AdData Date component to compare only the date, but I'm struggling to find an elegant solution.

So far I tried this without success :

public func ==(lhs: NSDate, rhs: NSDate) -> Bool {
    return lhs === rhs || lhs.compare(rhs) == .OrderedSame
}

public func <(lhs: NSDate, rhs: NSDate) -> Bool {
    return lhs.compare(rhs) == .OrderedAscending
}

extension NSDate: Comparable { }


let TodayDate = NSDate()
let TodayRows = RawDataFromDb.filter{($0.Date == TodayDate}

Thank you for your help !

anto0522
  • 652
  • 8
  • 30
  • Explain what you think "where Date matches today's date" means. Do you mean that its day, irrespective of time, should be same as today's day, irrespective of time? – matt Nov 04 '15 at 19:31
  • Yes that's exactly it ! Sorry I wasn't very clear – anto0522 Nov 04 '15 at 19:34
  • 1
    I am pretty sure that you'll find a solution in the answers to the referenced thread, e.g. using `isDateInToday` from this answer: http://stackoverflow.com/a/25538987/1187415. Otherwise let me know and I'll reopen the question. – Martin R Nov 04 '15 at 19:38
  • Hi Martin, thank you for the link. Although it does give some useful information, I suggest we leave this thread open as it relates specifically to Structs and the answers given here differ significantly from the ones in the post you have linked. – anto0522 Nov 04 '15 at 19:49

2 Answers2

1

Based on Martin R's comment and link you can just use isDateInToday! Which is very simple

You could try something like this:

let gregorianCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!

let TodayRows = RawDataFromDb.filter{
    return self.gregorianCalendar.isDateInToday($0.Date)
}

As for the equals comparable I like to use:

extension NSDate: Comparable { }

public func ==(leftDate: NSDate, rightDate: NSDate) -> Bool {
    return leftDate.isEqualToDate(rightDate)
}

If you use this, instead of isDateInToday you would need to set Today's and struct.Date's hours to 12 (in order to compare dates that land on the first day of daylights savings) and minutes/seconds to zero. Since the hours,minutes, and seconds do effect the comparison.

So for example:

let gregorianCalendar: NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let today: NSDate = gregorianCalendar.dateBySettingHour(12, minute: 0, second: 0, ofDate: NSDate(), options: NSCalendarOptions())!

let TodayRows = RawDataFromDb.filter{
    let structDate = self.gregorianCalendar.dateBySettingHour(12, minute: 0, second: 0, ofDate: NSDate(), options: NSCalendarOptions())!
    return structDate == self.today
}
Community
  • 1
  • 1
boidkan
  • 4,301
  • 4
  • 27
  • 42
  • 2
    You should use 12pm instead of 12am for this type of comparison since not everyday starts at 12am – Leo Dabus Nov 04 '15 at 19:49
  • Could you explain further? :) Thanks! – boidkan Nov 04 '15 at 19:50
  • Daylight savings time – Leo Dabus Nov 04 '15 at 19:51
  • So what you are saying is that the gregorian calendar is no good for daylights savings? – boidkan Nov 04 '15 at 19:58
  • Nothing to do with the calendar that has its own methods for comparing dates isDateInToday or isDate inSameDayAs – Leo Dabus Nov 04 '15 at 20:03
  • Ok. Could you be more direct please on what you mean by using 12pm! – boidkan Nov 04 '15 at 20:12
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/94241/discussion-between-boidkan-and-leo-dabus). – boidkan Nov 04 '15 at 20:12
  • Everyday has 12pm but not everyday has 12am – Leo Dabus Nov 04 '15 at 20:12
  • 1
    Oh right. The wheels slowly turned haha ;) So instead of setting hours to zero set them to 12. Obrigado – boidkan Nov 04 '15 at 20:16
  • After thinking about this longer I have a few questions. First of all doesn't the switch over happen at 2am U.S and 1am EU. Secondly, how would this effect two dates that you set the hours, minutes, and seconds to zero? Unless NSDate does not allow you to set the hour for the date to zero you should be fine when comparing? Also I though NSDate didn't care about timezones and such. – boidkan Nov 04 '15 at 21:29
  • @boidjan 0 hour of the day can be 1am – Leo Dabus Nov 04 '15 at 21:30
  • Right but the switch doesnt happen until 2am. This is what I got when playing with 2015-11-01 and setting the hour to 0, 1, and 2: `2015-11-01 05:00:00 +0000` `2015-11-01 06:00:00 +0000` `2015-11-01 08:00:00 +0000` Chat? So we don't spam here? :) – boidkan Nov 04 '15 at 21:32
  • See page 37 http://devstreaming.apple.com/videos/wwdc/2013/227xax5xif2s7s531dsmfs1afo2/227/227.pdf – Leo Dabus Nov 04 '15 at 21:44
  • Thanks, found the video and watching now. :) – boidkan Nov 04 '15 at 22:13
1

Most simply, for just today:

let calendar = NSCalendar.autoupdatingCurrentCalendar()

let targetData = rawData.filter({
  $0.date != nil && calendar.isDateInToday($0.date!)
})

For an arbitrary day:

let calendar = NSCalendar.autoupdatingCurrentCalendar()

let targetDate = NSDate(timeIntervalSince1970: 123456789)

let targetData = rawData.filter({
  $0.date != nil && calendar.isDate($0.date!, inSameDayAsDate: targetDate)
})
rob mayoff
  • 342,380
  • 53
  • 730
  • 766