2013-07-28 12 views
21

Esiste una funzione in haskell per l'epoca in secondi/millisecondi?Ottiene il tempo come Int

forse qualcosa di simile a

System.currentTimeMillis(); 

modifica di Java: come Int o Integer?

risposta

32

Sì.

getCurrentTime :: IO UTCTime.

UNIX epoch time potrebbe essere recuperate come Int così:

> :m + Data.Time System.Locale Control.Applicative 
> epoch_int <- (read <$> formatTime defaultTimeLocale "%s" <$> getCurrentTime) :: IO Int 
> epoch_int 
1375025861 

UPD: come altri utenti notato, c'è molto di più semplice modo per farlo:

> :m + Data.Time.Clock.POSIX 
> round `fmap` getPOSIXTime 
1375040716 
it :: Integer 
+0

ha ricevuto il messaggio "Not in scope:' <$> '" – jajdoo

+4

Conversione tramite stringa? Tecnicamente corretto, e probabilmente sicuro, ma si sente molto più messico rispetto alle altre soluzioni qui ... –

+1

@jajdoo importa solo 'Control.Applicativo'. Aggiornata la risposta –

5

Prova questo:

import Data.Time 
import Data.Time.Clock.POSIX 

t = getPOSIXTime 

Dispone di 6 cifre decimali di precisione.

+3

Importazione 'Data.Time' ridondante. 't' è' IO POSIXTime', la domanda è di ottenere un 'Int'. –

2

C'è anche la soluzione discussa in Real World Haskell:

import System.Time 
getClockTime >>= (\(TOD sec _) -> return sec) 
+1

Questo usa il vecchio pacchetto 'System.Time' che di solito dovrebbe essere sostituito da' Data.Time'. –

-6

Questo funziona:

import System.IO.Unsafe 
import Data.Time.Clock.POSIX 

time = round (unsafePerformIO getPOSIXTime) :: Int 

unsafePerformIO estrae tempo dalla monade IO. Arrotondare a Int produce quindi il risultato desiderato.

AGGIORNAMENTO: Nelle mie applicazioni Web Haskell, a volte utilizzo unsafePerformIO per compilare caselle di controllo HTML e pulsanti di opzione radio con numeri casuali e timestamp nascosti. A volte il mio campo di testo e le caselle di testo consentono agli utenti (giocatori di giochi interattivi) di fornire dati come numeri arbitrari e date. Giustino, confido che non pensi che i valori forniti dall'utente siano più sicuri dei numeri casuali e dei timestamp che fornisco ai moduli? E spero che tu non pensi che volessi dire, "Usa cose come unsafePerformIO se non capisci cosa stai facendo."

I browser Web utilizzano HTML, CSS e Javascript. Non è possibile "tenerlo nella monade IO" e i browser non eseguono più o meno in modo sicuro a seconda di come i valori che ricevono provengono dalle monadi Haskell.

Justin, a beneficio di tutti coloro che leggono questa pagina, ti chiedo di riconsiderare e di dire se pensi ancora che "davvero non dovrei usare unsafePerformIO in questo modo"? La mia mente è aperta. Non ho la minima idea di cosa, se non altro, potrei sbagliare nel mio lavoro, o perché i lettori dovrebbero essere scoraggiati dall'apprendere da me i due voti negativi.

P.S. Ho sentito che non si dovrebbe dire # @!% Davanti ai bambini, o in compagnia mista. Ho pubblicato la parola "U" dove i principianti potrebbero vederlo? Il cielo non voglia!-DS

+3

In realtà non dovresti usare 'unsafePerformIO' in questo modo. È utile soprattutto per chiamare le funzioni che conosci puramente usando FFI. Vedi [questo thread SO per maggiori informazioni] (http://stackoverflow.com/questions/19371636/am-i-abusing-unsafeperformio). Se stai facendo IO, tienilo nella monade IO e il tuo programma sarà più sicuro da usare ed estendere. Usa solo cose come 'unsafePerformIO' se capisci veramente cosa stai facendo. –

+0

Il mio commento è nell'aggiornamento, sopra. Non si adatterebbe qui –

+4

Questi sono solo modi folli per usare 'unsafePerformIO'. In generale, non si dovrebbe usare 'unsafePerformIO' per eseguire questo tipo di IO. Sì, va bene (nel mio libro) usarlo per prendere alcuni numeri casuali per un algoritmo di Las Vegas come Quickselect (ma non per uno di Monte Carlo), e va bene usarlo per consentire a un algoritmo concorrente di implementare una funzione pura (anche se sono abbastanza sicuro che ci sono funzioni di livello superiore per farlo un po 'più bene, anche se ancora pericolosamente), ed è certamente soddisfacente per le cose (pure) della FFI, ma queste non sono le cose che stai facendo. – dfeuer

3

ne dite:

import Data.Time.Clock.POSIX 

timeInMicros :: IO Integer 
timeInMicros = numerator . toRational . (* 1000000) <$> getPOSIXTime 

timeInMillis :: IO Integer 
timeInMillis = (`div` 1000) <$> timeInMicros 

timeInSeconds :: IO Integer 
timeInSeconds = (`div` 1000) <$> timeInMillis 

timeInSeconds' :: IO Double 
timeInSeconds' = (/ 1000000) . fromIntegral <$> timeInMicros 
1

Forse:

getCurrentTime >>= pure . (1000*) . utcTimeToPOSIXSeconds >>= pure . round 

Round è quello di ottenere intero che in realtà non è obbligatoria ...

risposta originale era senza (1000*) - ora è fisso

+0

** Dalla coda di revisioni: ** Posso chiederti di aggiungere un po 'più di contesto intorno alla tua risposta. Le risposte al solo codice sono difficili da capire. Aiuterà il richiedente e i futuri lettori sia se puoi aggiungere ulteriori informazioni nel tuo post. –

+0

Execuse me, per una risposta così breve (e in realtà non del tutto giusta). Per quanto mi riguarda, lo faccio in questo modo: 'getCurrentTime >> = pure. (1000 *). utcTimeToPOSIXSeconds >> = puro. round'. Entrambe le funzioni sono in Data.Time.Clock.POSIX. Questo (in esecuzione in GHCi) restituisce millisecondi del tempo corrente –

Problemi correlati