2016-09-14 97 views
2

うるう年を考慮した正確な年齢を計算したいと思います。私はウェブ上で研究し、いくつかのチュートリアルを見つけましたが、正確に日数の差を計算するうるう年は、[1]:https://answers.yahoo.com/question/index?qid=20110629162003AAof4mTこのリンクの "ベストアンサー"のようです。それは、どのようにすることができます日とI入力誕生日の日付、月最後)「の日= + leapYears日」以下「日計算が住んでいる」およびうるう年を考慮してJavaで年齢を計算する

2を書き​​込み、なぜ)

1:私は、コードを解析したが二つの質問を持っていますおよび年と現在の日、月、年とこれらの2つの日の違いをこのコード内でメインメソッドで見つけることができますか?私は本当にあなたの助けに感謝します。前もって感謝します !

PS:

public class Days { 


     static int leapYear(int year) { 
int leap; 
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) { 
leap = 1; 
} 
else { 
leap = 0; 
} 
return leap; 
} 

static int daysBefore(int month, int day, int year){ 
int days = 0; 
int monthDays[] = new int[] {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 
if (leapYear(year) == 1){ 
monthDays[1] = 29; 
} 
for (int b = 0; b < month - 1; b++){ 
days = days + monthDays[b]; 
} 
days = days + day; 
return days; 
} 
public static void main(String[] args) { 
//Birth date 
int birthMonth = 0; 
int birthDay = 0; 
int birthYear = 0; 

//Due date 
int dueMonth = 0; 
int dueDay = 0; 
int dueYear = 0; 

//(1) Calculate years lived 
int yearsLived = dueYear - birthYear + 1; 

//(2) Calculate leap years 
int leapYears = 0; 
for (int year = birthYear; year < dueYear+1; year++) 
{ 
leapYears = leapYears + leapYear(year); 
} 

//(3) Calculate the number of days in your birth year before birth 
int daysBeforeBirth = daysBefore(birthMonth, birthDay, birthYear); 

//(4) Calculate the number of days remaining in the current year after the due date 
int daysRemaining = 365 - daysBefore(dueMonth, dueDay, dueYear); 

//Calculate days lived 
int days = 0; 
days = days + (365 * yearsLived); 
days = days + leapYears; 
days = days - daysBeforeBirth; 
days = days - daysRemaining; 
} 
} 
+0

カレンダーを使用する –

+1

最初の原則から自分で計算したいのですか、または既存のJDKクラスを使用しますか? –

+5

Calendar: –

答えて

3

これを行う正しい方法は、java.timeパッケージのPeriodクラスとLocalDateクラスです。しかし、あなた自身で計算を再考しようとしているようです。

私がこれを行うことをお勧めする方法は、指定された日付、つまり過去の任意の日付の間の日数である「日数」を計算するクラスを作成することです。次に、指定された2つの日付の間の日数を検索する場合は、両方の日付の「日数」を計算して差し引くことができます。

純粋にグレゴリオ暦のためにここでこれを行っています。このクラスは、グレゴリオ暦の前にはうまくいきません.JDKのような歴史的に正確なジュリアン/グレゴリオ暦のハイブリッドカレンダーを作成しようとはしていません。そして、過去の任意の日付からの日数を計算するのは、12月31日、2BCです。この日付はもちろん、グレゴリオ暦の一部ではありません。ここの目的では問題ではありません。

グレゴリオ伐採前の日付が発生する可能性は低いので、このクラスはあなたの目的に十分すぎるはずです。プロダクションコードでは、この代わりにPeriodLocalDateのクラスを使用することをお勧めします。これはちょうどここにあるので、計算方法を見ることができます。

public class GregorianDate { 

    private final int day; 
    private final int month; 
    private final int year; 

    private static final int[] DAYS_PER_MONTH = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 

    public GregorianDate(int day, int month, int year) { 
     this.day = day; 
     this.month = month; 
     this.year = year; 
    } 

    public boolean isValid() { 
     return month >= 1 && month <= 12 && day >= 1 && day <= daysThisMonth(); 
    } 

    public static int daysBetween(GregorianDate from, GregorianDate to) { 
     return to.dayNumber() - from.dayNumber(); 
    } 

    public static int daysBetween(int fromDay, int fromMonth, int fromYear, int toDay, int toMonth, int toYear) { 
     return daysBetween(new GregorianDate(fromDay, fromMonth, fromYear), new GregorianDate(toDay, toMonth, toYear)); 
    } 

    private int daysThisMonth() { 
     return (isLeapYear() && month == 2) ? 29 : DAYS_PER_MONTH[month]; 
    } 

    private int dayNumber() { 
     return year * 365 + leapYearsBefore() + daysInMonthsBefore() + day; 
    } 

    private boolean isLeapYear() { 
     return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; 
    } 

    private int leapYearsBefore() { 
     return year/4 - year/100 + year/400; 
    } 

    private int daysInMonthsBefore() { 
     switch(month) { 
     case 1: 
      return 0; 
     case 2: 
      return 31; 
     default: 
      // Start with the number in January and February combined 
      int toReturn = isLeapYear() ? 60 : 59; 
      for (int monthToConsider = 3; monthToConsider < month; monthToConsider++) { 
       toReturn += DAYS_PER_MONTH[monthToConsider]; 
      } 
      return toReturn; 
     } 
    } 

} 
1

を、すべてはあなたが年に1日追加leapyear質問1. に答えるために:便宜上、私は上記の示したリンクからのコードが含まれています。

days = days + (365 * yearsLived); 

をし、その後leapyears(= 1日余分1 leapyearを覚えている)の数を追加します。作家は最初にすべての年が正常であった場合に住んでてきた日数計算することによって、この知識を使用しています。

2番目の質問の場合: コードでbirthDate(読み取り:startDate)とdueDate(読み取りendDate)の差を求めています。したがって、開始と終了の違いを計算するには、これらの整数に日付入力を与え、コードは残りの処理を行います。

+0

はい、私はそれを理解しました。素敵で深遠な説明をいただきありがとうございます! –

1

TL; DRあなたはアルゴリズムを模索している場合java.time

を使用して

long ageInDays = 
    ChronoUnit.DAYS.between( 
     LocalDate.of(1960 , 1 , 2) , 
     LocalDate.now(ZoneId.of("America/Montreal")) 
    ); 

、明らかにcorrect Answer by David Wallaceを参照してください。

生産的な作業のためにこれを実行している場合、ではなく、は独自の日付/時刻クラスをロールバックします。古い日時クラス(.Date.Calendarなど)を避け、java.timeクラスを使用します。

enumは、経過時間の計算を含む驚くほどの有用性を持っています。 Temporal個のオブジェクトを渡します。この場合、LocalDateオブジェクトです。 java.timeについて

LocalDate start = LocalDate.of(1960 , 1 , 2) ; 
LocalDate today = LocalDate.now(ZoneId.of("America/Montreal")) ; 
long ageInDays = ChronoUnit.DAYS.between(start , today) ; 

java.timeフレームワークは、Java 8に組み込まれており、後にされています。これらのクラスは、java.util.Date.Calendar、& java.text.SimpleDateFormatなどの面倒な古い日時クラスに取って代わります。

Joda-Timeプロジェクトは、今maintenance modeで、java.timeへの移行をアドバイスします。

詳しくはOracle Tutorialをご覧ください。そして、多くの例と説明のためにStack Overflowを検索してください。

java.time機能ThreeTen-BackportでJava 6 & 7に戻って、移植、さらにThreeTenABPAndroidに適合されているの多く(How to use…を参照)。

ThreeTen-Extraプロジェクトでは、追加のクラスでjava.timeを拡張します。このプロジェクトは、将来のjava.timeへの追加の可能性を証明する土台です。ここでは、IntervalYearWeekYearQuarterなどの便利なクラスがあります。

関連する問題