2

I have several Strings that say "Tonight at 8PM" or "Tonight at 6PM" and I need to find out how to get them converted to NSDates. I need the Format to be yyyy/mm/dd/hh.

Update:

Now I'm getting the wrong year returned. I'm getting 9223372036854775807 for year.

let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Month, .Day, .Year], fromDate:NSDate())
let year =  components.year
let month = components.month
let day = components.day

let NSDateString = "\(month)/\(day)/\(year) at \(date.chopPrefix(11))"
print(NSDateString)
luk2302
  • 55,258
  • 23
  • 97
  • 137
swiftyboi
  • 2,965
  • 4
  • 25
  • 52
  • Phew, I doubt there is anything built-in you can use. That is a very non-trivial task for which you probably have to search for some 3rd party api. I would be happy to be corrected ;) – luk2302 Oct 04 '15 at 13:05
  • 1
    Unless of course your strings are really all that similar, can you give more examples please? – luk2302 Oct 04 '15 at 13:06
  • Literally, they will only ever say "Tonight at (someTimePM)". They won't even say "Today at (someTimePM)" – swiftyboi Oct 04 '15 at 13:07
  • Okay, then it is quite easy, have you tried playing around with the `NSDateFormatter`! – luk2302 Oct 04 '15 at 13:08
  • I've been playing around with it. I think I've just about got it. Thanks for the suggestion! – swiftyboi Oct 04 '15 at 13:19
  • I'd just lop off everything but `"(someTimePM)"` and now your problem is much simpler. You already know the `yyyy/mm/dd` is equal to *now*. – nhgrif Oct 04 '15 at 13:28
  • Yup, that's what I'm working on, however, I'm getting the wrong year returned. It's giving me 9223372036854775807 as the year. I'll update my post with the code. – swiftyboi Oct 04 '15 at 13:29
  • @BK are you running it on the simulator, playground or a real device? Your code as well as my code both work. Maybe your date is somehow screwed up :/ In the first two cases try restarting xcode or the simulator. – luk2302 Oct 04 '15 at 13:40
  • I'm running it in the simulator... I'm about to test on a device to make sure the simulator's date isn't messed up. – swiftyboi Oct 04 '15 at 13:43
  • Nope, I'm still getting the wrong year on my phone. I'll keep investigating. – swiftyboi Oct 04 '15 at 13:48
  • 1
    That number refers to `NSDateComponentUndefined`. Put it in a playground to see that it's the same big number. – Abizern Oct 04 '15 at 14:01
  • Thank you, I've figured it out. Long story short, I forgot to put .Year into my calendar components. – swiftyboi Oct 04 '15 at 14:02
  • 1
    Also, you don't need to use calendar components or even parse this yourself. As I've shown in my answer. – Abizern Oct 04 '15 at 14:28
  • 1
    @luk2302 You'll be happy, then, to hear of the NSDataDetector class. – Abizern Oct 04 '15 at 14:44
  • @Abizern in fact I am, awesome! – luk2302 Oct 04 '15 at 15:41

2 Answers2

3

You don't need to do the parsing yourself. There is the handy NSDataDetector class that does this for you:

let string = "Tonight at 7pm"

// Create an NSDataDetector that looks for dates
let detector = try! NSDataDetector(types: NSTextCheckingType.Date.rawValue)

// Create an array of all the possible matches
let matches = detector.matchesInString(string, options: [], range: NSMakeRange(0, string.utf16.count))

// Since you are only expecting one date, extract it.
if let date = matches.first?.date  {
    print("\(date)")
} else {
    print("No matches found")
}

This takes care of locales for you. For example - where I am this gives the resulting date of:

"2015-10-04 18:00:00 +0000"

This gives you a nice raw NSDate instance which you can store or provide as formatted output as you wish.

Also this doesn't tie you in to just "today". Put this code in a playground and try such things as:

let string = "Wednesday at 7pm"

or

let string = "Yesterday at 7pm"

or

let string = "tomorrow morning at 2"

Which all return valid dates.

Abizern
  • 146,289
  • 39
  • 203
  • 257
2

What I have got working now is the following:

let inputString = "Tonight at 6PM"

let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Year, .Month, .Day], fromDate: NSDate())

let dfm = NSDateFormatter()
dfm.dateFormat = "'Tonight at' hha"

let inputDate = dfm.dateFromString(inputString)!
let hour = calendar.components(.Hour, fromDate: inputDate).hour

let outputDate = calendar.dateFromComponents(components)?.dateByAddingTimeInterval(Double(hour * 60 * 60))

Outputting:

Oct 4, 2015, 6:00 PM

A different approach would be to append the today date to the input string and then parse that all together again.

luk2302
  • 55,258
  • 23
  • 97
  • 137