2012-12-05 102 views
5

私は、RESTサービスから渡された日付文字列を検証して比較する良い方法を探しています。日付文字列とScalaの実際の日付との比較

2012-12-25(年月日)が文字列として渡された場合、それが有効な日付であることを確認し、日付が将来、または過去?

Scalaで日付を操作するには、明らかに既存のJavaライブラリを使用できます。しかし、Javaの日付を使って作業することは、常に暗いところに奉仕するようなものだったので、私はあまりにも多くの伝説を現在のコーディングスタイルにドラッグしたくありません。 Scala Dates example on langref.orgを見ると、私はこのスタイルのプログラミングに従えば、私はコーディングJavaに戻るだろうと感じています。

+2

私はScalaのエキスパートではありませんが、「Scala Time」という名前のJoda Timeラッパー(https://github.com/jorgeortiz85/scala-time)が役に立つかもしれません。 .. –

答えて

5

JodaTimeは大丈夫ですが、暗いところは心配しないでください(少なくともこの特定のJavaライブラリにはない)。

// "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に関連する事実上何でもできます。このライブラリがどれほどうまくいくかは不条理です。

+0

良いオプションのように見える、ありがとう。あなたは通常、scala-time(https://github.com/jorgeortiz85/scala-time)プロジェクトを使用しますか? – Jack

+0

いいえ、ScalaTimeの必要性を発見していない、JodaTimeは非常に簡潔です。つまり、ScalaTimeの強化が私のニーズにとって不可欠ではないDSL拡張機能です。JodaTimeはScalaとシームレスに動作し、Java interop proofの動作;-) – virtualeyes

+0

+1 JodaTime over Java日付ライブラリ* yuck * – fresskoma

3

あなたは、この標準的なJavaのSimpleDateFormatライブラリを使用して行うことができます。

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

をそしてそのようにそれを使用:

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

次にあなたが未来の日付をテストするための機能を持つことができます。

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

+1うまく説明しました、ありがとう – Jack

1

Javaの日付ライブラリを使用することには、tの欠如HREAD安全(Why is Java's SimpleDateFormat not thread-safe?)とAPIを使用するのは難しい、あなたは物事少し口に合うようにするために暗黙を使用することができます。

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() 
} 

次に、あなたがこのようにそれを使用することができます。

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

または、あなたでしたscala-timeを使用します。

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

このアプローチを使用すると、Scalaのフレンドリーなインターフェースを取得し、あなたが作成し、解析し、新しいのSimpleDateFormatオブジェクトのかで、それを保管する必要はありませんスレッドの問題を避けるために、ローカルにhreadしてください。

1

本当に日付時刻ライブラリを使用したくない場合は、適切な正規表現(この回答の例:https://stackoverflow.com/a/7221570/227019など)を使用して、文字列が実際に有効なISO 8601形式の日付であることを検証し、そのような日付を辞書編集で比較して一時的な順序を決定することができます(現在の日付を同じ形式でフォーマットし、通常の文字列比較を使用して他の日付と比較する)。