Java를 사용하여 두 날짜 사이의 날짜 계산


150

두 날짜 사이의 날짜를 계산하는 Java 프로그램이 필요합니다.

  1. 첫 번째 날짜를 입력하십시오 (독일 표기법; 공백 포함 : "dd mm yyyy")
  2. 두 번째 날짜를 입력하십시오.
  3. 프로그램은 두 날짜 사이의 일 수를 계산해야합니다.

윤년과 여름을 어떻게 포함시킬 수 있습니까?

내 코드 :

import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;

public class NewDateDifference {

    public static void main(String[] args) {

        System.out.print("Insert first date: ");
        Scanner s = new Scanner(System.in);
        String[] eingabe1 = new String[3];

        while (s.hasNext()) {
            int i = 0;
            insert1[i] = s.next();
            if (!s.hasNext()) {
                s.close();
                break;
            }
            i++;
        }

        System.out.print("Insert second date: ");
        Scanner t = new Scanner(System.in);
        String[] insert2 = new String[3];

        while (t.hasNext()) {
            int i = 0;
            insert2[i] = t.next();
            if (!t.hasNext()) {
                t.close();
                break;
            }
            i++;
        }

        Calendar cal = Calendar.getInstance();

        cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(insert1[0]));
        cal.set(Calendar.MONTH, Integer.parseInt(insert1[1]));
        cal.set(Calendar.YEAR, Integer.parseInt(insert1[2]));
        Date firstDate = cal.getTime();

        cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(insert2[0]));
        cal.set(Calendar.MONTH, Integer.parseInt(insert2[1]));
        cal.set(Calendar.YEAR, Integer.parseInt(insert2[2]));
        Date secondDate = cal.getTime();


        long diff = secondDate.getTime() - firstDate.getTime();

        System.out.println ("Days: " + diff / 1000 / 60 / 60 / 24);
    }
}

작동하지 않는 것은 무엇입니까? 충돌합니까? 숫자가 잘못 되었습니까?
jens108

배열 선언은 어디에 있습니까 : insert1?
Rhys

1
insert1 = 독일어에서 eingabe1 :)
peter.petrov

@ peter.petrov 아, 알겠습니다!
Rhys

나는 그가 함께 문제를 가지고 생각 mmMMP :
세이지

답변:


230

업데이트 : 일부 클래스가 교체되어 2013 년의 원래 답변이 구식입니다. 이 작업을 수행하는 새로운 방법은 새 java.time클래스를 사용하는 것 입니다.

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MM yyyy");
String inputString1 = "23 01 1997";
String inputString2 = "27 04 1997";

try {
    LocalDateTime date1 = LocalDate.parse(inputString1, dtf);
    LocalDateTime date2 = LocalDate.parse(inputString2, dtf);
    long daysBetween = Duration.between(date1, date2).toDays();
    System.out.println ("Days: " + daysBetween);
} catch (ParseException e) {
    e.printStackTrace();
}

이 솔루션은 달력 일 수가 아닌 실제 24 시간의 일 수를 제공합니다. 후자의 경우

long daysBetween = ChronoUnit.DAYS.between(date1, date2)

원문 답변 (자바 8 이전)

필요하지 않은 문자열로 변환하고 있습니다. SimpleDateFormat그것에 대한 수업이 있습니다-이것을 시도하십시오 :

SimpleDateFormat myFormat = new SimpleDateFormat("dd MM yyyy");
String inputString1 = "23 01 1997";
String inputString2 = "27 04 1997";

try {
    Date date1 = myFormat.parse(inputString1);
    Date date2 = myFormat.parse(inputString2);
    long diff = date2.getTime() - date1.getTime();
    System.out.println ("Days: " + TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));
} catch (ParseException e) {
    e.printStackTrace();
}

편집 : 이 코드의 정확성에 관한 몇 가지 토론이 있었으므로 실제로 윤년을 처리합니다. 그러나 TimeUnit.DAYS.convert밀리 초가 일로 변환되므로 함수의 정밀도가 떨어집니다 (자세한 내용은 링크 된 문서 참조). 이것이 문제인 경우 diff수동으로 변환 할 수도 있습니다.

float days = (diff / (1000*60*60*24));

float값 은 반드시 값일 필요는 없습니다 int.


40
이것은 윤년을 제대로 설명하지 못하는 나쁜 구현입니다.
Groovy Ed

3
TimeUnit.DAYS.convert (diff, TimeUnit.MILLISECONDS)); <3
Guihgo

3
@GroovyEd 내가 테스트 한 것으로 부터이 코드는 윤년에 문제가없는 것 같습니다. TimeUnit.Days.convert ()는 남은 단위를 무시합니다. 예를 들어 999 밀리 초를 초로 변환하면 0이됩니다. 즉, Date 객체 중 하나로 new Date ()를 사용하면 하루가 덜 걸릴 수 있으므로주의해야합니다.
Klitos G.

3
윤년에도 효과가 있습니다. 이 String inputString1 = "28 2 2016"; String inputString2 = "1 3 2016";답변을 확인하십시오 : 2
Rohit Gaikwad

10
나는 이것이 윤년 동안 올바르게 작동한다고 생각하지만 일광 절약 시간을 망칩니다. 로케일의 일광 절약 시간이 매년 인 경우 하루에 23 시간, 하루에 25 시간이 있습니다. 이 솔루션은 매일 24 시간이 있다고 잘못 가정합니다. 따라서 일광 절약 시간이 아닌 시간에 시작하여 일광 절약 시간에 끝나는 모든 기간에 대해 잘못된 답변을 제공합니다. 이 솔루션을 사용하지 마십시오. 더 좋은 방법이 있습니다.
Dawood ibn Kareem

100

가장 간단한 방법 :

public static long getDifferenceDays(Date d1, Date d2) {
    long diff = d2.getTime() - d1.getTime();
    return TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
}

7
글쎄, 기본적으로 이것은 현재 최고의 답변 과 동일 하지만이 답변은 함수로 제공합니다.
Andrew T.

16
이 날짜는 두 날짜 사이의 시간 간격이 24 시간보다 큰 경우에만 해당되므로 (코드에서 getDifferenceDays(11PM, 4 AM nextday) == 0
분명함

1
이 구현은 오늘처럼 마지막 날이 걸립니다. 예를 들어 d1 = today 및 d2 = yesterday로 프로그램을 실행하면 0 일이 반환됩니다.
karvoynistas

1
@Nav 6 월에 30 일이 있기 때문입니다.
Dawood ibn Kareem

1
이 답변은 잘못되었습니다. 일광 절약 시간을 올바르게 처리하지 못합니다. 올바른 결과를 원하면 사용하지 마십시오.
Dawood ibn Kareem

89

Java 8에서는 LocalDateand 를 사용하여이를 수행 할 수 DateTimeFormatter있습니다. 로부터 의 JavadocLocalDate:

LocalDate는 날짜를 나타내는 변경 불가능한 날짜-시간 객체이며, 종종 연월일로 표시됩니다.

패턴을 사용하여 구성 할 수 있습니다 DateTimeFormatter. 다음은 Javadoc 및 내가 사용한 관련 패턴 문자입니다.

기호 -의미- 프리젠 테이션 -예

Y - 년의 시대 - - 2004; 04

M / L- 년- 숫자 / 텍스트 -7; 07; 7 월; 칠월; 제이

d- 월- 숫자 -10

예를 들면 다음과 같습니다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

public class Java8DateExample {
    public static void main(String[] args) throws IOException {
        final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MM yyyy");
        final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        final String firstInput = reader.readLine();
        final String secondInput = reader.readLine();
        final LocalDate firstDate = LocalDate.parse(firstInput, formatter);
        final LocalDate secondDate = LocalDate.parse(secondInput, formatter);
        final long days = ChronoUnit.DAYS.between(firstDate, secondDate);
        System.out.println("Days between: " + days);
    }
}

가장 최근의 입력 / 출력 예 :

23 01 1997
27 04 1997
Days between: 94

더 최근의 첫 번째 :

27 04 1997
23 01 1997
Days between: -94

글쎄, 당신은 더 간단한 방법으로 그것을 할 수 있습니다 :

public static long betweenDates(Date firstDate, Date secondDate) throws IOException
{
    return ChronoUnit.DAYS.between(firstDate.toInstant(), secondDate.toInstant());
}

4
훌륭한 예입니다. 이것은 윤년을 자동으로 설명합니다. 1991 년과 1992 년 (윤년)을 확인하면 올바르게 계산됩니다. 완전한!
woahguy

표준 라이브러리를 많이 사용합니다.
dieresys

이것은 현재 허용되는 답변이어야합니다. 윤년 및 일광 절약 시간의 표준 라이브러리 사용 및 계정은 문제가되지 않습니다.
Pehmolelu

3
이것은 현재 / 현대 답변입니다 (다른 것들은 구식입니다). 또한 서머 타임 (DST)을 설명합니다. Java 6 또는 7에서 사용하려면 ThreeTen Backport를 가져 오십시오 . 새로운 Android ThreeTenABP 에서
Ole VV

일광 절약 시간을 고려하지 않습니다
Alex

63

일광 절약 시간이 다가 왔을 때 대부분 / 모든 답변에서 문제가 발생했습니다. JodaTime을 사용하지 않고 모든 날짜에 대한 작업 솔루션은 다음과 같습니다. 달력 객체를 사용합니다.

public static int daysBetween(Calendar day1, Calendar day2){
    Calendar dayOne = (Calendar) day1.clone(),
            dayTwo = (Calendar) day2.clone();

    if (dayOne.get(Calendar.YEAR) == dayTwo.get(Calendar.YEAR)) {
        return Math.abs(dayOne.get(Calendar.DAY_OF_YEAR) - dayTwo.get(Calendar.DAY_OF_YEAR));
    } else {
        if (dayTwo.get(Calendar.YEAR) > dayOne.get(Calendar.YEAR)) {
            //swap them
            Calendar temp = dayOne;
            dayOne = dayTwo;
            dayTwo = temp;
        }
        int extraDays = 0;

        int dayOneOriginalYearDays = dayOne.get(Calendar.DAY_OF_YEAR);

        while (dayOne.get(Calendar.YEAR) > dayTwo.get(Calendar.YEAR)) {
            dayOne.add(Calendar.YEAR, -1);
            // getActualMaximum() important for leap years
            extraDays += dayOne.getActualMaximum(Calendar.DAY_OF_YEAR);
        }

        return extraDays - dayTwo.get(Calendar.DAY_OF_YEAR) + dayOneOriginalYearDays ;
    }
}

일광 절약 시간제 전환을 멋지게 처리
Ravi

1
그러나 대답에 +1 Calendar dayOne = (Calendar) day1.clone(), dayTwo = (Calendar) day2.clone();하면 원래 캘린더 값이 재정의되지 않으므로 행이 필요하다는 것을 추가하고 싶습니다 . 나는이 줄을 중복으로 생각하고 삭제하여 원래 객체의 값 이이 함수 내에서 덮어 쓰여졌다는 사실에 1 시간을 낭비했습니다.
Rohan Kandwal

2
Calendar 클래스에서 월 값은 0을 기준으로합니다. calendar.set (2015, 11, 30, 0, 00, 00); 실제로 30/12/2015을 의미
Dmitry

20

가장 좋은 방법은 보너스로 문자열로 변환합니다.)

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    try {
        //Dates to compare
        String CurrentDate=  "09/24/2015";
        String FinalDate=  "09/26/2015";

        Date date1;
        Date date2;

        SimpleDateFormat dates = new SimpleDateFormat("MM/dd/yyyy");

        //Setting dates
        date1 = dates.parse(CurrentDate);
        date2 = dates.parse(FinalDate);

        //Comparing dates
        long difference = Math.abs(date1.getTime() - date2.getTime());
        long differenceDates = difference / (24 * 60 * 60 * 1000);

        //Convert long to String
        String dayDifference = Long.toString(differenceDates);

        Log.e("HERE","HERE: " + dayDifference);
    }
    catch (Exception exception) {
        Log.e("DIDN'T WORK", "exception " + exception);
    }
}

예외를 던질 가능성은 무엇입니까?
CoDe

윤년에는 작동하지 않습니다. 예를 들어 "02/15/2020"에서 "04/02/2020"까지는 47 일입니다. 이 논리는 46이 될 것입니다.
user1070304

11

사용하다:

public int getDifferenceDays(Date d1, Date d2) {
    int daysdiff = 0;
    long diff = d2.getTime() - d1.getTime();
    long diffDays = diff / (24 * 60 * 60 * 1000) + 1;
    daysdiff = (int) diffDays;
    return daysdiff;
}

이것은 윤년과 일광 절약을 설명합니까?
맥스 알렉산더 한나

1
그것은 윤년을 올바르게 설명하지만 일광 절약은 아닙니다. 일광 절약 시간 이외의 시간에는 기간이 시작될 때만 일광 절약 시간에는 끝날 때마다 정답을 제공합니다. 다른 모든 경우에는 하나씩입니다.
Dawood ibn Kareem

1
@saidesh_kilaru "+ 1"은 무엇입니까? 나는 당신이 그것을 제거해야한다고 생각합니다.
Alisa

INT로 캐스팅하면 4가 발생하고 플로팅으로 캐스팅하면 4.9가 발생하는 문제가 발생하여 실제로 원하는 것이 아닙니다. 아마도 23:59의 date1과 00:01의 date2의 경우와 예상 결과가 무엇인지 명확하게 설명하지 않았을 수도 있습니다.
EricG

10

Java 날짜 라이브러리가 손상되었습니다. Joda Time 을 사용하는 것이 좋습니다 . 윤년, 시간대 등을 관리합니다.

최소 작업 예 :

import java.util.Scanner;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class DateTestCase {

    public static void main(String[] args) {

        System.out.print("Insert first date: ");
        Scanner s = new Scanner(System.in);
        String firstdate = s.nextLine();
        System.out.print("Insert second date: ");
        String seconddate = s.nextLine();

        // Formatter
        DateTimeFormatter dateStringFormat = DateTimeFormat
                .forPattern("dd MM yyyy");
        DateTime firstTime = dateStringFormat.parseDateTime(firstdate);
        DateTime secondTime = dateStringFormat.parseDateTime(seconddate);
        int days = Days.daysBetween(new LocalDate(firstTime),
                                    new LocalDate(secondTime)).getDays();
        System.out.println("Days between the two dates " + days);
    }
}

4
이 답변은 몇 가지 방법으로 개선 될 수 있습니다. (a) JVM의 기본값에 의존하지 않고 시간대를 지정하십시오. 따라서 DateTimeFormatter를 만들 때에 호출을 추가하십시오 withZone( DateTimeZone.forID( "Europe/Berlin" ) ). (ㄴ) 사용 LocalDatedaysBetween전화? DateTime 객체 (firstTime, secondTime)를 전달하십시오. 하루 종일 전화하십시오 withTimeAtStartOfDays. 내가 변수 이름을 사용합니다 (C) firstDateTime보다는 firstTime날짜, 시간 및 날짜 - 시간 객체 사이의 모호성을 피하기 위해. (d) 예상 형식과 일치하지 않는 잘못된 데이터 입력을 처리하기 위해 try-catch를 추가하십시오.
Basil Bourque

5
String dateStart = "01/14/2015 08:29:58";
String dateStop = "01/15/2015 11:31:48";

//HH converts hour in 24 hours format (0-23), day calculation
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

Date d1 = null;
Date d2 = null;

d1 = format.parse(dateStart);
d2 = format.parse(dateStop);

//in milliseconds
long diff = d2.getTime() - d1.getTime();

long diffSeconds = diff / 1000 % 60;
long diffMinutes = diff / (60 * 1000) % 60;
long diffHours = diff / (60 * 60 * 1000) % 24;
long diffDays = diff / (24 * 60 * 60 * 1000);

System.out.print(diffDays + " days, ");
System.out.print(diffHours + " hours, ");
System.out.print(diffMinutes + " minutes, ");
System.out.print(diffSeconds + " seconds.");

1

프로그램을 실행할 때 두 번째 날짜를 입력 할 수있는 시점까지 가지 않습니다.

이것은 간단하고 오류가 적습니다.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Test001 {

    public static void main(String[] args) throws Exception {

        BufferedReader br = null;

        br = new BufferedReader(new InputStreamReader(System.in));
        SimpleDateFormat sdf = new SimpleDateFormat("dd MM yyyy");

        System.out.println("Insert first date : ");
        Date dt1 = sdf.parse(br.readLine().trim());

        System.out.println("Insert second date : ");
        Date dt2 = sdf.parse(br.readLine().trim());

        long diff = dt2.getTime() - dt1.getTime();

        System.out.println("Days: " + diff / 1000L / 60L / 60L / 24L);

        if (br != null) {
            br.close();
        }
    }
}

1
// date format, it will be like "2015-01-01"
private static final String DATE_FORMAT = "yyyy-MM-dd";

// convert a string to java.util.Date
public static Date convertStringToJavaDate(String date)
        throws ParseException {
    DateFormat dataFormat = new SimpleDateFormat(DATE_FORMAT);
    return dataFormat.parse(date);
}

// plus days to a date
public static Date plusJavaDays(Date date, int days) {
    // convert to jata-time
    DateTime fromDate = new DateTime(date);
    DateTime toDate = fromDate.plusDays(days);
    // convert back to java.util.Date
    return toDate.toDate();
}

// return a list of dates between the fromDate and toDate
public static List<Date> getDatesBetween(Date fromDate, Date toDate) {
    List<Date> dates = new ArrayList<Date>(0);
    Date date = fromDate;
    while (date.before(toDate) || date.equals(toDate)) {
        dates.add(date);
        date = plusJavaDays(date, 1);
    }
    return dates;
}

0

LocalDate 및 ChronoUnit Java 라이브러리를 사용할 수 있습니다. 아래 코드는 정상적으로 작동합니다. 날짜는 yyyy-MM-dd 형식이어야합니다.

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.*;
class Solution {
    public int daysBetweenDates(String date1, String date2) {
        LocalDate dt1 = LocalDate.parse(date1);
        LocalDate dt2= LocalDate.parse(date2);

        long diffDays = ChronoUnit.DAYS.between(dt1, dt2);

        return Math.abs((int)diffDays);
    }
}

4
기여해 주셔서 감사합니다. 나는이 좋은 제안이 이미 mkobit의 답변에 제시되었다고 생각합니다.
Ole VV
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.