5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Java8〜]日付の曜日を簡潔に取得する方法(ビフォーアフターあり)

Posted at

先日コードレビューをしていると、日付の曜日を取得するUtilクラスを実装してもらったところがありました。

共通処理をUtilクラスに切り出していることはとても良いことでしたが、コードを見るともう少し簡潔に書ける方法がありそうだなと思いました。

調べたところ、非常に簡潔に記述できる方法がありましたので、備忘録のためにも記述しておきます!

※一部抜粋コードで説明します。

修正前のコード

プロダクションコード
import java.time.DayOfWeek;
import java.time.LocalDate;

public class DateUtil {

  /**
   * 曜日を取得する
   *
   * @param baseDate 基準日
   * @return 基準日の曜日
   */
  public static String getDayOfWeek(LocalDate baseDate) {
    if (baseDate == null) {
      return "";
    }

    DayOfWeek dayOfWeek = baseDate.getDayOfWeek();
    switch (dayOfWeek) {
      case SUNDAY:
        return "日";
      case MONDAY:
        return "月";
      case TUESDAY:
        return "火";
      case WEDNESDAY:
        return "水";
      case THURSDAY:
        return "木";
      case FRIDAY:
        return "金";
      case SATURDAY:
        return "土";
      default:
        return "";
    }
  }
}

switch文のところが何やら臭いますね🤔

もっと簡潔に書ける方法がありそう・・

テストコード
public class DateUtilTest {

  @ParameterizedTest
  @MethodSource("providerGetDayOfWeek")
  void getDayOfWeek(LocalDate baseDate, String expected) {
    var actual = DateUtil.getDayOfWeek(baseDate);
    Assertions.assertEquals(expected, actual);
  }

  private static Stream<Arguments> providerGetDayOfWeek() {
    return Stream.of(
        Arguments.of(LocalDate.of(2023, 5, 21), "日"),
        Arguments.of(LocalDate.of(2023, 5, 22), "月"),
        Arguments.of(LocalDate.of(2023, 5, 23), "火"),
        Arguments.of(LocalDate.of(2023, 5, 24), "水"),
        Arguments.of(LocalDate.of(2023, 5, 25), "木"),
        Arguments.of(LocalDate.of(2023, 5, 26), "金"),
        Arguments.of(LocalDate.of(2023, 5, 27), "土")
    );
  }
}

現状のプロダクションコードでも、テストは期待値どおりきちんと成功します。

image.png

修正後のコード(パート1)

Java17以降であれば、switch文を拡張switch文に切り替えることができます。

プロダクションコード
import java.time.DayOfWeek;
import java.time.LocalDate;

public class DateUtil {

  /**
   * 曜日を取得する
   *
   * @param baseDate 基準日
   * @return 基準日の曜日
   */
  public static String getDayOfWeek(LocalDate baseDate) {
    if (baseDate == null) {
      return "";
    }

     DayOfWeek dayOfWeek = baseDate.getDayOfWeek();
-    switch (dayOfWeek) {
-      case SUNDAY:
-        return "日";
-      case MONDAY:
-        return "月";
-      case TUESDAY:
-        return "火";
-      case WEDNESDAY:
-        return "水";
-      case THURSDAY:
-        return "木";
-      case FRIDAY:
-        return "金";
-      case SATURDAY:
-        return "土";
-      default:
-        return "";
-    }

+    return switch (dayOfWeek) {
+      case SUNDAY -> "日";
+      case MONDAY -> "月";
+      case TUESDAY -> "火";
+      case WEDNESDAY -> "水";
+      case THURSDAY -> "木";
+      case FRIDAY -> "金";
+      case SATURDAY -> "土";
+      default -> "";
+    };
  }
}

これでもちょっとは簡潔になりましたよね。

ちなみにテストも成功のままです(リファクタリング成功🙌)
image.png

修正後のコード(パート2)

さらに簡潔に書ける方法を見ていきましょう。

プロダクションコード
import java.time.DayOfWeek;
import java.time.LocalDate;

public class DateUtil {

  /**
   * 曜日を取得する
   *
   * @param baseDate 基準日
   * @return 基準日の曜日
   */
  public static String getDayOfWeek(LocalDate baseDate) {
    if (baseDate == null) {
      return "";
    }

     DayOfWeek dayOfWeek = baseDate.getDayOfWeek();
-    switch (dayOfWeek) {
-      case SUNDAY:
-        return "日";
-      case MONDAY:
-        return "月";
-      case TUESDAY:
-        return "火";
-      case WEDNESDAY:
-        return "水";
-      case THURSDAY:
-        return "木";
-      case FRIDAY:
-        return "金";
-      case SATURDAY:
-        return "土";
-      default:
-        return "";
-    }
   
+   return dayOfWeek.getDisplayName(TextStyle.SHORT, Locale.JAPANESE); 
  }
}

たった1行です!

コードの説明をすると、

DayOfWeek dayOfWeek = baseDate.getDayOfWeek();

ここで、getDayOfWeek()メソッドを使用して、baseDateというLocalDateオブジェクトから曜日を取得してdayOfWeekに格納しています。

dayOfWeekにはenumのDayOfWeek型が入っています。このenumには、MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAYといった値が定義されています。

dayOfWeek.getDisplayName(TextStyle.SHORT, Locale.JAPANESE);

enumのDayOfWeek型のインスタンスは、getDisplayName()メソッドを持っており、このメソッドは、指定したTextStyleとLocale(ロケール、地域設定)に基づいて曜日の名前を取得します。

ここでは、TextStyle.SHORTとLocale.JAPANESEを指定しているため、曜日の日本語の短い名前(例えば、"月"、"火"、"水"など)を取得します。

TextStyle.FULLだと、"日曜日"や"月曜日"となります。
※詳しくは[参考]へ

最後にテストも確認しておきましょう!

きちんと成功のままリファクタリングできています🙌
image.png

以上です!

参考

https://docs.oracle.com/javase/jp/8/docs/api/java/time/DayOfWeek.html
https://docs.oracle.com/javase/jp/8/docs/api/java/time/format/TextStyle.html
https://docs.oracle.com/javase/jp/8/docs/api/java/util/Locale.html

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?