6

RESTサービスから渡された日付文字列を検証して比較するための優れた方法を探しています。

2012-12-25(年-月-日)を文字列として渡した場合、それが有効な日付であることを確認し、その日付が未来または過去であると言うためのエレガントな方法は何でしょうか?

Scalaで日付を操作するには、明らかに既存のJavaライブラリを使用できます。しかし、Javaで日付を操作することは、常にダークサイドを提供するようなものでした。そのため、そのレガシーの多くを現在のコーディングスタイルに引きずり込みたくありません。langref.orgのScalaDatesの例を見ると、このスタイルのプログラミングに従えば、Javaのコーディングに戻ると思います。

4

4 に答える 4

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 に関連するほぼすべての日付/時刻を実行できます。このライブラリがどれほど優れているかはばかげています。明確な親指を立ててください。

于 2012-12-05T21:54:14.757 に答える
4

これは、標準の 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)
于 2012-12-05T20:14:26.810 に答える
1

スレッド セーフの欠如 ( Why is Java's SimpleDateFormat not thread-safe? ) や使いにくい API など、Java 日付ライブラリの使用にはいくつかの欠点がありますが、暗黙を使用して物事をもう少し快適にすることができます。

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 オブジェクトを作成して解析したり、スレッド ローカルに格納したりする必要がなくなります。

于 2012-12-05T20:19:30.773 に答える
1

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

于 2012-12-05T21:40:40.060 に答える