swiftfoundationnstimezone

The purpose behind TimeZone vs NSTimeZone


Why there is a TimeZone with an API significantly different than NSTimeZone?

Say NSTimeZone has init(name: String) and TimeZone does not.

NSTimeZone has abbreviation property and in TimeZone abbreviation is a function that takes Date as a parameter (and nil is not an option)

Interestingly enough TimeZone(identifier:) digests abbreviations just fine.


Solution

  • The Foundation framework offers quite a few type pairs where the API of the original NS-prefixed type, as imported from the original Objective-C code, was less than optimal for Swift. Among these type pairs are

    and others.

    TimeZone and NSTimeZone are one such pair, where NSTimeZone is an Objective-C type which is exposed to Swift as-is, while TimeZone is a native Swift wrapper around NSTimeZone with an updated API. That updated API is intentionally different, because the original Objective-C API may be suboptimal in Swift.

    For example, as you note, NSTimeZone offers both an abbreviation property and an -abbreviationForDate: method, while TimeZone only offers the method. It's important to note that the abbreviation property just returns the result of calling -abbreviationForDate:, passing in [NSDate now]; i.e., it exists only because Objective-C doesn't support default arguments for methods, so abbreviation is a convenience. Swift, however, does have default arguments, so TimeZone.abbreviation(for:) unifies these: if you want to pass a specific Date, you can, but you don't have to.

    There are other reasons for disparate APIs on paired types like this:

    In all, it's very rare for the Swift variant of a type pair like this to offer less API than its Objective-C counterpart — and where API was removed, it's almost always for safety, ergonomics, or in favor of better APIs. But in general, the Swift variants typically have significantly more functionality, even if how that functionality is accessed is a little different.