java-beginner.com ブログ

プログラミングを学習するブログ(Javaをメインに)

整数で与えられた年・月・日をyyyy/MM/dd形式の文字列にする方法の速さを比較

投稿日:

最終更新日:2020年02月29日

アイキャッチ

こんにちは。「Javaを復習する初心者」です。

年・月・日が整数で与えられた場合に、その3つの整数からyyyy/MM/dd形式の文字列を作るという機会は結構あると思います。今回は、年は4桁で与えられることにします。また、月と日は一桁の整数が与えらえるかもしれないという状況とします。

yyyy/MM/dd形式なので月と日の部分はそれぞれ、一桁の整数の場合、2桁目に0で埋めるということです。

例えば、年月日がそれぞれ2019、1、2で与えらた場合、「2019/01/02」という文字列を生成することが目的となります。

今回は、次の2つの方法を考え、それぞれの処理の速さを比較してみました。

  1. String#format()メソッドを使う。
  2. StringBufferを使い、文字を追加していく方法。

1番目の方法ではフォーマット文字列を定義して、String#format()メソッドで目的のフォーマットで文字列を作るということをしました。2番目の方法はif文を使って、2桁目の0を出力するか判定して、文字列を作るということをしました。

String#format()を使う方法

Stringクラスにはformat()メソッドが用意されています。ドキュメントには以下のように定義が書いてあります。

  • public static String format(String format,Object… args)

staticで定義されているので、String.format(a,b,c)という感じで使います。

第一引数には書式文字列と呼ばれる文字列を指定します。今回は年・月・日がそれぞれ整数で与えらえているという想定なので、整数を出力する書式文字列を指定します。具体的には、以下を指定します。

  • “%d/%02d/%02d”

「%d」は10進整数を表します。

「%02d」は最低2桁で出力し、2桁目を0埋めしたい場合の書式設定です。細かい説明は省略しますが、以下に出力例を挙げます。

		System.out.println(String.format("%2d", 1));
		System.out.println(String.format("%02d", 1));

結果

 1
01

今回は年が4桁、月と日が2桁か1桁の整数ということなので、以下のような使い方になります。

		System.out.println(String.format("%d/%02d/%02d", 2021, 4, 1));

結果

2021/04/01

独自のメソッドとして用意したい場合は以下のようにすればよいです。

	private static final String FORMAT = "%d/%02d/%02d";

	public static String zeroSupppress1(int year, int month, int day) {
		return String.format(FORMAT, year, month, day);
	}

上記が今回考えた1番目の方法です。

if文で文字列を作る方法

2番目の方法として思いついたのは、0を追加するかどうかをif文で判定する方法です。

StringBuffer型で文字を追加していくときにif文を使うことにしました。

以下にソースを載せます。

ソース

	private static final String SEPARETOR = "/";

	public static String zeroSupppress2(int year, int month, int day) {

		StringBuffer sb = new StringBuffer();

		sb.append(year);
		sb.append(SEPARETOR);

		if(month < 10) {
			sb.append('0');
		}
		sb.append(month);
		sb.append(SEPARETOR);

		if(day < 10) {
			sb.append('0');
		}
		sb.append(day);

		return sb.toString();

	}

上記では月と日それぞれについて、10未満の場合、先に「0」を追加するということをしています。最大で2桁なので、これで0埋めが出来ました。

例えば以下のように使います。

ソース

		System.out.println(zeroSupppress2(2019, 1, 1));
		System.out.println(zeroSupppress2(2019, 10, 8));
		System.out.println(zeroSupppress2(2019, 9, 11));
		System.out.println(zeroSupppress2(2019, 12, 11));

結果

2019/01/01
2019/10/08
2019/09/11
2019/12/11

結果を見ると、年・月それぞれについて、1桁ならば2桁目に0が出力されています。

速さを比較

以下のソースで1番目と2番目の方法の速さを比較しました。

ソース

public class Test {

	public static void main(String[] args) {

		int max = 300000;
		long start, end;

		start = System.currentTimeMillis();
        for (int i = 0; i < max; i++) {
    		zeroSupppress1(2019, 9, 8);
        }
        end = System.currentTimeMillis();
        System.out.println("方法1: " + (end - start));

        start = System.currentTimeMillis();
        for (int i = 0; i < max; i++) {
    		zeroSupppress2(2019, 9, 8);
        }
        end = System.currentTimeMillis();
        System.out.println("方法2: " + (end - start));


	}

	private static final String FORMAT = "%d/%02d/%02d";

	public static String zeroSupppress1(int year, int month, int day) {
		return String.format(FORMAT, year, month, day);
	}

	private static final String SEPARETOR = "/";

	public static String zeroSupppress2(int year, int month, int day) {

		StringBuffer sb = new StringBuffer();

		sb.append(year);
		sb.append(SEPARETOR);

		if(month < 10) {
			sb.append('0');
		}
		sb.append(month);
		sb.append(SEPARETOR);

		if(day < 10) {
			sb.append('0');
		}
		sb.append(day);

		return sb.toString();

	}


}

結果

方法1: 2094
方法2: 116

結果を見ると、2番目の方がずっと速いということが分かりました。String.format()メソッドは書式文字列を指定することで簡単に出力の形式が実装できますが、処理は結構時間がかかるようです。

以上、参考になれば幸いです。