Processingで日時指定&ミリ秒表示付きのタイマーを作る
とある目的でProcessingでタイマーを作ることになったのですが、そこでの要件が「日付込みで終了時刻を設定したい」と「ミリ秒の桁(正確には1/100秒の桁)の表示もしたい」の2つでした。これが地味に面倒だったので、どうやったのかの記録をここに残しておきます。ProcessingというよりはもはやJavaの話です。
import java.util.Date; import java.util.Calendar; import java.text.ParseException; import java.text.SimpleDateFormat; // 終了時刻の設定(yyyy/MM/dd hh:mm:ssの形式で記述) Date limit = stringToDate("2020/12/31 23:59:00"); void setup() { size(600, 300); } void draw() { background(50); // 終了時刻と現在時刻の差から残り時間をミリ秒単位で取得 Date current = new Date(); long remaining_ms = limit.getTime() - current.getTime(); if ( remaining_ms < 0 ) remaining_ms = 0; // 残り時間表示 textSize(50); textAlign(CENTER); text( msToString(remaining_ms), width/2, height/2 ); } // 「yyyy/MM/dd hh:mm:ss」形式の文字列をDateに変換 Date stringToDate(String str) { try { SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss"); return sdFormat.parse(str); } catch (ParseException e) { e.printStackTrace(); } return null; } // ミリ秒から「dd days hh:mm:ss:SS」形式の文字列に変換 String msToString(long ms) { final long day_ms = 86400000; final long hour_ms = 3600000; final long min_ms = 60000; final long sec_ms = 1000; long day = ms/day_ms; ms %= day_ms; long hour = ms/hour_ms; ms %= hour_ms; long min = ms/min_ms; ms %= min_ms; long sec = ms/sec_ms; ms %= sec_ms; long SS = ms/10; return nf(day, 1, 0) + "days " + nf(hour, 2, 0) + ":" + nf(min, 2, 0) + ":" + nf(sec, 2, 0) + "." + nf(SS, 2, 0); }
冒頭で終了時刻設定をしてるところの「2020/12/31 23:59:00」という文字列を適宜変更してください。時刻データはDateを使って管理されますが、残り時間をミリ秒まで表示したい関係で、いったんミリ秒に変換してから現在時刻との差を計算し、それをまた時刻文字列に変換しています。なんかもっといいやり方がある気がしますが。