Differences in Nsdatecomponents Syntax

Differences in NSDateComponents syntax?

Swift 2

The NSCalendarUnit names have changed in Swift 2.

Also, now we have to pass these arguments in an OptionSet, like this:

let components = calendar.components([.Hour, .Minute, .Second, .Nanosecond], fromDate: date)

Swift 3

Many things have changed, according to the Swift API Design Guidelines.

Updated syntax:

let date = Date()
let calendar = Calendar.current()
let components = calendar.components([.hour, .minute, .second, .nanosecond], from: date)

Swift 4

Calendar.current is now a property, and .components has been renamed to .dateComponents. Otherwise it's the same as in Swift 3.

let calendar = Calendar.current
let components = calendar.dateComponents([.hour, .minute, .second, .nanosecond], from: date)

Difference between two NSDate objects -- Result also a NSDate

NSDate represents an instance in time, so it doesn't make sense to represent an interval of time as an NSDate. What you want is NSDateComponents:

NSDate *dateA;
NSDate *dateB;

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay
fromDate:dateA
toDate:dateB
options:0];

NSLog(@"Difference in date components: %i/%i/%i", components.day, components.month, components.year);

Get hour, minitues, seconds from NSCalendar components? (swift)

let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
let components = calendar?.components([.Hour, .Minute, .Second], fromDate: NSDate())
var hours = components?.hour
var min = components?.minute
var sec = components?.second

Get difference between two dates?

NSDateComponentsFormatter can do that

NSTimeInterval secondsBetween = [date2 timeIntervalSinceDate:date1];
NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
formatter.allowedUnits = NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute;
formatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull;
NSLog(@"%@", [formatter stringFromTimeInterval:secondsBetween]);

See NSDateComponentsFormatterUnitsStyle for other styles.

dateByAddingTimeInterval argument syntax

NSDate compute time by second.

change code from swift to swift 2.0

You can use the code below, basically I replaced the enums with new OptionSetType syntax and few small changes. NSCalendarUnit OptionSetType has these static types which you can use,

static var Era: NSCalendarUnit { get }
static var Year: NSCalendarUnit { get }
static var Month: NSCalendarUnit { get }
static var Day: NSCalendarUnit { get }
static var Hour: NSCalendarUnit { get }
static var Minute: NSCalendarUnit { get }
static var Second: NSCalendarUnit { get }
static var Weekday: NSCalendarUnit { get }
static var WeekdayOrdinal: NSCalendarUnit { get }
static var Quarter: NSCalendarUnit { get }
static var WeekOfMonth: NSCalendarUnit { get }
static var WeekOfYear: NSCalendarUnit { get }
static var YearForWeekOfYear: NSCalendarUnit { get }
static var Nanosecond: NSCalendarUnit { get }
static var Calendar: NSCalendarUnit { get }
static var TimeZone: NSCalendarUnit { get }

So, you new code would look like this,

let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Year, .Month, .Day] , fromDate: notification.fireDate!)
var gregorian:NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let unit: NSCalendarUnit = [.Hour, .Minute]
var comps:NSDateComponents = gregorian.components(unit, fromDate: timepicker.date)


comps.setValue(components.day, forComponent:.Day)
comps.setValue(components.month, forComponent:.Month)
comps.setValue(components.year, forComponent:.Year)
comps.setValue(comps.hour, forComponent:.Hour)
comps.setValue(comps.minute, forComponent:.Minute)
var NewFiredate : NSDate = gregorian.dateFromComponents(comps)!

Difference between dot syntax and valueForKey

It was a problem with the difference in epochs. NSDate uses Jan 1 2001 as an epoch. So when I was getting the value I was using the unix epoch (1970). That gave me a difference in values.

When KVC unwraps and wraps NSTimeInterval with a NSDate object it uses the NSDate 2001 epoch.

So instead of using dateWithTimeIntervalSince1970
I used dateWithTimeIntervalSinceReferenceDate when getting the value.

NSDate Syntax Error

That class method is available on OS X, but not on iOS. It actually does exist on iOS, but it's considered private, and your app will be rejected if you try to submit it to the App Store using this method.

You're going to have to find a third party library to accomplish this on iOS.

Getting the difference between two Dates (months/days/hours/minutes/seconds) in Swift

Xcode 8.3 • Swift 3.1 or later

You can use Calendar to help you create an extension to do your date calculations as follow:

extension Date {
/// Returns the amount of years from another date
func years(from date: Date) -> Int {
return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
}
/// Returns the amount of months from another date
func months(from date: Date) -> Int {
return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
}
/// Returns the amount of weeks from another date
func weeks(from date: Date) -> Int {
return Calendar.current.dateComponents([.weekOfMonth], from: date, to: self).weekOfMonth ?? 0
}
/// Returns the amount of days from another date
func days(from date: Date) -> Int {
return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
}
/// Returns the amount of hours from another date
func hours(from date: Date) -> Int {
return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
}
/// Returns the amount of minutes from another date
func minutes(from date: Date) -> Int {
return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
}
/// Returns the amount of seconds from another date
func seconds(from date: Date) -> Int {
return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
}
/// Returns the a custom time interval description from another date
func offset(from date: Date) -> String {
if years(from: date) > 0 { return "\(years(from: date))y" }
if months(from: date) > 0 { return "\(months(from: date))M" }
if weeks(from: date) > 0 { return "\(weeks(from: date))w" }
if days(from: date) > 0 { return "\(days(from: date))d" }
if hours(from: date) > 0 { return "\(hours(from: date))h" }
if minutes(from: date) > 0 { return "\(minutes(from: date))m" }
if seconds(from: date) > 0 { return "\(seconds(from: date))s" }
return ""
}
}

Using Date Components Formatter

let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [.second, .minute, .hour, .day, .weekOfMonth, .month, .year]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = .full
dateComponentsFormatter.string(from: Date(), to: Date(timeIntervalSinceNow: 4000000)) // "1 month"


let date1 = DateComponents(calendar: .current, year: 2014, month: 11, day: 28, hour: 5, minute: 9).date!
let date2 = DateComponents(calendar: .current, year: 2015, month: 8, day: 28, hour: 5, minute: 9).date!

let years = date2.years(from: date1) // 0
let months = date2.months(from: date1) // 9
let weeks = date2.weeks(from: date1) // 39
let days = date2.days(from: date1) // 273
let hours = date2.hours(from: date1) // 6,553
let minutes = date2.minutes(from: date1) // 393,180
let seconds = date2.seconds(from: date1) // 23,590,800

let timeOffset = date2.offset(from: date1) // "9M"

let date3 = DateComponents(calendar: .current, year: 2014, month: 11, day: 28, hour: 5, minute: 9).date!
let date4 = DateComponents(calendar: .current, year: 2015, month: 11, day: 28, hour: 5, minute: 9).date!

let timeOffset2 = date4.offset(from: date3) // "1y"

let date5 = DateComponents(calendar: .current, year: 2017, month: 4, day: 28).date!
let now = Date()
let timeOffset3 = now.offset(from: date5) // "1w"


Related Topics



Leave a reply



Submit