「指定範囲内の日付をランダムに取得」をGroovyでやってみた

最初は軽い気持ちだったんです、 そしたら何故か深い所に連れて行かれてました。
2
ikeda @kinumi

ある期間の中でランダムな日付を取得する処理って、ありそうでぱっと浮かんでこない @テストツール

2011-06-09 09:23:59
まちのシステム屋さん(揺れる重い) @xnrghzjh

Groovyならこうか、と思ったけど、なんかJavaのまんまだ。 先生助けて!! QT (cont) http://tl.gd/b079or

2011-06-09 12:13:04

↑ http://tl.gd/b079or はこんな感じ

@Grab(group='joda-time', module='joda-time', version='*')
import org.joda.time.*

def rand_date(def fr, def to) {
 def d = new DateTime(fr)
 def range = Days.daysBetween(d, new DateTime(to)).getDays() + 1
 d.plusDays((Integer)Math.floor(Math.random() * range)).toString("yyyy-MM-dd")
}

5.times {
 println rand_date("1978-09-30","2011-10-10")
}

close_yutori @kimukou2628

自分も実力不足>< https://gist.github.com/1016091 RT @xnrghzjh: Groovyならこうか、と思ったけど、なんかJavaのまんまだ。 先生助けて!! QT (cont) http://tl.gd/b079or

2011-06-09 14:02:23
まちのシステム屋さん(揺れる重い) @xnrghzjh

ありがとうございます! groovyなコードになりました。 https://gist.github.com/1015997 QT @kimukou_26 自分も実力不足>< https://gist.github.com/1016091

2011-06-09 14:55:06

↑ 14:55にgithubのURLを公開

close_yutori @kimukou2628

@xnrghzjh ()か少ないほうがいいので、明示的なキャスト先がわかっているなら toInteger() のほうが良いと思いますよ

2011-06-09 15:00:34
close_yutori @kimukou2628

@xnrghzjh あとdefは、実体として明示的に渡さなければいけないとき以外は省略できますね(基本ローカルスコープ参照するし)。あとたぶん@fumokmmさんあたりならMetaClassあたり使ってもっとかっこよくかけると思うけど http://goo.gl/ABGp5

2011-06-09 15:03:44
きょん@アジャイルコーチ、システムアーキテクト @kyon_mm

gistのアカウントすっかり忘れていてアップするのに20分ちかくかかったなんて言えない。

2011-06-09 15:20:16

↑ フォークされるまで25分 - アップに20分 = 実質作業時間 5分

まちのシステム屋さん(揺れる重い) @xnrghzjh

ありがとうございます! ますますGroovyを遠くに感じれそうな気がしてきました。 QT @kyon_mm フォークしました。https://gist.github.com/1016168 @kimukou_26

2011-06-09 15:38:44
close_yutori @kimukou2628

@kyon_mm @xnrghzjh 紛らわしいので自分の改変コード消して forkでやり直しました https://gist.github.com/1016191

2011-06-09 15:43:56
まちのシステム屋さん(揺れる重い) @xnrghzjh

自分のつぶやきから @kyon_mm 先生のフォークまで25分、でもアップに20分ということは、実質作業5分、Groovyエヴァンジェリストすごい...  QT @kyon_mm gistのアカウントすっかり忘れていてアップするのに20分ちかくかかったなんて言えない。

2011-06-09 16:02:29
まちのシステム屋さん(揺れる重い) @xnrghzjh

ボクシング良く分かんないけど、ライト級でちまちまやってたらヘビー級の人から「こっち来いよ、いいから、ほら」と連れて行かれる。 そんな感じな今。

2011-06-09 16:08:40

最終的にこうなりました。

@Grab(group='joda-time', module='joda-time', version='*')
import org.joda.time.*

DateTime.metaClass.random ={t->
 def range = Days.daysBetween(delegate, new DateTime(t)).getDays() + 1
 delegate.plusDays(Math.floor(Math.random() * range) as int).toString("yyyy-MM-dd")
}

5.times{
 println new DateTime("1978-09-30").random("2011-10-10")
}


復習を兼ねて処理を展開 & コメント追加

// joda-timeライブラリの最新版をダウンロードして使用
@Grab(group='joda-time', module='joda-time', version='*')
import org.joda.time.*

// DateTime にメソッド random(def t) を動的に追加宣言
DateTime.metaClass.random ={t->

 // 範囲の抽出 この例では "2011-10-10" - "1978-09-30" = 12064日
 range = Days.daysBetween(delegate, new DateTime(t)).getDays() + 1

 //delegate.plusDays(Math.floor(Math.random() * range) as int).toString("yyyy-MM-dd")
 // ↑を展開すると↓のようになる

 // 何日進めるかを範囲内からランダムに取得
 add = Math.floor(Math.random() * range) as int

 // delegate = new DateTime("1978-09-30")のインスタンスに日を加算
 date = delegate.plusDays(add)

 // "yyyy-MM-dd"形式にフォーマット
 date.toString("yyyy-MM-dd")

 // return文は省略可(最後のが返る)

}

ikeda @kinumi

知らないところで話が広がってて吹いた RT: @xnrghzjh: 「「指定範囲内の日付をランダムに取得」をGroovyでやってみた」をトゥギャりました。 http://togetter.com/li/146287

2011-06-09 17:07:21
close_yutori @kimukou2628

@xnrghzjh まあ@kyon_mm様はGroovyの生き地方神様ですから、何でも聞けば答えてくれます。もっと難しいことは上神様の@fumokmmさん辺りに聞けばほとんど解決ですね

2011-06-09 17:20:24
ふも @fumokmm

metaClass版 http://goo.gl/oLMNn RT @kimukou_26: @xnrghzjh まあ@kyon_mm様はGroovyの生き地方神様ですから、何でも聞けば答えてくれます。もっと難しいことは上神様の@fumokmmさん辺りに聞けばほとんど解決ですね

2011-06-09 18:59:23