haskell - Is there a better way to convert from UTCTime to EpochTime? -
i want set file's modification time time got exif data.
to time exif, found :
graphics.exif.gettag :: exif -> string -> io (maybe string)
to set file modification time, found :
system.posix.files.setfiletimes :: filepath -> epochtime -> epochtime -> io ()
assuming find time in exif, need convert string epochtime.
- with
parsetime
canutctime
. - with
utctimetoposixseconds
canposixtime
- with
posixtime
can more or lessepochtime
to convert utctime
epochtime
typechecks, i'm not sure it's correct :
fromintegral . fromenum . utctimetoposixseconds $ etime
this part of function gettime return time exif data, if present, otherwise file's modification time :
gettime (path,stat) = let ftime = modificationtime $ stat err (someexception _) = return ftime time <- liftio $ handle err $ exif <- exif.fromfile path let getexiftime = maybet . liftio . exif.gettag exif res <- runmaybet $ tmp <- msum . map getexiftime $ [ "datetimeoriginal","datetimedigitized", "datetime" ] maybet . return . parsetime defaulttimelocale "%y:%m:%d %h:%m:%s" $ tmp case res of nothing -> return ftime etime -> return . fromintegral . fromenum . utctimetoposixseconds $ etime return (path,time)
my question is
is there better/simpler way convert time ? ( maybe using different libaries )
data.time
best supported time library, agree choice of using parse string representation of date , time out of exif data.
are sure need set modification time of file? that's unusual. if so, yes, you'll need use system.posix
libraries on posix system.
if need read modification of file, better off using more generic function system.directory.getmodificationtime
. unfortunately, function uses non-standard time library, system.time
long-deprecated old-time
package in case. still need similar machinations.
your conversion posixtime
epochtime
happens ok in particular case, in general it's not ideal way go.
the epochtime
type, a.k.a time_t
type c, not support direct way constructed in haskell without going via integral value, though not integral depending on operating system. go via c using ffi if potential fractions of second important you. here that's not important, because you're getting seconds %s
format parameter can have no fractional part. anyway. still need kind of rounding or truncating non-integral utctime
type epochtime
.
you're using enum
instance of posixtime
rounding/truncating you, decides to. again, in particular case doesn't matter, because happen know value integral. in general, it's better specify explicitly using floor
, ceiling
, or round
. e.g.,
return $ maybe ftime (frominteger . round . utctimetoposixseconds) etime
(note don't need write out case
explicitly, can use maybe
function prelude.)
notice explicitly using frominteger
push conversion through integer
type. if want go via int
instead (watch out "year 2038 problem" on 32-bit machines), define separate conversion function make clear:
return $ maybe ftime utctimetoepochtime etime ... -- convert utctime epochtime via int utctimetoepochtime :: utctime -> epochtime utctimetoepochtime = fromintegral . tosecs tosecs :: utctime -> int tosecs = round . utctimetoposixseconds
Comments
Post a Comment