Sample code is following:
//: Playground - noun: a place where people can play
import Foundation
let timeZone = NSTimeZone(name: "PST")!
// Make Results Sidebar to display in PST
NSTimeZone.setDefaultTimeZone(timeZone)
let cal = NSCalendar(identifier: NSCalendarIdentifierGregorian)!
let comp = NSDateComponents()
comp.calendar = cal
comp.timeZone = timeZone
comp.era = 1
comp.year = 2015
comp.month = 7
comp.day = 24
comp.hour = 11
comp.minute = 27
comp.second = 0
comp.nanosecond = 0
let d = cal.dateFromComponents(comp)! // "2015/07/24 11:27"
//: getting past date
var u: NSCalendarUnit, v: Int
// I wish "2015/07/24 11:00"
u = .Minute
v = 0
// Using dateBySettingUnit fails
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .WrapComponents) // "2015/07/24 12:00"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchStrictly) // "2015/07/24 12:00"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .SearchBackwards) // "2015/07/24 12:00"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchPreviousTimePreservingSmallerUnits) // "2015/07/24 12:00"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchNextTimePreservingSmallerUnits) // "2015/07/24 12:00"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchNextTime) // "2015/07/24 12:00"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchFirst) // "2015/07/24 12:00"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchLast) // "2015/07/24 12:00"
// Using nextDateAfterDate fails. Yes, it's intended.
cal.nextDateAfterDate(d, matchingUnit: u, value: v, options: .MatchPreviousTimePreservingSmallerUnits) // "2015/07/24 12:00"
cal.nextDateAfterDate(d, matchingUnit: u, value: v, options: .MatchNextTimePreservingSmallerUnits) // "2015/07/24 12:00"
cal.nextDateAfterDate(d, matchingUnit: u, value: v, options: .MatchNextTime) // "2015/07/24 12:00"
// I wish "2015/07/24 11:13"
v = 13
// Using dateBySettingUnit fails
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .WrapComponents) // "2015/07/25 0:00"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchStrictly) // "2015/07/25 0:00"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .SearchBackwards) // "2015/07/25 0:00"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchPreviousTimePreservingSmallerUnits) // "2015/07/25 0:00"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchNextTimePreservingSmallerUnits) // "2015/07/25 0:00"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchNextTime) // "2015/07/25 0:00"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchFirst) // "2015/07/25 0:00"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchLast) // "2015/07/25 0:00"
// Using nextDateAfterDate fails. Yes, it's intended, but something wrongs…
cal.nextDateAfterDate(d, matchingUnit: u, value: v, options: .MatchPreviousTimePreservingSmallerUnits) // "2015/07/24 13:13"
cal.nextDateAfterDate(d, matchingUnit: u, value: v, options: .MatchNextTimePreservingSmallerUnits) // "2015/07/25 0:00"
cal.nextDateAfterDate(d, matchingUnit: u, value: v, options: .MatchNextTime) // "2015/07/25 0:00"
//: getting future date
// I wish "2015/07/24 11:28"
v = 28
// Using dateBySettingUnit successes
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .WrapComponents) // "2015/07/24 11:28"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchStrictly) // "2015/07/24 11:28"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .SearchBackwards) // "2015/07/24 11:28"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchPreviousTimePreservingSmallerUnits) // "2015/07/24 11:28"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchNextTimePreservingSmallerUnits) // "2015/07/24 11:28"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchNextTime) // "2015/07/24 11:28"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchFirst) // "2015/07/24 11:28"
cal.dateBySettingUnit(u, value: v, ofDate: d, options: .MatchLast) // "2015/07/24 11:28"
// Using nextDateAfterDate successes. Yes, it's intended
cal.nextDateAfterDate(d, matchingUnit: u, value: v, options: .MatchPreviousTimePreservingSmallerUnits) // "2015/07/24 11:28"
cal.nextDateAfterDate(d, matchingUnit: u, value: v, options: .MatchNextTimePreservingSmallerUnits) // "2015/07/24 11:28"
cal.nextDateAfterDate(d, matchingUnit: u, value: v, options: .MatchNextTime) // "2015/07/24 11:28"
Is this intended behavior?