Is there any methods available for NSDate/NSCalendar to calculate the number of days in the current month and current year ?
The only thing I saw is to get the number of days from a given date or between two dates.
Is this the only way ?
Here is a method which works for both months and years:
let calendar = NSCalendar.currentCalendar()
let date = NSDate()
// Calculate start and end of the current year (or month with `.Month`):
var startOfInterval : NSDate?
var lengthOfInterval = NSTimeInterval()
calendar.rangeOfUnit(.Year, startDate: &startOfInterval, interval: &lengthOfInterval, forDate: date)
let endOfInterval = startOfInterval!.dateByAddingTimeInterval(lengthOfInterval)
// Compute difference in days:
let days = calendar.components(.Day, fromDate: startOfInterval!, toDate: endOfInterval, options: [])
print(days)
(You may want to add some error checking instead of forcibly unwrapping
optionals.)
Update for Swift 3:
let calendar = Calendar.current
let date = Date()
// Calculate start and end of the current year (or month with `.month`):
let interval = calendar.dateInterval(of: .year, for: date)!
// Compute difference in days:
let days = calendar.dateComponents([.day], from: interval.start, to: interval.end).day!
print(days)
let date = NSDate()
let cal = NSCalendar(calendarIdentifier:NSCalendarIdentifierGregorian)!
let days = cal.rangeOfUnit(.Day, inUnit: .Month, forDate: date)
print("\(days) in the month of \(date)")
Related
I am able to next 15 days date from current date, but when i tried to give custom date instead of current date, it not working.
let date = sharedAppDelegate.dueDate
let givenDate = Utility.convertStringToDate(format: "yyyy-MM-dd",
dateString: date)
let futureDate = (givenDate as NSCalendar).date(byAdding: dateComponents, to: Date()) ?? Date()
Third line gives error like Date? is not convertible to NSCalendar.
Expected result:- futureDate should be next 15 date from givenDate
A Date is not a Calendar
You can use the Calendar to do calculations or comparisons on Date objects, in your case you want to use the Calendar to add x number of days to your starting date
Try
let startDate = Date()
let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: startDate)
print(tomorrow)
OUTPUT:
Optional(2019-06-01 07:14:48 +0000)
You can extend Date class like this.
extension Date {
func dateByAddingDays(dateNum:Int) -> Date {
return Calendar.gregorian.date(byAdding: .day, value: dateNum, to: self)!
}
}
Now create date object
let today = Date()
let dayAfterTomorrow = today.dateByAddingDays(dateNum:2)
debugPrint(dayAfterTomorrow)
Im new at swift programming and i havent been able successfully find code to find difference between two dates in terms of years , months and days.
I tried the following code but it didnt work
let form = NSDateComponentsFormatter()
form.maximumUnitCount = 2
form.unitsStyle = .Full
let s = form.stringFromTimeInterval( date2.timeIntervalSinceReferenceDate - date1.timeIntervalSinceReferenceDate)
Input
Date1 = "12/March/2015"
Date2 = "1/June/2015"
Output : x years y months z days
Please advice
We can use this function in Swift 2.0
func yearsBetweenDate(startDate: NSDate, endDate: NSDate) -> Int
{
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Year], fromDate: startDate, toDate: endDate, options: [])
return components.year
}
You can return anything like I returned year in this function. This will return number of years between the two dates.
You can just write months,days etc in order to find the difference between the two dates in months and days respectively.
Edit
Swift 3.0 and Above
func yearsBetweenDate(startDate: Date, endDate: Date) -> Int {
let calendar = Calendar.current
let components = calendar.dateComponents([.year], from: startDate, to: endDate)
return components.year!
}
If you need the difference (in years, months, days) numerically then
compute NSDateComponents as in Swift days between two NSDates or Rajan's answer.
If you need the difference as a (localized) string to present it to the user,
then use NSDateComponentsFormatter like this
let form = NSDateComponentsFormatter()
form.maximumUnitCount = 2
form.unitsStyle = .Full
form.allowedUnits = [.Year, .Month, .Day]
let s = form.stringFromDate(date1, toDate: date2)
As already mentioned in the comments, computing the difference
from the pure time interval between the dates cannot give correct
results because most information about the dates is lost.
Update for Swift 3:
let form = DateComponentsFormatter()
form.maximumUnitCount = 2
form.unitsStyle = .full
form.allowedUnits = [.year, .month, .day]
let s = form.string(from: date1, to: date2)
With Swift 5 and iOS 12, you can use one of the 3 solutions below in order to calculate the difference (in years, months, days) between two dates.
#1. Using Calendar's dateComponents(_:from:to:) method
Calendar has a method called dateComponents(_:from:to:). dateComponents(_:from:to:) has the following declaration:
func dateComponents(_ components: Set<Calendar.Component>, from start: DateComponents, to end: DateComponents) -> DateComponents
Returns the difference between two dates specified as DateComponents.
The Playground example below show how to use dateComponents(_:from:to:) in order to compute the difference between two dates:
import Foundation
let calendar = Calendar.current
let startComponents = DateComponents(year: 2010, month: 11, day: 22)
let endComponents = DateComponents(year: 2015, month: 5, day: 1)
let dateComponents = calendar.dateComponents([.year, .month, .day], from: startComponents, to: endComponents)
print(dateComponents) // prints: year: 4 month: 5 day: 9 isLeapMonth: false
#2. Using Calendar's dateComponents(_:from:to:) method
Calendar has a method called dateComponents(_:from:to:). dateComponents(_:from:to:) has the following declaration:
func dateComponents(_ components: Set<Calendar.Component>, from start: Date, to end: Date) -> DateComponents
Returns the difference between two dates.
The Playground example below show how to use dateComponents(_:from:to:) in order to compute the difference between two dates:
import Foundation
let calendar = Calendar.current
let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!
let dateComponents = calendar.dateComponents([.year, .month, .day], from: startDate, to: endDate)
print(dateComponents) // prints: year: 4 month: 5 day: 9 isLeapMonth: false
#3. Using DateComponentsFormatter's string(from:to:) method
DateComponentsFormatter has a method called string(from:to:). string(from:to:) has the following declaration:
func string(from startDate: Date, to endDate: Date) -> String?
Returns a formatted string based on the time difference between two dates.
The Playground example below show how to use string(from:to:) in order to compute the difference between two dates:
import Foundation
let calendar = Calendar.current
let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.allowedUnits = [.year, .month, .day]
let string = formatter.string(from: startDate, to: endDate)!
print(string) // prints: 4 years, 5 months, 9 days
Try this one
func calculateDiffInTwoDate (date1: NSDate, date2: NSDate) -> NSInteger {
//var userAge : NSInteger = 0
let calendar : NSCalendar = NSCalendar.currentCalendar()
let unitFlags : NSCalendarUnit = [ .Year , .Month, .Day]
let dateComponentNow : NSDateComponents = calendar.components(unitFlags, fromDate: date2)
let dateComponentBirth : NSDateComponents = calendar.components(unitFlags, fromDate: date1)
if ( (dateComponentNow.month < dateComponentBirth.month) ||
((dateComponentNow.month == dateComponentBirth.month) && (dateComponentNow.day < dateComponentBirth.day))
)
{
return dateComponentNow.year - dateComponentBirth.year - 1
}
else {
return dateComponentNow.year - dateComponentBirth.year
}
}
By This you can get diff between two dates in Years
Why don't you use the inbuild method to find the difference between 2 dates in seconds, and then write a method to convert seconds in terms of years, months and days.
let diff = date1.timeIntervalSinceDate(date2)
//Assigning Dates
let StartDate = datePicker.date
let currentDate = Date()
//Finding Difference of Dates
let components = Set<Calendar.Component>([.day, .month, .year])
let differenceOfDate = Calendar.current.dateComponents(components, from:
StartDate, to: currentDate)
Print(differenceOfDate)
Goord Morning all together,
i have an app with ios 8 and swift.
in there is a UIViewcontroller within a UIDatepicker
I set a minimum date. for example the date of today: 2 | May | 2015
with this solution it should not be possible to set a date which is in the past
but if would like to set this date 15 | January | 2016
i set at first the day to 15
than the month to january but then the UIDatepicker goes back to the minimum date 2 May 2015
is it be possible, that wenn change the day to 15 and the month to january, that the year changes automaticly to 2016?
Let your minimumDate unset and try to configure it by code...
Try this:
#IBAction func changeValue(sender: UIDatePicker)
{
//Get time Now, and convert to a NSCalendar
//Specify the minimun date if you want.
let now = NSDate()
let nowCalendar = NSCalendar.currentCalendar()
let nowComponents = nowCalendar.components([.Day, .Month, .Year], fromDate: now)
//Compare if date is lesser than now and then create a new date
if nowCalendar.compareDate(sender.date, toDate: now, toUnitGranularity: [.Day, .Month, .Year]) == NSComparisonResult.OrderedAscending
{
let dateCalendar = NSCalendar.currentCalendar()
let dateComponents = dateCalendar.components([.Day, .Month, .Year], fromDate: sender.date)
dateComponents.year = nowComponents.year + 1
let newDate = dateCalendar.dateFromComponents(dateComponents)
sender.date = newDate!
}
}
///Swift4 Version - I think it may works with 3 too.
#IBAction func changeValue(sender: UIDatePicker)
{
//Get time Now, and convert to a NSCalendar
//Specify the minimun date if you want.
let now = Date()
let nowCalendar = Calendar.current
let nowComponents = nowCalendar.dateComponents([.day, .month, .year], from: now)
//Compare if date is lesser than now and then create a new date
if nowCalendar.compare(sender.date, to: now, toGranularity: Calendar.Component.day) == ComparisonResult.orderedAscending
{
var dateCalendar = Calendar.current
var dateComponents = dateCalendar.dateComponents([.day, .month, .year], from: sender.date)
guard let year = nowComponents.year else { return }
dateComponents.year = year + 1
let newDate = dateCalendar.date(from:dateComponents)
sender.date = newDate!
}
}
I published a complete example working in playground if you wish to play a little.
https://gist.github.com/dedeexe/4878f78d7e1d5fe8b372ef84de629b59
For swift 4:
I have like this.
1. My function:
func AddDaysToToday(days: Int) -> Date? {
var dateComponents = DateComponents()
dateComponents.day = days
return Func.GetCalendar(tz: .utc).date(byAdding: dateComponents, to: Date()) //you can return your own Date here.
}
In my VC:
let today = DateFunc.AddDaysToToday(days: 0)
datePicker.minimumDate = today
I'm building a birthday reminder app. I want the user to be able to see how many days it is until somebody's next birthday.
Let's say I have an NSDate() = 2015-06-30 07:21:47 +0000
And the NSDate for the birthday = 1985-08-29 12:00:00 +0000
How would I get the number of days until the next birthday? I've used something like this which gives a negative number of days since the date's actual beginning (which are in the thousands with birthdates). Then with that I would add 365 to the numerical difference until it was positive but it still returns a wonky number. I'm assuming due to leap years or something.
Is there a method to this I can implement? Somehow equalize the year components so that it's always comparing from the next birthday and not the original birthdate?
Edit:
Here is the function I am using:
func daysBetween(date1: NSDate, date2: NSDate) -> Int {
var calendar: NSCalendar = NSCalendar.currentCalendar()
let date1 = calendar.startOfDayForDate(date1)
let date2 = calendar.startOfDayForDate(date2)
let flags = NSCalendarUnit.CalendarUnitDay
let components = calendar.components(flags, fromDate: date1, toDate: date2, options: nil)
return components.day
}
With the example dates I posted I would use it like this:
// sampleDate = 1985-08-29 12:00:00 +0000
daysBetween(sampleDate, date2: NSDate())
// --> 10897
Whether positive or negative, the number is in the thousands. I'm looking to equalize that into number of days to the next calendar birthday.
What you need is to compute the next occurrence of the (day and month
component of the) birthday after today:
let cal = NSCalendar.currentCalendar()
let today = cal.startOfDayForDate(NSDate())
let dayAndMonth = cal.components(.CalendarUnitDay | .CalendarUnitMonth,
fromDate: birthday)
let nextBirthDay = cal.nextDateAfterDate(today,
matchingComponents: dayAndMonth,
options: .MatchNextTimePreservingSmallerUnits)!
Remarks:
The purpose of the MatchNextTimePreservingSmallerUnits option is
that if the birthday is on February 29 (in the Gregorian calendar), its next occurrence will be
computed as March 1 if the year is not a leap year.
You might need to check first if the birthday is today, as it seems
that nextDateAfterDate() would return the next birthday in that case.
Then you can compute the difference in days as usual:
let diff = cal.components(.CalendarUnitDay,
fromDate: today,
toDate: nextBirthDay,
options: nil)
println(diff.day)
Update for Swift 2.2 (Xcode 7.3):
let cal = NSCalendar.currentCalendar()
let today = cal.startOfDayForDate(NSDate())
let dayAndMonth = cal.components([.Day, .Month],
fromDate: birthday)
let nextBirthDay = cal.nextDateAfterDate(today,
matchingComponents: dayAndMonth,
options: .MatchNextTimePreservingSmallerUnits)!
let diff = cal.components(.Day,
fromDate: today,
toDate: nextBirthDay,
options: [])
print(diff.day)
Update for Swift 3 (Xcode 8 GM):
let cal = Calendar.current
let today = cal.startOfDay(for: Date())
let dayAndMonth = cal.dateComponents([.day, .month], from: birthday)
let nextBirthDay = cal.nextDate(after: today, matching: dayAndMonth,
matchingPolicy: .nextTimePreservingSmallerComponents)!
let diff = cal.dateComponents([.day], from: today, to: nextBirthDay)
print(diff.day!)
Btw, in case anyone needs here is the #Aaron function in Swift 3:
func daysBetween(date1: Date, date2: Date) -> Int {
let calendar = Calendar.current
let date1 = calendar.startOfDay(for: date1)
let date2 = calendar.startOfDay(for: date2)
let components = calendar.dateComponents([Calendar.Component.day], from: date1, to: date2)
return components.day ?? 0
}
How might the day number of the year be found with swift? Is there a simple way that I'm not seeing, or do I have to find the number of seconds from Jan 1 to the current date and divide by the number of seconds in a day?
This is a translation of the answer to How do you calculate the day of the year for a specific date in Objective-C? to Swift.
Swift 2:
let date = NSDate() // now
let cal = NSCalendar.currentCalendar()
let day = cal.ordinalityOfUnit(.Day, inUnit: .Year, forDate: date)
print(day)
Swift 3:
let date = Date() // now
let cal = Calendar.current
let day = cal.ordinality(of: .day, in: .year, for: date)
print(day)
This gives 1 for the first day in the year, and 56 = 31 + 25 for today (Feb 25).
... or do I have to find the number of seconds from Jan 1 to the current date
and divide by the number of seconds in a day
This would be a wrong approach, because a day does not have a fixed
number of seconds (transition from or to Daylight Saving Time).
Swift 3
extension Date {
var dayOfYear: Int {
return Calendar.current.ordinality(of: .day, in: .year, for: self)!
}
}
use like
Date().dayOfYear
Not at all !!! All you have to do is to use NSCalendar to help you do your calendar calculations as follow:
let firstDayOfTheYear = NSCalendar.currentCalendar().dateWithEra(1, year: NSCalendar.currentCalendar().component(.CalendarUnitYear, fromDate: NSDate()), month: 1, day: 1, hour: 0, minute: 0, second: 0, nanosecond: 0)! // "Jan 1, 2015, 12:00 AM"
let daysFromJanFirst = NSCalendar.currentCalendar().components(.CalendarUnitDay, fromDate: firstDayOfTheYear, toDate: NSDate(), options: nil).day // 55
let secondsFromJanFirst = NSCalendar.currentCalendar().components(.CalendarUnitSecond, fromDate: firstDayOfTheYear, toDate: NSDate(), options: nil).second // 4,770,357
You can find the number of days since your date like this:
let date = NSDate() // your date
let days = cal.ordinalityOfUnit(.CalendarUnitDay, inUnit: .CalendarUnitYear, forDate: date)
println(days)