haskell / time

A time library
http://hackage.haskell.org/package/time
Other
120 stars 80 forks source link

ticks #126

Closed BebeSparkelSparkel closed 4 years ago

BebeSparkelSparkel commented 4 years ago

I just came across the unit ticks.

The value of this property represents the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001 in the Gregorian calendar

https://docs.microsoft.com/en-us/dotnet/api/system.datetime.ticks?view=netframework-4.8

AshleyYakeley commented 4 years ago

What kind of support for this did you have in mind?

BebeSparkelSparkel commented 4 years ago

Something like:

newtype Ticks = Ticks {_ticks :: Integer} deriving (Show, Eq, Ord, Num, Zero)
makeLenses ''Ticks
instance ToJSON Ticks where toJSON = toJSON . view ticks

divOf :: Integral a => a -> Iso' a a
divOf x = iso (`div` x) (* x)

multOf :: Integral a => a -> Iso' a a
multOf = from . divOf

posix :: Iso' Integer POSIXTime
posix =
  (iso MkFixed (\(MkFixed x) -> x) :: Iso' Integer Pico) .
  (iso secondsToNominalDiffTime nominalDiffTimeToSeconds :: Iso' Pico POSIXTime)

ticks2posix :: Iso' Ticks POSIXTime
ticks2posix =
  ticks .
  subtracting 621355968000000000 .
  multOf (10 ^ 5) .
  posix
AshleyYakeley commented 4 years ago

The time library has avoided the approach of having a type for each unit. Instead, it has a type for each concept, such as "absolute time" or "relative time" or, in this case, "POSIX time" due to the particular way POSIX ignores leap seconds. Ticks measure POSIX time, and the time library has the POSIXTime type for representing that.

The .NET DateTime.Ticks property has (.NET) type long, corresponding to Haskell Int64. Therefore we could have:

dotNetTicksToPosix :: Int64 -> POSIXTime
posixToDotNetTicks :: POSIXTime -> Int64

However, since "ticks" comes from .NET, it's not clear to me this belongs in the time library rather than some .NET-specific library.

BebeSparkelSparkel commented 4 years ago

Thanks