如何在 haskell 中将纪元转换为公历日期时间
How to convert epoch to gregorian datetime in haskell
假设我有一个代表大纪元时间的整数,例如epoch = 1499055085
,我想在Haskell中将其转换为UTCTime
。
我该怎么做?
在其他语言中这是一个非常微不足道的任务,为什么在 haskell 中如此困难?
谁说难?
您可以简单地使用 fromIntegral :: (Integral a, Num b) => a -> b
将纪元(整数)转换为 POSIXTime
。
接下来我们可以使用 posixSecondsToUTCTime :: POSIXTime -> UTCTime
to obtain the UTCTime
, and finally we use the utctDay :: UTCTime -> Day
来获取 UTCTime
的日期部分。
如果你想要一个 (year,month,day) 元组,我们可以使用 toGregorian :: Day -> (Integer,Int,Int)
方法。
所以我们可以使用下面的方法:
import Data.Time.Calendar(toGregorian)
import Data.Time.Clock(utctDay,UTCTime)
import Data.Time.Clock.POSIX(posixSecondsToUTCTime)
epochToUTC :: Integral a => a -> UTCTime
epochToUTC = posixSecondsToUTCTime . fromIntegral
epochToGregorian :: Integral a => a -> (Integer,Int,Int)
epochToGregorian = toGregorian . utctDay . epochToUTC
然后例如:
Main> epochToGregorian 1234567
(1970,1,15)
Main> epochToGregorian 123456789
(1973,11,29)
Main> epochToGregorian 1234567890
(2009,2,13)
尽管有反对票,但这个问题一点也不差。那么这里相当标准的 "strptime" 和 "strftime" 相当于什么?
你觉得这相当复杂,我同意,因为我花了相当多的时间来解决这个问题(这里是 n00b),所以这里是我的一些发现。不简单,因为:
- 处理时间很复杂。
- Data.Time库侧重于类型安全(与Haskell一致),这也意味着没有为您完成自动类型转换。因此,您必须了解一两件事。
- epoch 的读法取决于它到底代表什么以及它是如何存储的。因此,如果标准库中没有实现通用函数
epoch -> utc
,那不是遗漏,而是因为它不存在。
说 python 更简单,因为 datetime
随 "pretty good defaults" 一起从您的环境中推断出来。 "good enough default parameter value for most circumstances" 的概念不适用于 Haskell.
如果纪元值来自某个任意整数,则 Willem Van Onsem 的 epochToUTC
有效。如果它是来自文件的时间戳 (EpochTime
),我们需要另一个函数,因为它不是一个整数(它看起来像一个整数,它的行为也像一个整数,但它既不是 Int
也不是Integer
——那是一些很深的水)。
至于 import
语句,您可以将其简化为纯粹的 import Data.Time
,它将从该模块中获取我们需要的所有内容,但 posixSecondsToUTCTime
除外,因为。 ..我想它被认为是一种专业化。
import System.Posix.Types(EpochTime)
import Data.Time
import Data.Time.Clock.POSIX(posixSecondsToUTCTime)
epochToUTC :: EpochTime -> UTCTime
epochToUTC = posixSecondsToUTCTime . realToFrac
ghci 中的示例:(当前工作目录的时间戳)
import System.Posix.Files
fStat <- getFileStatus "."
let someTime = epochToUTC . modificationTime $ fStat
并且我们可以很好地操纵这个时间值。请注意,EpochTime
特定于 System.Posix
模块。如果它是从数据库或网页中检索到的时间戳,则可能是另一个故事(类型安全不是免费的)。
正如这个 "strptime" 操作不太熟悉一样,类似的故事也发生在类似 "strftime" 的操作中。这将通过 formatTime
完成。示例:
formatTime defaultTimeLocale "%Y-%m-%d" someTime
--equivalent
formatTime defaultTimeLocale ( iso8601DateFormat Nothing ) someTime
--whichever dateFmt defined in that TimeLocale
formatTime defaultTimeLocale ( dateFmt defaultTimeLocale ) someTime
--"%a, %_d %b %Y %H:%M:%S %Z"
formatTime defaultTimeLocale rfc822DateFormat someTime
如果总是在defaultTimeLocale
,那么你可以优雅地缩写为:
formatTime' = formatTime defaultTimeLocale
读数:
A Haskell Time Library Tutorial(我们需要更多这样的!)
假设我有一个代表大纪元时间的整数,例如epoch = 1499055085
,我想在Haskell中将其转换为UTCTime
。
我该怎么做?
在其他语言中这是一个非常微不足道的任务,为什么在 haskell 中如此困难?
谁说难?
您可以简单地使用 fromIntegral :: (Integral a, Num b) => a -> b
将纪元(整数)转换为 POSIXTime
。
接下来我们可以使用 posixSecondsToUTCTime :: POSIXTime -> UTCTime
to obtain the UTCTime
, and finally we use the utctDay :: UTCTime -> Day
来获取 UTCTime
的日期部分。
如果你想要一个 (year,month,day) 元组,我们可以使用 toGregorian :: Day -> (Integer,Int,Int)
方法。
所以我们可以使用下面的方法:
import Data.Time.Calendar(toGregorian)
import Data.Time.Clock(utctDay,UTCTime)
import Data.Time.Clock.POSIX(posixSecondsToUTCTime)
epochToUTC :: Integral a => a -> UTCTime
epochToUTC = posixSecondsToUTCTime . fromIntegral
epochToGregorian :: Integral a => a -> (Integer,Int,Int)
epochToGregorian = toGregorian . utctDay . epochToUTC
然后例如:
Main> epochToGregorian 1234567
(1970,1,15)
Main> epochToGregorian 123456789
(1973,11,29)
Main> epochToGregorian 1234567890
(2009,2,13)
尽管有反对票,但这个问题一点也不差。那么这里相当标准的 "strptime" 和 "strftime" 相当于什么?
你觉得这相当复杂,我同意,因为我花了相当多的时间来解决这个问题(这里是 n00b),所以这里是我的一些发现。不简单,因为:
- 处理时间很复杂。
- Data.Time库侧重于类型安全(与Haskell一致),这也意味着没有为您完成自动类型转换。因此,您必须了解一两件事。
- epoch 的读法取决于它到底代表什么以及它是如何存储的。因此,如果标准库中没有实现通用函数
epoch -> utc
,那不是遗漏,而是因为它不存在。
说 python 更简单,因为 datetime
随 "pretty good defaults" 一起从您的环境中推断出来。 "good enough default parameter value for most circumstances" 的概念不适用于 Haskell.
如果纪元值来自某个任意整数,则 Willem Van Onsem 的 epochToUTC
有效。如果它是来自文件的时间戳 (EpochTime
),我们需要另一个函数,因为它不是一个整数(它看起来像一个整数,它的行为也像一个整数,但它既不是 Int
也不是Integer
——那是一些很深的水)。
至于 import
语句,您可以将其简化为纯粹的 import Data.Time
,它将从该模块中获取我们需要的所有内容,但 posixSecondsToUTCTime
除外,因为。 ..我想它被认为是一种专业化。
import System.Posix.Types(EpochTime)
import Data.Time
import Data.Time.Clock.POSIX(posixSecondsToUTCTime)
epochToUTC :: EpochTime -> UTCTime
epochToUTC = posixSecondsToUTCTime . realToFrac
ghci 中的示例:(当前工作目录的时间戳)
import System.Posix.Files
fStat <- getFileStatus "."
let someTime = epochToUTC . modificationTime $ fStat
并且我们可以很好地操纵这个时间值。请注意,EpochTime
特定于 System.Posix
模块。如果它是从数据库或网页中检索到的时间戳,则可能是另一个故事(类型安全不是免费的)。
正如这个 "strptime" 操作不太熟悉一样,类似的故事也发生在类似 "strftime" 的操作中。这将通过 formatTime
完成。示例:
formatTime defaultTimeLocale "%Y-%m-%d" someTime
--equivalent
formatTime defaultTimeLocale ( iso8601DateFormat Nothing ) someTime
--whichever dateFmt defined in that TimeLocale
formatTime defaultTimeLocale ( dateFmt defaultTimeLocale ) someTime
--"%a, %_d %b %Y %H:%M:%S %Z"
formatTime defaultTimeLocale rfc822DateFormat someTime
如果总是在defaultTimeLocale
,那么你可以优雅地缩写为:
formatTime' = formatTime defaultTimeLocale
读数:
A Haskell Time Library Tutorial(我们需要更多这样的!)