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()
Related
I have a problem with the creation of dates and the timezone of the device which causes problems in my unit tests.
Here my code to create a date:
private func createDate(weekday: Int, hour: Int, minute: Int)->Date{
var components = DateComponents()
components.hour = hour
components.minute = minute
components.year = 2016
components.weekday = weekday
components.weekdayOrdinal = 10
components.timeZone = TimeZone(abbreviation: "CET")
var cal = Calendar.current
cal.timeZone = TimeZone(abbreviation: "CET")!
return cal.date(from: components)!
}
Here my test where I create a date on a Monday 0:01 in TimeZone Paris:
func testMon0001(){
let date = createDate(weekday: 2, hour: 00, minute: 01)
let unitFlags : Set<Calendar.Component> = [.era, .hour, .minute, .day, .month, .year, .timeZone, .weekday]
var components = Calendar.current.dateComponents(unitFlags, from: date)
components.timeZone = TimeZone(abbreviation: "CET")
guard let hour = components.hour else {
[...]
}
[...]
}
In the end hour is 16 if the device is running on timezone Vancouver which is not correct. The date object is "2016-03-06 23:01:00 +0000"
What do I have to do to ignore the devices timezone?
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
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"
I have dateformat string like this "2015-03-09".How do i get next 10 days date from current date?any help will be appreciated.thanks in advance
For a purely Swift 3 solution:
Calendar.current.date(byAdding: .day, value: 10, to: Date())
Here's how to get a date 10 days from now, using built-in date modification method .dateByAddingUnit
If all 10 days (dates) are required, can be looped by "value:10" part and added to array.
var tenDaysfromNow: NSDate {
return NSCalendar.currentCalendar().dateByAddingUnit(.Day, value: 10, toDate: NSDate(), options: [])!
}
print(tenDaysfromNow)
And for Swift3:
var tenDaysfromNow: Date {
return (Calendar.current as NSCalendar).date(byAdding: .day, value: 10, to: Date(), options: [])!
}
You can use the dateByAddingTimeInterval() method for this.
var dateStr = "2015-03-09"
var formatter = NSDateFormatter()
formatter.dateFormat = "YYYY-MM-dd"
var currDate = formatter.dateFromString(dateStr)
for i in 1...10
{
var interval = NSTimeInterval(60 * 60 * 24 * i)
var newDate = currDate?.dateByAddingTimeInterval(interval)
println(newDate)
}
EDIT:
As mentioned by #Martin R in the comments, it'll be better to use dateByAddingComponents() of NSCalendar class:
var calendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)
var dateComponent = NSDateComponents()
for i in 1...10
{
dateComponent.day = i
var newDate = calendar?.dateByAddingComponents(dateComponent, toDate: currDate!, options:nil)
println(newDate)
}
There is a function 'dateByAddingTimeInterval()' for an NSDate object. With this, you can create a NSDate from your date string. Then add 10 days = 10*24*60*60 to get next 10 days NSDate value
let today : NSDate = ....
let next10days = today.dateByAddingTimeInterval(10*60*60*24); //interval = seconds
//then you convert back to your date string format if you want, by using NSDateFormatter
To avoid problem with Daylighttime saving (#MartinR):
let cal = NSCalendar(calendarIdentifier: NSGregorianCalendar)
let next10Days = cal.dateByAddingUnit(NSCalendarUnit.DayCalendarUnit, value: 10, toDate: today, options: nil)
Here is a swift 4/5 version of the answer by #MidhunMP
var dateStr = "2015-03-09"
var formatter = DateFormatter()
formatter.dateFormat = "YYYY-MM-dd"
var calendar = Calendar(identifier: .gregorian)
var dateComponent = DateComponents()
if let currDate = formatter.date(from: dateStr) {
for i in 1...10 {
let newDate = calendar.date(byAdding: .day, value: i, to: currDate)
print(newDate)
}
}
For Swift 3:
let now = NSDate()
let plusTen = now.dateByAddingDays(10)
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