質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

1028閲覧

以下のコードから引数の書き方のパターンを増やしたい

fall

総合スコア12

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2020/04/22 04:40

編集2020/04/22 05:54

引数として生年月日を渡したらそれを元に年齢を計算するプログラムを作りました。
引数がyyyy/MM/dd以外の書き方(yyyy-MM-dd、yyyMMdd)でも受け付けるよう修正したいです。
どのように修正すればいいでしょうか。
ご教示いただけますと幸いです。
コード2種類のうち下の方は編集中のものです。動作はしていません。

Java

1import java.time.LocalDate; 2import java.time.format.DateTimeFormatter; 3import java.time.format.DateTimeParseException; 4import java.time.temporal.ChronoUnit; 5 6public class Age { 7 public static void main(String[] args) { 8 if (args.length != 1) { 9 System.err.println("Error"); 10 return; 11 } 12 13 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd"); 14 15 LocalDate birthDay; 16 // 生年月日を表す文字列から、LocalDateを生成 17 try { 18 birthDay = LocalDate.parse(args[0], formatter); 19 } catch (DateTimeParseException e) { 20 System.err.println("Error"); 21 System.err.println(e); 22 return; 23 } 24 25 // 現在の日付を取得 26 LocalDate nowDate = LocalDate.now(); 27 28 if (nowDate.compareTo(birthDay) >= 0) { 29 // 年齢を計算する 30 long age = ChronoUnit.YEARS.between(birthDay , nowDate); 31 // 年齢 32 System.out.println("年齢は" + age); 33 } else { 34 System.err.println("Error"); 35 } 36 } 37}

Java

1import java.time.LocalDate; 2import java.time.format.DateTimeFormatter; 3import java.time.format.DateTimeParseException; 4import java.time.temporal.ChronoUnit; 5 6public class Age { 7 public static void main(String[] args) { 8 9 if (args.length != 1) { 10 System.err.println("Err"); 11 System.exit(1); 12 return; 13 } 14 15 // 正規表現のパターンを作成 16 Pattern p = Pattern.compile("^[0-9]+$"); 17 Matcher m = p.matcher(str); 18 19 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); 20 21 // LocalDateを取得 22 LocalDate birthDay; 23 24 try { 25 birthDay = LocalDate.parse(args[0], formatter); 26 } 27 catch ( DateTimeParseException e) { 28 System.err.println("Err"); 29 System.err.println(e); 30 System.exit(1); 31 return; 32 } 33 34 35 // 現在の日付を取得 36 LocalDate nowDate = LocalDate.now(); 37 38 if (nowDate.compareTo(birthDay) >= 0) { 39 // 年齢を計算する 40 long age = ChronoUnit.YEARS.between(birthDay, nowDate); 41 // 年齢を出力 42 System.out.println("年齢は" + age); 43 System.exit(0); 44 } 45 else { 46 System.err.println("Err"); 47 System.exit(1); 48 } 49 } 50} 51

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

momon-ga

2020/04/22 06:03

フォーマット的には、8桁の数字が含まれていればよいのでしょうか? たとえば、”20-20-04-2-2”のような入力でも受け付けますか?
fall

2020/04/22 06:04

”20-20-04-2-2”のような形でも大丈夫です。 8桁を超えた数字の場合にはエラーを表示させたいです。
guest

回答2

0

ベストアンサー

文字列から、スラッシュ、ハイフンを削除するようにコードを組めばいいです

#なんなら数字以外を削除とか

投稿2020/04/22 04:56

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fall

2020/04/22 05:17

ありがとうございます。 DateTimeFormatter formatter = DateTimeFormatter.compile("[0-9]+"); 上記のような書き方で数字以外を削除できるみたいですが、日付型(yyyyMMdd)を適用した上で数字以外を削除する方法がわかりませんでした。
y_waiwai

2020/04/22 05:32

文字列変数の形で、まず数字以外を削除しておいて、DateTimeFormatterにかけましょう
fall

2020/04/22 05:54

ありがとうございます。 質問欄の下のコードを編集しました。 このような書き方になりますか?
y_waiwai

2020/04/22 06:06

String r =args[0].replaceAll("[^0-9]", ""); としたら、r には数値のみが入りますね
fall

2020/04/22 06:14

うまく動作できました!ありがとうございました。
guest

0

方法としましては大きく2つあるかと思います.

1つは, 先に文字列を加工して一定の形式に変換してから年月日として解析することです. (y_waiwai さんが回答されている方法です)

もう1つは, 1つ目で変換できなかったら2つ目の変換, 2つ目の変換で変換できなかったら3つ目の変換...と変換できるまで(もしくは変換するフォーマットが無くなるまで)変換を試すことです.

#追加
3つ目(?)として正規表現で解析するなら, このような感じでしょうか.

java

1import java.util.*; 2import java.util.regex.*; 3import java.time.*; 4import java.time.format.*; 5 6public class Main { 7 private static class TestCase { 8 final String str; 9 final boolean result; 10 private TestCase(String str, boolean result) { this.str = str; this.result = result; } 11 static TestCase True(String str) { return new TestCase(str, true); } 12 static TestCase False(String str) { return new TestCase(str, false); } 13 } 14 public static void main(String[] args) throws Exception { 15 TestCase testPattern[] = { 16 TestCase.True("45671203"),TestCase.True("4567/12/03"),TestCase.True("4567-12-03"), 17 18 TestCase.False("4567123"),TestCase.False("456712301"), 19 TestCase.False("4567-12/30"),TestCase.False("4567=12=30"),TestCase.False("4567-12-00"), 20 TestCase.False("4567-00-30"),TestCase.False("456-12-30"),TestCase.False("45678-12-30"), 21 TestCase.False(""),TestCase.False("A-B-C"),TestCase.False(null), 22 }; 23 String totalResult = "=== OK ==="; 24 for(TestCase test : testPattern) { 25 if(testParse(test.str) != test.result) totalResult = "*** ERR ***"; 26 } 27 System.out.println(totalResult); 28 } 29 private static boolean testParse(String str) { 30 try { 31 LocalDate a = parse(str); 32 System.out.println(a); 33 return true; 34 } catch(Exception e) { 35 System.out.println(e.getMessage()); 36 return false; 37 } 38 } 39 private static Pattern DateParsePattern = Pattern.compile("(\d{4})([/-]?)(\d{2})\2(\d{2})"); 40 private static LocalDate parse(String str) throws DateTimeParseException { 41 Matcher m = DateParsePattern.matcher(str); 42 if(!m.matches()) throw new DateTimeParseException("unmatch format.", str, -1); 43 try { 44 int year = Integer.parseInt(m.group(1)); 45 Month month = Month.of(Integer.parseInt(m.group(3))); 46 int dayOfMonth = Integer.parseInt(m.group(4)); 47 return LocalDate.of(year, month, dayOfMonth); 48 } catch(DateTimeException e) { 49 throw new DateTimeParseException("unmatch format.", str, -1, e); 50 } 51 } 52}

plain

14567-12-03 24567-12-03 34567-12-03 4unmatch format. 5unmatch format. 6unmatch format. 7unmatch format. 8unmatch format. 9unmatch format. 10unmatch format. 11unmatch format. 12unmatch format. 13unmatch format. 14null 15=== OK ===

#追加2
1つ目,2つ目,3つ目...と試す形の場合, 3パターン程度であればあるいは直接並べても良いかもしれませんが, 例えば配列とループにして成功するまで回すという形に出来ます.

java

1 private static DateTimeFormatter parsers[] = new DateTimeFormatter[] { 2 DateTimeFormatter.ofPattern("yyyy/MM/dd"), 3 DateTimeFormatter.ofPattern("yyyy-MM-dd"), 4 DateTimeFormatter.ofPattern("yyyyMMdd") 5 }; 6 private static LocalDate parse(String str) throws DateTimeParseException { 7 DateTimeParseException ex = null; 8 for(DateTimeFormatter parser : parsers) { 9 try { 10 return LocalDate.parse(str, parser); 11 } catch(DateTimeParseException e) { 12 ex = e; 13 } 14 } 15 throw ex; 16 }

plain

14567-12-03 24567-12-03 34567-12-03 4Text '4567123' could not be parsed at index 6 5Text '456712301' could not be parsed at index 0 6Text '4567-12/30' could not be parsed at index 4 7Text '4567=12=30' could not be parsed at index 4 8Text '4567-12-00' could not be parsed at index 4 9Text '4567-00-30' could not be parsed at index 4 10Text '456-12-30' could not be parsed at index 0 11Text '45678-12-30' could not be parsed at index 4 12Text '' could not be parsed at index 0 13Text 'A-B-C' could not be parsed at index 0 14text 15=== OK ===

投稿2020/04/22 05:01

編集2020/04/22 09:05
jimbe

総合スコア13209

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fall

2020/04/22 05:18

ありがとうございます。数字以外を削除する方法を試してみたいと思います。
fall

2020/04/22 06:55

ありがとうございます。 参考にさせていただきます。
fall

2020/04/22 08:44

2つ目の方法の、 つ目で変換できなかったら2つ目の変換, 2つ目の変換で変換できなかったら3つ目の変換...と変換できるまで(もしくは変換するフォーマットが無くなるまで)変換を試す という内容について詳しく方法をお聞きしてもよろしいでしょうか。 DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy/MM/dd"); DateTimeFormatterを上記のように3パターン用意、tryも同じく3パターン用意するという形で実装できますか?
jimbe

2020/04/22 09:08

追加しました.
fall

2020/04/22 10:23

参考にさせて頂きます。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問