2013-07-28 23 views
21

Saniye/milisaniye cinsinden zamanlama için haskell'de bir işlev var mı?Int olarak zaman al

belki java'nın

System.currentTimeMillis(); 

düzenlemeye benzer bir şey: Int veya Integer olarak?

cevap

32

Evet.

getCurrentTime :: IO UTCTime.

UNIX dönem süresi böyle Int olarak alınamadı :

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

UPD:

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

"Kapsam kapsamında değil:" <$> "" – jajdoo

+4

Dize Dönüştürme "mesajını aldı mı? Teknik olarak doğru ve muhtemelen güvenli, ama burada diğer çözümler daha çok daha karışıklık hissediyor ... –

+1

@jajdoo sadece 'Control.Applicative' ithal. Yanıt –

5

bu deneyin:

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

t = getPOSIXTime 

Bu doğruluk 6 ondalık basamağı vardır.

+3

düzeltildi gereksiz "Data.Time" içe aktarma. '' 'IO POSIXTime'' sorusu' Int' alma hakkındadır. –

2

vardır: Diğer kullanıcıların fark olarak, bunu yapmanın yolu çok daha basit olduğu Aynı zamanda, çözelti, Real World Haskell:

+1

Bu, genellikle 'Data.Time' ile değiştirilmesi gereken eski 'System.Time 'paketini kullanır. –

-6

Bu çalışır:

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

time = round (unsafePerformIO getPOSIXTime) :: Int 

unsafePerformIO IO monad gelen zaman ayıklar. Int'e yuvarlama daha sonra istenen sonucu verir.

GÜNCELLEME: Haskell web uygulamalarımda, HTML onay kutusunu ve radyo düğmesi formlarını rastgele sayılar ve gizli zaman damgalarıyla doldurmak için bazen güvensizPerformIO kullanıyorum. Bazen metin alanım ve metin kutusu formları, kullanıcıların (etkileşimli oyunların oyuncuları) rasgele sayılar ve tarihler gibi veriler sağlamasına olanak tanır. Justin, kullanıcı tarafından sağlanan değerlerin, formlara verdiğim rastgele sayılardan ve zaman damgalarından daha güvenli olduğunu düşünmemenize güveniyorum. Ve inanıyorum ki, "Yaptığını anlamadıysan, güvensizPerformi gibi şeyler kullan."

Web tarayıcıları HTML, CSS ve Javascript kullanır. “IO monadında saklayamazsınız” ve tarayıcılar, aldıkları değerlerin Haskell monad'larından nasıl çıktıklarına bağlı olarak daha fazla veya daha az güvenli bir şekilde performans göstermezler.

Justin, bu sayfayı okuyan herkesin yararı için, sizden hala "güvensiz Pseformio'yu bu şekilde kullanmamalı mıyım?" Diye düşünmenizi rica ediyorum. Aklım açık. Yaptığım işte yanlış olan bir şey varsa ya da okuyucunun neden benden iki oy ile öğrenmekten vazgeçilmemesi gerektiğine dair bir fikrim yok.

P.S. Bunun çocukların önünde ya da karışık bir şirkette #%! Yenilerin görebileceği "U" kelimesini mi yayınladım? Allah korusun!-DS

+3

Bu yolla 'unsafePerformIO' kullanmamalısınız. FFI kullanarak saf olduğunu bildiğiniz işlevleri çağırmak için çoğunlukla yararlıdır. [Daha fazla bilgi için bu SO iş parçacığına bakın] (http://stackoverflow.com/questions/19371636/am-i-abusing-unsafeperformio). Eğer IO yapıyorsanız, IO monadında tutun ve programınız kullanmak ve uzatmak için daha güvenli olacaktır. Ne yaptığınızı gerçekten anlarsanız sadece 'güvensizPerformIO 'gibi şeyler kullanın. –

+0

Yorumum, yukarıdaki güncellemedir. Bu burada uygun değil –

+4

Bunlar 'güvensizPerformIO' kullanmak için sadece çılgın yolları vardır. Genel olarak, bu tür bir IO gerçekleştirmek için 'güvensizPerformi'yi kullanmamalısınız. Evet, (kitapta), Quickselect gibi bir Las Vegas algoritması için rasgele bir sayı elde etmek için kullanmak iyidir (ancak bir Monte Carlo için değil), ve bir eşzamanlı algoritmanın saf bir işlevi yerine getirmesine izin vermek için kullanmak iyidir (Her ne kadar oldukça tehlikeli olsa da, daha iyi bir seviye olsa da, daha yüksek seviyeli fonksiyonlara sahip olduğumdan eminim) ve kesinlikle (saf) FFI şeyleri için iyidir, fakat bunlar yaptığınız şeyler değildir. – dfeuer

3

ne dersiniz:

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

Belki:

orijinal cevap (1000*) idi

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

Round aslında zorunlu değildir tamsayı almak istiyorsa ... - şimdi

+0

** İnceleme kuyruğundan: ** Cevabınız etrafında biraz daha içerik eklemenizi rica edebilir miyim? Sadece kod cevapları anlamak zor. Gönderinize daha fazla bilgi ekleyebilmeniz durumunda, okuyucunun ve gelecekteki okuyucuların yardımcı olacaktır. –

+0

Bana, çok kısa (ve aslında tamamen doğru değil) cevap ver. Bana gelince, bunu şu şekilde yapıyorum: 'getCurrentTime >> = pure. (1000 *). utcTimeToPOSIXSeconds >> = saf. round'. Her iki funk da Data.Time.Clock.POSIX. Bu (GHCi'de çalışırken) geçerli zamanın milisaniye değerini döndürür –

İlgili konular