読者です 読者をやめる 読者になる 読者になる
スポンサーリンク

JavaScriptで,ランダムな日付情報を取得・表示する関数(うるう年などを加味し,期間の範囲も指定可能)

javascript


JavaScriptで,特定の期間内のランダムな日付を得る関数のサンプルコード。

<script>

// 2つの年月日の間に存在する,ランダムな日付情報を返却する。
// 第一引数を開始日とし,第二引数は開始日よりも後の日付であること。
function getRandomDate( date1, date2 )
{
	// 引数を取り出し
	var y1 = date1.y;
	var m1 = date1.m;
	var d1 = date1.d;
	var y2 = date2.y;
	var m2 = date2.m;
	var d2 = date2.d;
	
	// うるう年などを考慮した,矛盾のない日付オブジェクトを生成
	var d1 = new Date( y1, m1, d1 );
	var d2 = new Date( y2, m2, d2 );
	
	// 差分をミリ秒で求める
	var diff_ms = d2 - d1;
		//alert( "オリジナルの差分は" + diff_ms + "ミリ秒" );
	
	// 差分を0〜100%の割合でランダムに加工する
	var diff_ms_random = Math.random() * diff_ms;
		//alert( "加工された差分は" + diff_ms_random + "ミリ秒" );
	
	// 基準日時に対してランダムな差分を加算し,新たな日付オブジェクトとする
	var d_random = new Date();
	d_random.setTime( d1.getTime() + diff_ms_random );

	// ランダムな日付として返却する
	return d_random;
}


// Dateオブジェクトの年月日を,月と日に対して0埋めした形で連結して返す。
function getYYYYMMDDfromDateObject( obj_d )
{
	var y = obj_d.getFullYear();
	
	var m = obj_d.getMonth() + 1;
	if( m < 10 ) m = "0" + m;
	
	var d = obj_d.getDate();
	if( d < 10 ) d = "0" + d;
	
	return "" + y + m + d;
}


// ランダムな日付の情報を表示
function displayRandomDateString()
{
	// この期間の範囲内で,ランダムな日付を取得
	var random_date = getRandomDate(
		// 開始日
		{ 
			y : 2000, 
			m : 1,
			d : 1
		},
		// 終了日
		{
			y : 2100,
			m : 12,
			d : 31
		}
	);
	
	// 表示
	alert( getYYYYMMDDfromDateObject( random_date ) );
}

</script>


このボタンを押してください:
<input
  type="button" 
  value="ランダムな日付の情報を表示"
  onclick="displayRandomDateString()"
>


ミソ:

  • 引き算した後で,差分を0%〜100%で伸縮し,基準日に足し直している。
  • うるう年など,矛盾のない日付情報を取得したいのであれば,Dateオブジェクトの利用は避けられない。

IEとFirefoxで動作確認済み。


参考:

日付(Date)
http://www.tohoho-web.com/js/date.htm


JavaScript による日付・時刻・時間の計算・演算のまとめ
http://www.hoge256.net/2007/08/64.html

補足

下記の質問への返答として執筆した。

【JavaScript switch文のcaseに変数を使う】日付をランダムに選出して代入するプログラムを作りたい
http://q.hatena.ne.jp/1314526078


上記の質問へのフォロー:

12.11 switch 文 (The switch Statement)
http://www2u.biglobe.ne.jp/~oz-07ams/...

  • switch文に関するECMAScriptの仕様(BNF)


JavaScriptの動かないコード (初級編) switch文で,数値以外の変数を評価した時のエラー
http://language-and-engineering.hatenablog.jp/entry/20100831/p1

  • switch文を使う場合,厳密な型の一致が求められるので注意


上記リンクにあるJavaScript文法の仕様通り,switchステートメント中ではCaseBlock,つまりcase clauseの集合が要求される。

下記のようなコードは,発想はどこかしらRuby的で面白いが,残念ながらinvalid switch statementと評価されエラーになる。

<script>

// 動かない
switch(1)
{
	for( var i = 0; i < 100; i ++ )
	{
		case i:
			alert( i );
			break;
	}
}

</script>


あと,引数はダラダラ並べずに,意味のある固まりごとにまとめて,JSONを渡しましょう。

Javascriptによる大規模開発の覚え書き
http://blog.xole.net/article.php?id=612

  • 3.引数のJSON化(Hash化)せよ


Railsの引数としてのHashの使い方上手いよな
http://d.hatena.ne.jp/LukeSilvia/2008...

補足2:1970年1月1日以前の日付はどうなる?

JavaScriptでは,Dateオブジェクトは,内部的には「UTC(世界協定時刻,1970/1/1 00:00)」から経過したミリ秒に基づいて日時情報を保持している。


こういった経過ミリ秒による管理形式の事を

  • 「UTCミリ秒」

などと呼ぶ。現時点では13ケタである。


もし,ミリ秒ではなく秒単位での経過時間であれば

  • 「UNIXタイムスタンプ」
  • 「UNIX時間」

などと呼ぶ。10ケタなのですぐわかる。

setTimeメソッド
http://www.ajaxtower.jp/js/date_class...

  • Dateクラスの内部では、日付/時刻の値を1970年1月1日0時0分0秒(UTC)を起点とした経過ミリ秒という数値で管理している


システム時刻
http://ja.wikipedia.org/wiki/%E3%82%B...

  • システム時刻とは,任意の開始時刻(エポック)からの経過時間を求めたもの
  • Unix系、ならびにPOSIX互換なオペレーティングシステムでは例えば、1970年1月1日0時0分0秒(UTC,UNIXエポックタイム)から閏秒を考慮しない経過時間(UNIX時間)が使われる
  • Microsoft Windows NTでは1601年1月1日0時0分(UTC)(先発グレゴリオ暦)からの100ナノ秒ティック単位での経過時間が主に用いられる


UNIX TIME キリ番
http://www.geocities.jp/sunpillar0301...

  • 2ちゃんねるのスレッド番号は、Unix TIMEに基づきます。上手くいくと、珍しいURLのスレッドが立ちます。


2038年問題
http://ja.wikipedia.org/wiki/2038%E5%...

  • UNIX秒を符号付き32ビット整数で表していると,2038年1月19日にバッファオーバーフローする予定


ではJavaScriptでは,基準日時である1970年より前の情報は扱えないのか?というと,そうではない。

負のミリ秒をセットすれば,JavaScriptでは1970年以前の日時も扱える。


UTCミリ秒として,マイナスの値をセットするサンプルコード:

<script>

var d = new Date();

// 1970/01/01 9:00
d.setTime( 0 );
alert( d.toString() );
alert( d.getTime() );

// 1970/01/01 8:59
d.setTime( -1 );
alert( d.toString() );
alert( d.getTime() );

// 1969/01/01 9:00
d.setTime( - 365 * 24 * 60 * 60 * 1000 );
alert( d.toString() );
alert( d.getTime() );

</script>

IE8とFirefox6で動作確認済み。


なお,toString() 時に「0:00」ではなく「9:00」と表示されるのは,私が日本国内で作業していることの証である。

ブラウザが勝手にWindows API経由でBIOSと通信して,GMTを判断し,

ロンドン郊外にあるグリニッジ天文台の標準時からみた時差を考慮に入れてくれているのだ。

イヌでもわかるJavaScript講座 / 誕生日から経過日を計算する
http://www.red.oit-net.jp/tatsuya/jav...

  • Date( )には、getTime( )というメソッドがあります。これは、1970年1月1日0時0分0秒0ミリ秒からの通算ミリ秒(経過ミリ秒)を返してくれます。
  • 1970年以前でしたら、マイナス値になります。これを使えば、うるう年は気にしなくて良くなります。
  • 【注意】IE3は1970年以前は扱えません。


Javascript Dates-The Complete Reference
http://www.hunlock.com/blogs/Javascri...

  • Since we didn't specify a timezone the browser will use the user's timezone.
  • Midnight, January 1, 1970 GMT is represented as zero by Javascript. Positive numbers indicate dates after 1970 and negative numbers indicate dates prior to 1970. For instance -1000 represents 11:59:59pm, December 31, 1969.


GMT/グリニッジ標準時
http://ja.wikipedia.org/wiki/%E3%82%B...


JavaのTimestampクラスも同様の扱いが可能なようだ。

public Timestamp(long time)
http://e-class.center.yuge.ac.jp/jdk_...

  • 1970 年 1 月 1 日、0 時 0 分 0 秒 GMT (グリニッジ標準時) を起点とした時間をミリ秒で表した値。負の値は、1970 年 1 月 1 日、0 時 0 分 0 秒 GMT (グリニッジ標準時) より前のミリ秒