#きっかけ
yyyy年m月のフォーマットで値が登録されている選択リスト項目があり
その当月末日の値をそれぞれ日付項目にセットしてほしい。
という感じのご要望があったので実装しました。ApexのPatternクラスを使用します。
今回は 正規表現で年月テキストから年と月を取得し、日付型で月末日を返すメソッド の紹介です。
当月末日のほかに前月末日、翌月末日も用意しました。
Patternクラス(正規表現)を使用した処理については、もう一つ記事を書いていますのでこちら↓もご参考ください。
【Salesforce】【Apex】正規表現でテキスト内から指定文字列を複数取得する
#仕様
選択リスト項目の値のフォーマット「yyyy年m月」
例:1999年12月、2020年1月 など
これらの値を引数にいれて、正規表現で年と月を取得し、日付型で月末日を返します。
※引数が不正な値で日付が取れなかった場合はNULLを返します。
#コード その1
メソッドを置いておきます。
使用したいクラスにコピペして呼び出せば使用できると思います。
前月末日
public static Date getLastDayOfPreviousMonth(String text){
// 年月の正規表現
String regex = '([0-9]{4})年([1-9]|1[0-2])月';
// 正規表現をPatternにコンパイルし、textに一致するMatcherを作成する
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(text);
if (m.find()){
Integer year = Integer.valueOf(m.group(1));
Integer month = Integer.valueOf(m.group(2));
return Date.newInstance(year, month, 0);
}
return NULL;
}
当月末日
public static Date getLastDayOfTheMonth(String text){
// 年月の正規表現
String regex = '([0-9]{4})年([1-9]|1[0-2])月';
// 正規表現をPatternにコンパイルし、textに一致するMatcherを作成する
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(text);
if (m.find()){
Integer year = Integer.valueOf(m.group(1));
Integer month = Integer.valueOf(m.group(2));
return Date.newInstance(year, month + 1, 0);
}
return NULL;
}
翌月末日
public static Date getLastDayOfNextMonth(String text){
// 年月の正規表現
String regex = '([0-9]{4})年([1-9]|1[0-2])月';
// 正規表現をPatternにコンパイルし、textに一致するMatcherを作成する
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(text);
if (m.find()){
Integer year = Integer.valueOf(m.group(1));
Integer month = Integer.valueOf(m.group(2));
return Date.newInstance(year, month + 2, 0);
}
return NULL;
}
・引数の文字列から正規表現にマッチする値をMatcher.find()で検索
・取得した年月文字列をInteger.valueOf()で数値に変換
・Date.newInstance()で月末日の値を取得
の3つがポイントです。
Date.newInstance(year, month, day) ですが、dayを0で指定してあげるとmonthの前月末日になります。
当月末日が取りたい場合は month + 1
翌月末日が取りたい場合は month + 2
を指定してあげるだけです。
#コード その2
ほとんど同じ内容のメソッドをいくつも用意するのはスマートじゃないので
前月か当月か翌月か~を引数で指定できるようにしてまとめたのも置いておきます。
addMonthNum 次第で前々月末日も翌々月末日も取得できますね!
/**
* 年月テキストから月末日付を取得する
* @param text 年月テキスト フォーマット:yyyy年m月
* @param addMonthNum 0:前月末日, 1:当月末日, 2:翌月末日
* @return 月末日付
*/
public static Date getLastDayOfMonth(String text, Integer addMonthNum){
// 年月の正規表現
String regex = '([0-9]{4})年([1-9]|1[0-2])月';
// 正規表現をPatternにコンパイルし、textに一致するMatcherを作成する
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(text);
if (m.find()){
Integer year = Integer.valueOf(m.group(1));
Integer month = Integer.valueOf(m.group(2));
return Date.newInstance(year, month + addMonthNum, 0);
}
return NULL;
}
#結果
いくつかの値で匿名実行したログを載せておきます。
99年99月
年は4桁数値なので1000~9999かゼロパディングした値しかマッチしません。月は1~12のみOKです。
取りたい日付によって正規表現うまくを直したり、取得後の日付の値を判定したりは適宜お願いします。