日付を MM/DD/YY 形式で解析し、現在/前世紀に調整する最良の方法は何ですか?

StackOverflow https://stackoverflow.com/questions/251535

  •  05-07-2019
  •  | 
  •  

質問

当社の顧客の 1 人は、年コンポーネントに 2 桁のみの日付を入力できるようにしたいと考えています。日付は過去になるため、2 桁の年が現在の年より後の場合は前世紀で機能するようにしますが、2 桁の年が現在の年以下の場合は今世紀で機能するようにします。

2008 年 10 月 30 日現在

01/01/01 = 01/01/2001

01/01/09 = 01/01/1909

これは奇妙な要件であり、問​​題は解決しましたが、自分の解決策が気に入らないだけです。もっと良い方法があるような気がします。

助けてくれてありがとう。

public static String stupidDate(String dateString)
{
    String twoDigitYear = StringUtils.right(dateString, 2);
    String newDate = StringUtils.left(dateString, dateString.length() - 2);
    int year = NumberUtils.toInt(twoDigitYear);
    Calendar c = GregorianCalendar.getInstance();
    int centuryInt = c.get(Calendar.YEAR) - year;
    newDate = newDate + StringUtils.left(Integer.toString(centuryInt), 2) + twoDigitYear;
    return newDate;
}
役に立ちましたか?

解決

@bobince が SimpleDateFormat について述べた点を示す Groovy スクリプト (Java に投げるのに十分簡単)。

import java.text.SimpleDateFormat

SimpleDateFormat sdf = new SimpleDateFormat('MM/dd/yy')
SimpleDateFormat fmt = new SimpleDateFormat('yyyy-MM-dd')

Calendar cal = Calendar.getInstance()
cal.add(Calendar.YEAR, -100)
sdf.set2DigitYearStart(cal.getTime())

dates = ['01/01/01', '10/30/08','01/01/09']
dates.each {String d ->
  println fmt.format(sdf.parse(d))
}

収量

2001-01-01
2008-10-30
1909-01-01

他のヒント

SimpleDateFormat は、2 文字の「yy」形式を使用して、2 桁の年の解析をすでに行っています。(もちろん 4 桁も許可されます。)

デフォルトでは、now-80→now+20 が使用されるため、提案したルールとまったく同じではありませんが、(少なくとも Java の世界では)合理的で標準化されており、必要に応じて set2Digit YearStart() を使用してオーバーライドできます。

DateFormat informat= new SimpleDateFormat("MM/dd/yy");
DateFormat outformat= new SimpleDateFormat("MM/dd/yyyy");
return outformat.format(informat.parse(dateString));

長期的には、ISO8601 日付形式 (yyyy-MM-dd) への移行を試みてください。MM/dd/yy はほぼ最悪の日付形式であり、最終的に問題が発生する可能性があるためです。

これはどう:

public static String anEasierStupidDateWithNoStringParsing(String dateString) {
    DateFormat df = new SimpleDateFormat("MM/dd/yyyy");

    //handling ParseExceptions is an exercise left to the reader!
    Date date = df.parse(dateString);
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);

    Calendar now = Calendar.getInstance();
    if (cal.after(now)) {
        cal.add(Calendar.YEAR, -100);
    }

    return cal;
}

言い換えれば、SimpleDateFormat に String を解析させ、SimpleDateFormat (年の文字列を解釈するための独自のルールがあります) は、現在の日付より後の日付を返します。

これにより、返される日付はすべて過去のものであることが保証されます。ただし、次のように解析される可能性のある日付は考慮されていません。 前に この一世紀 - たとえば、次のような形式で MM/dd/yyyy, 、「01/11/12」のような日付文字列は、西暦 12 年 1 月 11 日と解析されます。

Joda Time がオプションの場合:

String inputDate = "01/01/08";
// assuming U.S. style date, since it's not clear from your original question
DateTimeFormatter parser = DateTimeFormat.forPattern("MM/dd/yy");
DateTime dateTime = parser.parseDateTime(inputDate);
// if after current time
if (dateTime.isAfter(new DateTime())) {
    dateTime = dateTime.minus(Years.ONE);
}

return dateTime.toString("MM/dd/yyyy");

Joda Time が Java SE の一部ではないことはわかっています。また、別のスレッドでも述べたように、同じことを行う Java ライブラリがある場合、私は通常、サードパーティのライブラリを使用することを容認しません。ただし、Joda Time を開発している人は、Java 7 に組み込まれる日付と時刻 API である JSR310 の主導者でもあります。したがって、I Joda Time は基本的に将来の Java リリースに組み込まれる予定です。

Date deliverDate = new SimpleDateFormat("MM/dd/yy").parse(deliverDateString);
String dateString2 = new SimpleDateFormat("yyyy-MM-dd").format(deliverDate);

私のために働いています。

Joda 時間のピボット年

優れた Joda-Time 2.5 ライブラリには、この機能が含まれています。自分でコードを記述する必要はありません。電話するだけ withPivotYear()DateTimeFormatter. 。使用方法の例については、リンクされたドキュメントを参照してください。

最良の方法は、Java で日付と時刻に Joda Time API を使用することです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top