How to add one month to an NSDate? - ios

How To Add Month To NSDate Object?
NSDate *someDate = [NSDate Date] + 30Days.....;

You need to use NSDateComponents:
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setMonth:1];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *newDate = [calendar dateByAddingComponents:dateComponents toDate:originalDate options:0];
[dateComponents release]; // If ARC is not used, release the date components

With iOS 8 and OS X 10.9 you can add NSCalendarUnits using NSCalendar:
Objective-C
NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *someDate = [cal dateByAddingUnit:NSCalendarUnitMonth value:1 toDate:[NSDate date] options:0];
Swift 3
let date = Calendar.current.date(byAdding: .month, value: 1, to: Date())
Swift 2
let cal = NSCalendar.currentCalendar()
let date = cal.dateByAddingUnit(.Month, value: 1, toDate: NSDate(), options: [])

For swift 3.0
extension Date {
func addMonth(n: Int) -> Date {
let cal = NSCalendar.current
return cal.date(byAdding: .month, value: n, to: self)!
}
func addDay(n: Int) -> Date {
let cal = NSCalendar.current
return cal.date(byAdding: .day, value: n, to: self)!
}
func addSec(n: Int) -> Date {
let cal = NSCalendar.current
return cal.date(byAdding: .second, value: n, to: self)!
}
}

For example, to add 3 months to the current date in Swift:
let date = NSCalendar.currentCalendar().dateByAddingUnit(.MonthCalendarUnit, value: 3, toDate: NSDate(), options: nil)!
In Swift 2.0:
let date = NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: 3, toDate: NSDate(), options: [])
The new OptionSetType structure of NSCalendarUnit lets you more simply specify .Month
Parameters that take OptionSetType (like the options: parameter, which takes NSCalendarOptions) can't be nil, so pass in an empty set ([]) to represent "no options".

In Swift 2.0
let startDate = NSDate()
let dateComponent = NSDateComponents()
dateComponent.month = 1
let cal = NSCalendar.currentCalendar()
let endDate = cal.dateByAddingComponents(dateComponent, toDate: startDate, options: NSCalendarOptions(rawValue: 0))

FOR SWIFT 3.0
here is function , you can reduce days , month ,day by any count
like for example here , i have reduced the current system date's year by 100 year , you can do it for day , month also
just set the counter and then store the values in array , and do whatever you want to do with that array
func currentTime(){
let date = Date()
let calendar = Calendar.current
var year = calendar.component(.year, from: date)
let month = calendar.component(.month, from: date)
let day = calendar.component(.day, from: date)
let pastyear = year - 100
var someInts = [Int]()
printLog(msg: "\(day):\(month):\(year)" )
for _ in pastyear...year {
year -= 1
print("\(year) ")
someInts.append(year)
}
print(someInts)
}

Other answers work fine if your desired behaviour is adding a month and allowing for daylight savings time. This produces results such that:
01/03/2017 00:00 + 1 month -> 31/03/2017 23:00
01/10/2017 00:00 + 1 month -> 01/11/2017 01:00
However I wanted to ignore the hour lost or gained by DST, such that:
01/03/2017 00:00 + 1 month -> 01/04/2017 00:00
01/10/2017 00:00 + 1 month -> 01/11/2017 00:00
So I check if a DST boundary is passed, and if so either add or subtract an hour accordingly:
func offsetDaylightSavingsTime() -> Date {
// daylightSavingTimeOffset is either + 1hr or + 0hr. To offset DST for a given date, we need to add an hour or subtract an hour
// +1hr -> +1hr
// +0hr -> -1hr
// offset = (daylightSavingTimeOffset * 2) - 1 hour
let daylightSavingsTimeOffset = TimeZone.current.daylightSavingTimeOffset(for: self)
let oneHour = TimeInterval(3600)
let offset = (daylightSavingsTimeOffset * 2) - oneHour
return self.addingTimeInterval(offset)
}
func isBetweeen(date date1: Date, andDate date2: Date) -> Bool {
return date1.compare(self).rawValue * self.compare(date2).rawValue >= 0
}
func offsetDaylightSavingsTimeIfNecessary(nextDate: Date) -> Date {
if let nextDST = TimeZone.current.nextDaylightSavingTimeTransition(after: self) {
if nextDST.isBetweeen(date: self, andDate: nextDate){
let offsetDate = nextDate.offsetDaylightSavingsTime()
let difference = offsetDate.timeIntervalSince(nextDate)
return nextDate.addingTimeInterval(difference)
}
}
return nextDate
}
func dateByAddingMonths(_ months: Int) -> Date? {
if let dateWithMonthsAdded = Calendar.current.date(byAdding: .month, value: months, to: self) {
return self.offsetDaylightSavingsTimeIfNecessary(nextDate: dateWithMonthsAdded)
}
return self
}
Test:
func testDateByAddingMonths() {
let date1 = "2017-01-01T00:00:00Z".asDate()
let date2 = "2017-02-01T00:00:00Z".asDate()
let date3 = "2017-03-01T00:00:00Z".asDate()
let date4 = "2017-04-01T00:00:00Z".asDate()
let date5 = "2017-05-01T00:00:00Z".asDate()
let date6 = "2017-06-01T00:00:00Z".asDate()
let date7 = "2017-07-01T00:00:00Z".asDate()
let date8 = "2017-08-01T00:00:00Z".asDate()
let date9 = "2017-09-01T00:00:00Z".asDate()
let date10 = "2017-10-01T00:00:00Z".asDate()
let date11 = "2017-11-01T00:00:00Z".asDate()
let date12 = "2017-12-01T00:00:00Z".asDate()
let date13 = "2018-01-01T00:00:00Z".asDate()
let date14 = "2018-02-01T00:00:00Z".asDate()
var testDate = "2017-01-01T00:00:00Z".asDate()
XCTAssertEqual(testDate, date1)
testDate = testDate.dateByAddingMonths(1)!
XCTAssertEqual(testDate, date2)
testDate = testDate.dateByAddingMonths(1)!
XCTAssertEqual(testDate, date3)
testDate = testDate.dateByAddingMonths(1)!
XCTAssertEqual(testDate, date4)
testDate = testDate.dateByAddingMonths(1)!
XCTAssertEqual(testDate, date5)
testDate = testDate.dateByAddingMonths(1)!
XCTAssertEqual(testDate, date6)
testDate = testDate.dateByAddingMonths(1)!
XCTAssertEqual(testDate, date7)
testDate = testDate.dateByAddingMonths(1)!
XCTAssertEqual(testDate, date8)
testDate = testDate.dateByAddingMonths(1)!
XCTAssertEqual(testDate, date9)
testDate = testDate.dateByAddingMonths(1)!
XCTAssertEqual(testDate, date10)
testDate = testDate.dateByAddingMonths(1)!
XCTAssertEqual(testDate, date11)
testDate = testDate.dateByAddingMonths(1)!
XCTAssertEqual(testDate, date12)
testDate = testDate.dateByAddingMonths(1)!
XCTAssertEqual(testDate, date13)
testDate = testDate.dateByAddingMonths(1)!
XCTAssertEqual(testDate, date14)
}
For completeness, the .asDate() method I'm using
extension String {
static let dateFormatter = DateFormatter()
func checkIsValidDate() -> Bool {
return self.tryParseToDate() != nil
}
func tryParseToDate() -> Date? {
String.dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
return String.dateFormatter.date(from: self)
}
func asDate() -> Date {
return tryParseToDate()!
}
}

Do you want to add a "month" or exactly 30 days or one day or one year based on user selecting automatically calculation to date.
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]
init];
[dateFormatter setDateFormat:#"YYYY-MM-dd HH:mm:ss"];
NSDateComponents *components = [calendar components:(NSCalendarUnitHour | NSCalendarUnitMinute) fromDate:[NSDate date]];
NSDateComponents *dayComponent = [[NSDateComponents alloc]
init];
int changeid = [here number of days intValue];
dayComponent.hour = changeid;
NSCalendar *theCalendar = [NSCalendar currentCalendar];
NSDate *nextDate = [theCalendar
dateByAddingComponents:dayComponent toDate:[dateFormatter
dateFromString:self.fromDateTF.text] options:0];
NSLog(#"nextDate: %# ...", nextDate);
[self.toDateTF setText:[dateFormatter
stringFromDate:nextDate]];
////month

Do you want to add a "month" or exactly 30 days? If it's 30 days, you do it like this:
// get a date
NSDate *date = [NSDate dateWithNaturalLanguageString:#"2011-01-02"];
// add 30 days to it (in seconds)
date = [date dateByAddingTimeInterval:(30 * 24 * 60 * 60)];
NSLog(#"%#", date); // 2011-02-01
Note: this will not take daylight savings time transitions or leap seconds into account. Use #TheEye's answer if you need that

Related

How to make 30 minute time intervals in swift 2.3

startTime = 10:00 AM
endTime = 01:00 PM
Now i want to split the time in the interval of 30mins like
10:00 AM 10:30 AM 11:00 AM 11:30 AM .......... till 01:00 PM.
I tried like
let startDate : NSDate! = NSDate()
let time1 : NSDate = startDate.dateByAddingTimeInterval((60*60)/2)
let time2 : NSDate = time1.dateByAddingTimeInterval((60*60)/2)
let time3 : NSDate = time2.dateByAddingTimeInterval((60*60)/2)
let time4 : NSDate = time3.dateByAddingTimeInterval((60*60)/2)
func makeTimeInterval(startTime:String ,endTime:String) -> String
{
let timeFormat = DateFormatter()
timeFormat.dateFormat = "hh:mm a"
var fromTime:NSDate = (timeFormat.date(from:startTime) as NSDate?)!
let toTime:NSDate = (timeFormat.date(from:endTime) as NSDate?)!
var dateByAddingThirtyMinute : NSDate!
let timeinterval : TimeInterval = toTime.timeIntervalSince(fromTime as Date)
let numberOfIntervals : Double = timeinterval / 3600;
var formattedDateString : String!
for _ in stride(from: 0, to: Int(numberOfIntervals * 2), by: 1)
{
dateByAddingThirtyMinute = fromTime.addingTimeInterval(1800)
fromTime = dateByAddingThirtyMinute
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "hh:mm a"
formattedDateString = dateFormatter.string(from: dateByAddingThirtyMinute! as Date) as String?
print("Time after 30 min = \(formattedDateString)")
}
return formattedDateString
}
Tried those things and i got like 10:10,10:40..etc
how to make 30 min round of interval like 10:00,10:30...etc
Thanks in advance
Use the below function if user enters anytime less than 30 than it will start with very next 30 min e.g 10:20, start from 10:30. And if user give time greater than 30 then very time will be 00 e.g 10:45, start from 11:00.
func makeTimeInterval(startTime:String ,endTime:String) -> String
{
var arr = startTime.components(separatedBy: " ")[0].components(separatedBy: ":")
let str = arr[1] as String
if (Int(str)! > 0 && Int(str)! < 30){
arr[1] = "00"
}
else if(Int(str)! > 30){
arr[1] = "30"
}
let startT:String = "\(arr.joined(separator: ":")) \(startTime.components(separatedBy: " ")[1])"
let timeFormat = DateFormatter()
timeFormat.dateFormat = "hh:mm a"
var fromTime:NSDate = (timeFormat.date(from:startT) as NSDate?)!
let toTime:NSDate = (timeFormat.date(from:endTime) as NSDate?)!
var dateByAddingThirtyMinute : NSDate!
let timeinterval : TimeInterval = toTime.timeIntervalSince(fromTime as Date)
let numberOfIntervals : Double = timeinterval / 3600;
var formattedDateString : String!
for _ in stride(from: 0, to: Int(numberOfIntervals * 2), by: 1)
{
dateByAddingThirtyMinute = fromTime.addingTimeInterval(1800)
fromTime = dateByAddingThirtyMinute
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "hh:mm a"
formattedDateString = dateFormatter.string(from: dateByAddingThirtyMinute! as Date) as String?
print("Time after 30 min = \(formattedDateString)")
}
return formattedDateString
}
You can user Calendar Components to set minutes 00 and then calculate intervals:
func getIntervals(start: String, end: String)->[Date]{
let formatter = DateFormatter()
formatter.dateFormat = "hh:mm a"
var fromDate = formatter.date(from: start)!
let calendar = Calendar(identifier: .gregorian)
let component = calendar.dateComponents([.hour, .minute], from: fromDate)
fromDate = calendar.date(bySettingHour: component.hour!, minute: 0, second: 0, of: fromDate)!
let thirtyMin: TimeInterval = 1800
let endDate = formatter.date(from: end)!
var intervals = Int(endDate.timeIntervalSince(fromDate)/thirtyMin)
intervals = intervals < 0 ? 0 : intervals
var dates = [Date]()
for x in 0...intervals{
let date = fromDate.addingTimeInterval(TimeInterval(x)*thirtyMin)
dates.append(date)
}
return dates
}
let timeIntervals = getIntervals(start: "10:10 am", end: "1:40 pm")
You can use NSDateComponents class. This class allow to get some date units. You can get minutes and hours values from the date and round the minutes to nearest "good" value (sometimes you should be change hours also).
After that you can get new date with new values of hours and minutes.
Don't forget about a time zone.
NSDate* date = [NSDate date]; //start date
NSCalendar* calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents* components = [calendar components:(NSCalendarUnitMinute | NSCalendarUnitHour) fromDate:date];
NSInteger minutes = [components minute];
NSInteger hours = [components hour];
NSInteger nearestGoodMinutes = [self _nearestGoodMinutesForMinutes:minutes];
BOOL shouldIncHours = [self _shouldINcHoursForMinutes:minutes];
if (shouldIncHours)
{
hours++;
}
NSDate* dateWithGoodHours = [calendar dateBySettingUnit:NSCalendarUnitHour value:hours ofDate:date options:kNilOptions];
NSDate* goodDate = [calendar dateBySettingUnit:NSCalendarUnitMinute value:nearestGoodMinutes ofDate:dateWithGoodHours options:kNilOptions];
Some explanation. NSDate does not contain any date components. Date components depend on current callendar. Also values of the components depent on current time zone. If you create NSCalendar with identifier, you will get calendar in current time zone. The time zone should be same with time zone that you use for displaying of the date to the user.
P.S.
You can do it only for the start date.
func format(minute: Int) {
let h = minute / 60
let m = minute % 60
timeLabel.text = "\(h.padZero()):\(m.padZero())"
}
private extension Int {
func padZero() -> String {
return String(format: "%02d", self)
}
}
Refered to this post https://github.com/onmyway133/blog/issues/340

Strange date result calculating start of next month using NSDateComponents in Swift 2

I have a function:
internal func startOfNextMonth() -> NSDate? {
guard
let cal: NSCalendar = NSCalendar.currentCalendar(),
let comp: NSDateComponents = NSDateComponents() else { return nil }
comp.month = 1
comp.day = 0
comp.to12pm()
let date = cal.dateByAddingComponents(comp, toDate: self.startOfMonth()!, options: [])!
return date
}
This should calculate the first day of next month, however it's returning 2016-03-02 08:00:00 UTC.
Is this something to do with it being a leap year (Feb. 29 messing it up?)
Here's my startOfMonth function for reference, and the to12pm() extension:
internal func startOfMonth() -> NSDate? {
guard
let cal: NSCalendar = NSCalendar.autoupdatingCurrentCalendar(),
let comp: NSDateComponents = cal.components([.Year, .Month], fromDate: self.at12pm()!) else { return nil }
comp.to12pm()
return cal.dateFromComponents(comp)!
}
internal extension NSDateComponents {
func to12pm() {
self.hour = 12
self.minute = 0
self.second = 0
}
}
internal func at12pm() -> NSDate? {
let cal = NSCalendar.currentCalendar()
return cal.dateBySettingHour(12, minute: 0, second: 0, ofDate: self, options: [])
}
startOfMonth() returns first of next month at 12 pm (12:00) then you add another 12 hours in startOfNextMonth(), this results one day ahead.
NSCalendar has a smart method to calculate the start of next month regardless of daylight saving changes or other irregularity
let calendar = NSCalendar.currentCalendar()
let components = NSDateComponents()
components.day = 1
let startOfNextMonth = calendar.nextDateAfterDate(NSDate(), matchingComponents: components, options: .MatchNextTime)
If you just want to calculate the first day of the next month, all you have to do is:
let calendar = NSCalendar.autoupdatingCurrentCalendar()
let todayComponents = calendar.components([.Year, .Month], fromDate: NSDate())
todayComponents.month += 1
let firstDayOfMonth = calendar.dateFromComponents(todayComponents)
Test:
print(firstDayOfMonth)
Prints in the console:
Optional(2016-03-01 08:00:00 +0000)
Also, if it is December, the date will overflow to January of the next year.

Returns wrong result For printing FIRST AND LAST DATE OF THE MONTH in swift

I need the first and last date of the month using current date. I have found lots of solutions for this. But all gives me wrong answer.
My code:
1. First Date of the month
extension NSDate{
func firstDateOfMonth ()->NSDate{
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Year, .Month], fromDate: self)
let startOfMonth = calendar.dateFromComponents(components)!
return startOfMonth
}
func lastDateOfmonth()->NSDate{
let calendar = NSCalendar.currentCalendar()
let comps2 = NSDateComponents()
comps2.month = 1
comps2.day = -1
let endOfMonth = calendar.dateByAddingComponents(comps2, toDate: self, options: [])!
return endOfMonth
}
}
Result looks like this:
print(NSDate().firstDateOfMonth())
print(NSDate().lastDateOfmonth())
Output:
2016-01-31 18:30:00 +0000 // instead of 2016-02-01
// prints the previous month last date
2016-03-02 06:56:17 +0000 // instead of 2016-02-29
// next month date
Please correct if anything is wrong
And I tried this code also
extension NSDate{
func firstDateOfMonths ()->NSDate{
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Era, .Year,.Month], fromDate: self)
components.day = 1
let startOfMonth = calendar.dateFromComponents(components)!
return startOfMonth
}
}
Thanks
The first problem is the common problem that you don't understand how NSDate works. NSDate returns UTC, not a date in your time zone. There are hundreds of questions explaining this.
The second problem is you being careless by getting all date components. You are adding one month minus one day to the current date.
The most reliable way to calculate days is rangeOfUnit of NSCalendar
extension NSDate {
func firstDateOfMonth() -> NSDate {
let calendar = NSCalendar.currentCalendar()
// calendar.timeZone = NSTimeZone(forSecondsFromGMT: 0) use this line if you need UTC
var startDate : NSDate?
calendar.rangeOfUnit(.Month, startDate: &startDate, interval: nil, forDate: self)
return startDate!
}
func lastDateOfMonth() -> NSDate {
let calendar = NSCalendar.currentCalendar()
// calendar.timeZone = NSTimeZone(forSecondsFromGMT: 0) use this line if you need UTC
let dayRange = calendar.rangeOfUnit(.Day, inUnit: .Month, forDate: self)
let dayLength = dayRange.length
let components = calendar.components([.Year, .Month, .Day], fromDate: self)
components.day = dayLength
return calendar.dateFromComponents(components)!
}
}
Swift 3+
In Calendar the API is named dateInterval(of:start:interval:for:
extension Date {
func firstDateOfMonth() -> Date {
let calendar = Calendar.current
var startDate = Date()
var interval : TimeInterval = 0
_ = calendar.dateInterval(of:.month, start: &startDate, interval: &interval, for: self)
return startDate
}
func lastDateOfMonth() -> Date {
let calendar = Calendar.current
let dayRange = calendar.range(of:.day, in: .month, for: self)!
let dayLength = dayRange.upperBound
var components = calendar.dateComponents([.year, .month, .day], from: self)
components.day = dayLength
return calendar.date(from:components)!
}
}

How to change the first day of week in Swift

I have made a functioning app and part of it includes formatting the date from a date picker.
I need to change the first day of the week as the week days are being displayed as "1" - "7". However, day 1 is currently Sunday and I need day 1 to be Monday and Sunday as day 7.
The code for my date formatter and picker are below:
var chosenDate = self.datePicker.date
var formatter = NSDateFormatter()
formatter.dateFormat = "ewYY"
let day = formatter.stringFromDate(chosenDate)
let dateResult = "\(day)"
DestViewController.date = dateResult
I got all of my date formatting info from this page:
http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns
I just can't seem to work out how to change this first day of the week?
Many thanks in advance
Mark.
Here is good example in how to manipulate date in swift. you can change the code to fit it better for what you may need, but right now it does what you need.
// Playground - noun: a place where people can play
// Setup the calendar object
let calendar = NSCalendar.currentCalendar()
// Set up date object
let date = NSDate()
// Create an NSDate for the first and last day of the month
let components = NSCalendar.currentCalendar().components(NSCalendarUnit.CalendarUnitMonth, fromDate: date)
components.month
// Getting the First and Last date of the month
components.day = 1
let firstDateOfMonth: NSDate = calendar.dateFromComponents(components)!
components.month += 1
components.day = 0
let lastDateOfMonth: NSDate = calendar.dateFromComponents(components)!
var unitFlags = NSCalendarUnit.WeekOfMonthCalendarUnit |
NSCalendarUnit.WeekdayCalendarUnit |
NSCalendarUnit.CalendarUnitDay
let firstDateComponents = calendar.components(unitFlags, fromDate: firstDateOfMonth)
let lastDateComponents = calendar.components(unitFlags, fromDate: lastDateOfMonth)
// Sun = 1, Sat = 7
let firstWeek = firstDateComponents.weekOfMonth
let lastWeek = lastDateComponents.weekOfMonth
let numOfDatesToPrepend = firstDateComponents.weekday - 1
let numOfDatesToAppend = 7 - lastDateComponents.weekday + (6 - lastDateComponents.weekOfMonth) * 7
let startDate: NSDate = calendar.dateByAddingUnit(NSCalendarUnit.CalendarUnitDay, value: -numOfDatesToPrepend, toDate: firstDateOfMonth, options: nil)!
let endDate: NSDate = calendar.dateByAddingUnit(NSCalendarUnit.CalendarUnitDay, value: numOfDatesToAppend, toDate: lastDateOfMonth, options: nil)!
Array(map(0..<42) {
calendar.dateByAddingUnit(NSCalendarUnit.CalendarUnitDay, value: $0, toDate: startDate, options: nil)!
})
"\(components.year)"
//var dateString = stringFromDate(NSDate())// change to your date format
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "EE"
var dateString = dateFormatter.stringFromDate(NSDate())
var xdate = dateFormatter.dateFromString(dateString)
//var someDate = dateFormatter.dateString
println(dateString)
this will output::
"Thu"

Minimum and maximum date in UIDatePicker

I want to get the minimum and maximum date from a date picker, but minimum date should be "- 18" of the current date and the maximum date should be "- 100" of current date.
Suppose current year is 2018 then I want minimum date 2000 and maximum date 1918.
What I have done so far is :
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorian components:NSYearCalendarUnit fromDate:[NSDate date]];
NSInteger year = [components year];
int mindt = year - 18;
int maxdt = year -100;
// NSDate * MinDate = [components year] - 18;
// NSDate * MaxDate = [components year] - 100;
// self.datePicker.minimumDate = MinDate;
// self.datePicker.maximumDate = MaxDate;
but I cant get this integer to my date format..
Try this:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *currentDate = [NSDate date];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setYear:-18];
NSDate *minDate = [gregorian dateByAddingComponents:comps toDate:currentDate options:0];
[comps setYear:-150];
NSDate *maxDate = [gregorian dateByAddingComponents:comps toDate:currentDate options:0];
[comps release];
self.datePicker.minimumDate = minDate;
self.datePicker.maximumDate = maxDate;
It may be easily translated to Swift 4.2:
let calendar = Calendar(identifier: .gregorian)
let currentDate = Date()
var components = DateComponents()
components.calendar = calendar
components.year = -18
components.month = 12
let maxDate = calendar.date(byAdding: components, to: currentDate)!
components.year = -150
let minDate = calendar.date(byAdding: components, to: currentDate)!
picker.minimumDate = minDate
picker.maximumDate = maxDate
Look at this for Swift version.
User negative value (-) to subtract and positive value to add date component.
1. Set minimum date
yourDatePicker.minimumDate = Calendar.current.date(byAdding: .year, value: -1, to: Date())
2. Set maximum date
yourDatePicker.maximumDate = Calendar.current.date(byAdding: .year, value: 1, to: Date())
Swift 5.1
extension UIDatePicker {
func set18YearValidation() {
let currentDate: Date = Date()
var calendar: Calendar = Calendar(identifier: Calendar.Identifier.gregorian)
calendar.timeZone = TimeZone(identifier: "UTC")!
var components: DateComponents = DateComponents()
components.calendar = calendar
components.year = -18
let maxDate: Date = calendar.date(byAdding: components, to: currentDate)!
components.year = -150
let minDate: Date = calendar.date(byAdding: components, to: currentDate)!
self.minimumDate = minDate
self.maximumDate = maxDate
} }
This is how it would look like in 2017 (Swift 3)
var components = DateComponents()
components.year = -100
let minDate = Calendar.current.date(byAdding: components, to: Date())
components.year = -18
let maxDate = Calendar.current.date(byAdding: components, to: Date())
datePicker.minimumDate = minDate
datePicker.maximumDate = maxDate
In Swift 2.1:
let currentDate: NSDate = NSDate()
let calendar: NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
// let calendar: NSCalendar = NSCalendar.currentCalendar()
calendar.timeZone = NSTimeZone(name: "UTC")!
let components: NSDateComponents = NSDateComponents()
components.calendar = calendar
components.year = -18
let minDate: NSDate = calendar.dateByAddingComponents(components, toDate: currentDate, options: NSCalendarOptions(rawValue: 0))!
components.year = -150
let maxDate: NSDate = calendar.dateByAddingComponents(components, toDate: currentDate, options: NSCalendarOptions(rawValue: 0))!
self.dateOfBirthUIDatePicker.minimumDate = minDate
self.dateOfBirthUIDatePicker.maximumDate = maxDate
print("minDate: \(minDate)")
print("maxDate: \(maxDate)")
Swift 3.0
let gregorian: NSCalendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)!
let currentDate: Date = Date()
let components: NSDateComponents = NSDateComponents()
components.year = -150
let minDate: Date = gregorian.date(byAdding: components as DateComponents, to: currentDate, options: NSCalendar.Options(rawValue: 0))!
components.year = -16
let maxDate: Date = gregorian.date(byAdding: components as DateComponents, to: currentDate, options: NSCalendar.Options(rawValue: 0))!
self.datepicker.minimumDate = minDate
self.datepicker.maximumDate = maxDate
**Minimum and maximum date in UIDatePicker: #Swift
**if you want to select the min and max date between two date value use below simple code: **
for Example : Min Date : 01-04-2017 and Max Date : 31-03-2018
let calendar = Calendar.current
var minDateComponent = calendar.dateComponents([.day,.month,.year], from: Date())
minDateComponent.day = 01
minDateComponent.month = 04
minDateComponent.year = 2017
let minDate = calendar.date(from: minDateComponent)
print(" min date : \(String(describing: minDate))")
var maxDateComponent = calendar.dateComponents([.day,.month,.year], from: Date())
maxDateComponent.day = 0
maxDateComponent.month = 03 + 1
maxDateComponent.year = 2018
let maxDate = calendar.date(from: maxDateComponent)
print("max date : \(String(describing: maxDate))")
picker.minimumDate = minDate! as Date
picker.maximumDate = maxDate! as Date
In Objective C,
NSDateComponents *comps = [[NSDateComponents alloc] init];
NSDateComponents *components = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]];
NSInteger year = components.year;
NSInteger month = components.month;
NSInteger day = components.day;
NSInteger minimumYear = year - 1900;//Given some year here for example
NSInteger minimumMonth = month - 1;
NSInteger minimumDay = day - 1;
[comps setYear:-minimumYear];
[comps setMonth:-minimumMonth];
[comps setDay:-minimumDay];
NSDate *minDate = [calendar dateByAddingComponents:comps toDate:currentDate options:0];
[datePicker setMinimumDate:minDate];
[datePicker setMaximumDate:[NSDate date]];
The minimum date would be January 01 1900. I hope it works for you all.. :)
In Swift 2.0 or later
let calendar = NSCalendar(calendarIdentifier:NSCalendarIdentifierGregorian);
let todayDate = NSDate()
let components = calendar?.components([NSCalendarUnit.Year,NSCalendarUnit.Month,NSCalendarUnit.Day], fromDate: todayDate)
let minimumYear = (components?.year)! - 1900
let minimumMonth = (components?.month)! - 1
let minimumDay = (components?.day)! - 1
let comps = NSDateComponents();
comps.year = -minimumYear
comps.month = -minimumMonth
comps.day = -minimumDay
let minDate = calendar?.dateByAddingComponents(comps, toDate: todayDate, options: NSCalendarOptions.init(rawValue: 0))
datePicker.minimumDate = minDate
datePicker.maximumDate = datePicker.date
Swift 4.1
I have created my extension for all type of limit based on Calendar.Component
extension UIDatePicker {
func setLimit(forCalendarComponent component:Calendar.Component, minimumUnit min: Int, maximumUnit max: Int) {
let currentDate: Date = Date()
var calendar: Calendar = Calendar(identifier: Calendar.Identifier.gregorian)
guard let timeZone = TimeZone(identifier: "UTC") else { return }
calendar.timeZone = timeZone
var components: DateComponents = DateComponents()
components.calendar = calendar
components.setValue(-min, for: component)
if let maxDate: Date = calendar.date(byAdding: components, to: currentDate) {
self.maximumDate = maxDate
}
components.setValue(-max, for: component)
if let minDate: Date = calendar.date(byAdding: components, to: currentDate) {
self.minimumDate = minDate
}
}
}
We can use this as following:
self.datePicker.setLimit(forCalendarComponent: .year, minimumUnit: 13, maximumUnit: 100)
Another case :
Suppose I want to show Date of birth as a Date picker, Dob is within the range of 1/1/1980 to  1/1/2000.
#IBOutlet var datePicker: UIDatePicker!
override func viewDidLoad() {
super.viewDidLoad()
datePicker.datePickerMode = UIDatePickerMode.date
// 01/01/1980 to 01/01/2000
let calendar = Calendar.current
var minDateComponent = calendar.dateComponents([.day,.month,.year], from: Date())
minDateComponent.day = 01
minDateComponent.month = 01
minDateComponent.year = 1980
let minDate = calendar.date(from: minDateComponent)
print(" min date : \(minDate)")
var maxDateComponent = calendar.dateComponents([.day,.month,.year], from: Date())
maxDateComponent.day = 01
maxDateComponent.month = 01
maxDateComponent.year = 2000
let maxDate = calendar.date(from: maxDateComponent)
print("max date : \(maxDate)")
self.datePicker.minimumDate = minDate! as Date
self.datePicker.maximumDate = maxDate! as Date
}
Swift 4.0
UIDatePicker Extension
extension UIDatePicker {
func set18YearValidation() {
let currentDate: NSDate = NSDate()
let calendar: NSCalendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)!
calendar.timeZone = NSTimeZone(name: "UTC")! as TimeZone
let components: NSDateComponents = NSDateComponents()
components.calendar = calendar as Calendar
components.year = -18
let maxDate: NSDate = calendar.date(byAdding: components as DateComponents, to: currentDate as Date, options: NSCalendar.Options(rawValue: 0))! as NSDate
components.year = -150
let minDate: NSDate = calendar.date(byAdding: components as DateComponents, to: currentDate as Date, options: NSCalendar.Options(rawValue: 0))! as NSDate
self.minimumDate = minDate as Date
self.maximumDate = maxDate as Date
} }
if you want to set current date as minimum value for date picker, use this line of code:
datePicker.minimumDate = Date()

Resources