Proposal

Represent a point in time as a Swift immutable scalar type TimePoint

Motivation

The representation of time and calculations involving time are fundamental to 
the correct functioning of all computer systems. If the language can express 
and manipulate points in time in a consistent and well-defined way, then the 
user will make fewer programming errors, the reliability and security of the 
system will be improved, and the scope of applications for that language will 
increase.

Representing and manipulating points in time has historically been an 
error-prone endeavor. Problems include:

* Precision: lack of or unknown stored precision, loss during calculations, 
floating point quirks
* Range: Underflow or overflow during calculation due to unexpectedly small 
range or unsigned representation 
* Lack of built-in representations: distant past and distant future usually 
require values with special meaning
* Use of inappropriate operators on scalar types that are used to store a 
representation of a point in time


Proposed Solution

The Swift language should provide an immutable scalar type TimePoint that can 
represent only a point in time. Additionally it should provide a mutable signed 
scalar type TimeOffset that can represent only the difference between two 
TimePoints.

TimePoint is approximated by the following enumeration:

enum TimePoint : Strideable, RawRepresentable, Hashable {
    case DistantPast, 
    case DistantFuture,
    case At(Int64, UInt64)   // Seconds, nanos
}

TimePoint is similar to NSDate. However, its underying storage strategy is 
hidden from the user. To access the value, rawValue must be called to get a 
tuple (seconds: Int64, nanos: UInt64).

TimePoint provides the guarantee that it has sufficient resolution and range 
for all practical purposes (precision to nanos worst case, range of the order 
of the age of the universe).

The Stride of a TimePoint is of signed type TimeOffset. TimeOffset is 
approximated by the following struct:

struct TimeOffset : Comparable, RawRepresentable, Hashable {
    var seconds:Int64
    var nanos: UInt64
} 

The compiler is aware of the meaning of .DistantFuture and .DistantPast and can 
warn of inappropriate or nonsensical use. For example, the following can never 
be true:

if t > TimePoint.DistantFuture { return }

Since .DistantFuture and .DistantPast are not special values, TimePoint behaves 
as expected across its entire range.

The underlying storage can be made efficient since it is opaque. Since common, 
practical points in time are specified to units larger than nanos, and they do 
not need the full range, many zero or fixed bit values can be encoded into a 
small space, while rare or impractical points in time can still be faithfuly 
recorded.

TimePoint and TimeOffset have appropriate initializers, getters, and methods 
(TBD) to allow them to interoperate with other types.

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to