Scala

2012-12-05 24 views
5

'daki gerçek tarihlerle tarih dizelerini karşılaştırma Bir REST hizmetinden aktarılan bir tarih dizesini doğrulamak ve karşılaştırmak için iyi bir yöntem arıyorum.Scala

Eğer 2012-12-25 (yıl-ay-gün) dize olarak geçilirse, geçerli bir tarih olduğunu doğrulamak için şık bir yol olur ve sonra tarihin gelecekte ya da gelecekte olduğunu söylerdi. geçmiş?

Scala'da tarihlerle çalışmak için, mevcut Java kitaplıklarını açıkça kullanabilirsiniz. Ancak, Java'da tarihlerle çalışmak her zaman karanlık tarafa hizmet etmek gibi olmuştur, bu yüzden bu mirasın çoğunu mevcut kodlama stilime sürüklemek istemiyorum. Scala Dates example on langref.org'a baktığımda, bu programlama stilini takip edersem Java'yı kodlamaya geri döneceğimi hissederim.

+2

Herhangi bir yolla Scala uzmanı değilim, ama belki de [Scala Time] adına [Joda Time sarıcı] (https://github.com/jorgeortiz85/scala-time) sizin için işe yarayabilir. .. –

cevap

5

JodaTime güzel, güzel, güzel, karanlık taraf için endişelenme, mevcut değil (veya en azından bu belirli Java kütüphanesinde).

// "20121205".to_date 
class String2Date(ymd: String) { 
    def to_date = { 
    try{ Some(ymdFormat.parseDateTime(ymd)) } 
    catch { case e:Exception => None } 
    } 
    val ymdFormat = org.joda.time.format.DateTimeFormat.forPattern("yyyyMMdd") 
} 
@inline implicit final def string2Date(ymd: String) = new String2Date(ymd) 

def dater(ymd: String) = { 
    val other = new JodaTime 
    ymd.to_date map{d=> 
    if(d.isBefore other) ... 
    else ... 
    } getOrElse("bad date format") 
} 

JodaTime ile ilgili neredeyse herhangi bir tarih/saat yapabilir; Bu kütüphanenin ne kadar iyi olduğu çok saçma: Keskin bir yaşasın.

+0

İyi bir seçenek gibi görünüyor, teşekkürler. Normalde, scala-time (https://github.com/jorgeortiz85/scala-time) projesini kullanıyor musunuz? – Jack

+0

no, ScalaTime için bir ihtiyaç bulamadı, JodaTime oldukça özlü; yani, ScalaTime'ın üzerinde durduğu DSL geliştirmeleri ihtiyaçlar için gerekli değildir.JodaTime Scala ile sorunsuz bir şekilde çalışır, eylemde Java interop ispatı ;-) – virtualeyes

+0

+1 JodaTime over Java Tarih kitaplıkları * yuck * – fresskoma

3

Bu standart Java SimpleDateFormat kitaplığı kullanarak yapabilirsiniz:

: O zaman gelecek tarihleri ​​test etmek için bir işleve sahip olabilir

parseDate("2012-125") // None 
parseDate("2012-12-05") // Some(Wed Dec 05 00:00:00 EST 2012) 

: şöyle kullandım sonra

def parseDate(value: String) = { 
    try { 
    Some(new SimpleDateFormat("yyyy-MM-dd").parse(value)) 
    } catch { 
    case e: Exception => None 
    } 
} 

Ve

def isFuture(value: Date) = value.after(new Date) 
+0

+1 Güzel açıkladı, teşekkürler – Jack

1

Ancak, yokluğu gibi java tarih kitaplıklarını kullanmanın bazı olumsuzlukları vardır. yapabildin,

implicit val format = "yyyy-MM-dd" 
"2012-12-02" isValid // true 
"2012-12-02" beforeNow // ? 
"2012-12-25" afterNow // ? 

Veya:

implicit def stringToDate(date: String) = new { 
    def parse(implicit format: String) = parse0(date)(format) 
    private def parse0(date: String)(implicit format: String) = { 
    val sdf = new SimpleDateFormat(format) 
    sdf.setLenient(false) 
    sdf.parse(date) 
    } 
    def isValid(implicit format: String) = try { parse0(date)(format); true } catch { case _ => false } 
    def beforeNow(implicit format: String) = parse0(date)(format) before new Date() 
    def afterNow(implicit format: String) = parse0(date)(format) after new Date() 
} 

Sonra şöyle kullanabilirsiniz: hread güvenliği (Why is Java's SimpleDateFormat not thread-safe?) ve sert bir API kullanmak için, işler biraz daha kabul edilebilir hale implicits kullanabilirsiniz scala-time kullanın:

import org.joda.time.format.ISODateTimeFormat._ 
import org.joda.time.DateTime 
for(date <- date.parseOption("2012-12-02")) yield date < new DateTime // Option(?) 

Bu yaklaşımla, bir Scala dostu bir arayüz almak ve oluşturmak zorunda ve yeni bir SimpleDateFormat nesnesi ayrıştırmak ya da bunu saklamak yok iş parçacığı sorunlarını önlemek için yerel olarak gezin.

1

Gerçekten herhangi bir tarih kitaplığı kullanmaktan kaçınmak istiyorsanız, dizenin gerçekten geçerli bir ISO 8601 biçimlendirilmiş tarih olduğunu doğrulamak için uygun bir düzenli ifade kullanabilirsiniz (bu yanıtta: https://stackoverflow.com/a/7221570/227019). ve sonra, bu tarihlerin zamansal sıralamasını belirlemek için sözlüksel olarak karşılaştırılabilir olması gerçeğini kullanın (sadece geçerli tarihi aynı biçimde biçimlendirin ve normal dize karşılaştırmasını kullanarak diğer tarihle karşılaştırın).