Java 캘린더를 사용하여 날짜에서 X 일을 빼는 방법은 무엇입니까?


180

누구나 Java 달력을 사용하여 날짜에서 X 일을 빼는 간단한 방법을 알고 있습니까?

Java에서 날짜에서 X 일을 직접 빼는 함수를 찾을 수 없었습니다. 누군가 올바른 방향으로 나를 가리킬 수 있습니까?


참고로, 귀찮은 된 날짜 - 시간 클래스는 다음과 같은 java.util.Calendar지금 기존 에 의해 대체, java.time의 클래스. Oracle의 Tutorial을 참조하십시오 .
Basil Bourque

답변:


309

여기 문서 에서 가져온 :

캘린더 규칙에 따라 지정된 캘린더 필드에 지정된 시간을 더하거나 뺍니다. 예를 들어, 달력의 현재 시간에서 5 일을 빼려면 다음을 호출하여 달성 할 수 있습니다.

Calendar calendar = Calendar.getInstance(); // this would default to now
calendar.add(Calendar.DAY_OF_MONTH, -5).

1
항상 예상대로 롤링되는 것은 아니기 때문에이 작업을주의하십시오.
carson

1
이 답변에는 많은 투표가 있지만 사용하는 것이 안전합니까? 또는 이것이 더 낫다 : stackoverflow.com/a/10796111/948268
Kuldeep Jain

44
원하는 Calendar.DAY_OF_MONTH경우 몇 개월 사이에 롤을 처리하지 않으므로이 경우에는 사용 하지 않습니다. 사용 Calendar.DAY_OF_YEAR대신에
알고리즘

4
이것은 당신이 그것을 추가 할 분명히 할 때, 안전해야 문제가되지 않습니다 경우의 DAY_OF_MONTH 또는 DAY_OF_YEAR stackoverflow.com/q/14065198/32453
rogerdpack

@ carson이 접근법의 문제점은 무엇입니까?
tatmanblue

38

add메소드를 사용하고 음수로 전달할 수 있습니다. 그러나 Calendar다음과 같은 클래스를 사용하지 않는 간단한 메소드를 작성할 수도 있습니다.

public static void addDays(Date d, int days)
{
    d.setTime( d.getTime() + (long)days*1000*60*60*24 );
}

이것은 날짜의 시간 소인 값 (에포크 이후 밀리 초)을 가져오고 적절한 밀리 초 수를 추가합니다. days 매개 변수에 음수를 전달하여 빼기를 수행 할 수 있습니다. 이것은 "적절한"캘린더 솔루션보다 간단합니다.

public static void addDays(Date d, int days)
{
    Calendar c = Calendar.getInstance();
    c.setTime(d);
    c.add(Calendar.DATE, days);
    d.setTime( c.getTime().getTime() );
}

이 두 가지 솔루션 모두 Date완전히 새로운을 반환하지 않고 매개 변수로 전달 된 객체를 변경합니다 Date. 원하는 경우 다른 방법으로 기능을 쉽게 변경할 수 있습니다.


3
.setTime 및 .add가 Calendar의 정적 메소드라고는 생각하지 마십시오. 인스턴스 변수를 사용해야합니다. c.
Edward

@ 에드워드 : 당신은 정확합니다. 내 실수를 지적 해 주셔서 감사합니다. 코드가 올바르게 작동하도록 코드를 수정했습니다.
Eli Courtwright

3
leapyear 일 처리가 실패 할 때 예를 들어, 첫 번째 방법에주의 : stackoverflow.com/a/1006388/32453
rogerdpack

참고로, 귀찮은 된 날짜 - 시간 클래스는 다음과 같은 java.util.Calendar지금 기존 에 의해 대체, java.time의 클래스. Oracle의 Tutorial을 참조하십시오 .
Basil Bourque

36

Anson의 대답 은 간단한 경우에는 잘 작동하지만 더 복잡한 날짜 계산을 수행하려면 Joda Time을 확인하는 것이 좋습니다 . 그것은 당신의 인생을 훨씬 쉽게 만들어 줄 것입니다.

참고로 Joda Time에서 할 수있는 일

DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);

1
@ShahzadImam, DateTimeFormat을 확인하십시오 . 임의의 형식을 사용하여 DateTime 인스턴스를 문자열로 변환 할 수 있습니다. java.text.DateFormat 클래스와 매우 유사합니다.
Mike Deck


참고로 Joda-Time 프로젝트는 이제 유지 관리 모드 에 있으며 팀은 java.time 클래스 로의 마이그레이션을 조언합니다 . Oracle의 Tutorial을 참조하십시오 .
Basil Bourque

19

tl; dr

LocalDate.now().minusDays( 10 )

시간대를 지정하는 것이 좋습니다.

LocalDate.now( ZoneId.of( "America/Montreal" ) ).minusDays( 10 )

세부

java.util.Date/ 와 같이 초기 버전의 Java와 번들로 제공되는 이전 날짜-시간 클래스 .Calendar는 번거롭고 혼란스럽고 결함이있는 것으로 입증되었습니다. 피하십시오.

java.time

Java 8 이상은 새로운 java.time 프레임 워크로 이전 클래스를 대체합니다. 튜토리얼을 참조하십시오 . JSR 310에 의해 정의되고 Joda-Time 에서 영감을 얻었으며 ThreeTen-Extra 프로젝트에 의해 확장되었습니다 . ThreeTen-Backport 프로젝트는 클래스를 Java 6 & 7로 백 포트합니다. ThreeTenABP 프로젝트를 Android로

날짜 만 요청하는지 또는 날짜-시간을 요구하는지 명확하지 않은 질문은 모호합니다.

LocalDate

시간이없는 날짜 전용 LocalDate클래스를 사용하십시오 . "오늘"과 같은 날짜를 결정하는 데 중요한 시간대가 있습니다.

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
LocalDate tenDaysAgo = today.minusDays( 10 );

ZonedDateTime

날짜-시간을 의미 한 경우 Instant클래스를 사용하여 UTC로 시간 표시 막대에 순간을 가져옵니다 . 거기에서 표준 시간대로 조정하여 ZonedDateTime개체 를 가져옵니다 .

Instant now = Instant.now();  // UTC.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
ZonedDateTime tenDaysAgo = zdt.minusDays( 10 );

최신 및 기존 Java의 날짜-시간 유형 테이블.


java.time에 대하여

java.time의 프레임 워크는 나중에 자바 8에 내장되어 있습니다. 이 클래스는 까다로운 기존에 대신 기존 과 같은 날짜 - 시간의 수업을 java.util.Date, Calendar, SimpleDateFormat.

Joda 타임 프로젝트는 지금에 유지 관리 모드 의로 마이그레이션을 조언 java.time의 클래스.

자세한 내용은 Oracle Tutorial을 참조하십시오 . 많은 예제와 설명을 보려면 스택 오버플로를 검색하십시오. 사양은 JSR 310 입니다.

java.time 객체를 데이터베이스와 직접 교환 할 수 있습니다 . JDBC 4.2 이상을 준수 하는 JDBC 드라이버를 사용하십시오 . 문자열이 필요없고 수업이 필요 없습니다 .java.sql.*

java.time 클래스는 어디서 구할 수 있습니까?

ThreeTen - 추가 프로젝트 추가 클래스와 java.time를 확장합니다. 이 프로젝트는 향후 java.time에 추가 될 수있는 입증 된 근거입니다. 당신은 여기에 몇 가지 유용한 클래스와 같은 찾을 수 있습니다 Interval, YearWeek, YearQuarter, 그리고 .


이것은 다른 옵션보다 훨씬 개선 된 것입니다 (또한 훨씬 더 새롭고 새로운 방법을 사용합니다). 지금이 문제를 방문하고 있다면 바로이 방법입니다.
Shourya Bansal


5

대신 내 자신을 쓰는 addDays엘리에 의해 제안, 내가 사용하는 것을 선호 DateUtils에서 아파치 . 프로젝트에서 여러 위치를 사용해야 할 때 특히 편리합니다.

API는 말합니다 :

addDays(Date date, int amount)

새 개체를 반환하는 날짜에 일 수를 추가합니다.

Date객체를 반환하고 이전 객체 자체는 변경하지 않습니다.


2

다음과 같이 쉽게 수행 할 수 있습니다

Calendar calendar = Calendar.getInstance();
        // from current time
        long curTimeInMills = new Date().getTime();
        long timeInMills = curTimeInMills - 5 * (24*60*60*1000);    // `enter code here`subtract like 5 days
        calendar.setTimeInMillis(timeInMills);
        System.out.println(calendar.getTime());

        // from specific time like (08 05 2015)
        calendar.set(Calendar.DAY_OF_MONTH, 8);
        calendar.set(Calendar.MONTH, (5-1));
        calendar.set(Calendar.YEAR, 2015);
        timeInMills = calendar.getTimeInMillis() - 5 * (24*60*60*1000);
        calendar.setTimeInMillis(timeInMills);
        System.out.println(calendar.getTime());

이 답변은 지금은 레거시 인 끔찍한 오래된 날짜-시간 클래스를 사용하여 잘못 권장됩니다. java.time 클래스로 대체되었습니다. 또한이 코드는 시간대의 중요한 문제를 무시하고 순진하게 24 시간을 가정합니다. 또 다른 문제는 날짜 전용 클래스를 사용하여 날짜 전용 문제를 해결하는 것입니다. 사용 LocalDate이 훨씬 간단하고 적절합니다.
Basil Bourque

1

누군가 Joda Time을 추천 했으므로이 CalendarDate 클래스를 사용하고 있습니다. http://calendardate.sourceforge.net

Joda Time과 다소 경쟁이 치열하지만 2 개 클래스에서만 훨씬 더 기본적입니다. 프로젝트보다 큰 패키지를 사용하고 싶지 않기 때문에 매우 편리하고 필요한 기능을 수행했습니다. Java 대응과 달리 가장 작은 단위는 요일이므로 실제로 날짜입니다 (밀리 초 또는 그 이하로 줄이지 않음). 날짜를 만든 후에는 myDay.addDays (-5)와 같이 5 일 뒤로 돌아가는 것만 빼면됩니다. 그것을 사용하여 요일과 그와 같은 것을 찾을 수 있습니다. 다른 예시:

CalendarDate someDay = new CalendarDate(2011, 10, 27);
CalendarDate someLaterDay = today.addDays(77);

과:

//print 4 previous days of the week and today
String dayLabel = "";
CalendarDate today = new CalendarDate(TimeZone.getDefault());
CalendarDateFormat cdf = new CalendarDateFormat("EEE");//day of the week like "Mon"
CalendarDate currDay = today.addDays(-4);
while(!currDay.isAfter(today)) {
    dayLabel = cdf.format(currDay);
    if (currDay.equals(today))
        dayLabel = "Today";//print "Today" instead of the weekday name
    System.out.println(dayLabel);
    currDay = currDay.addDays(1);//go to next day
}

1

java.time.Instant 클래스를 사용하여 시간 단위 (월, 일, 시간, 분, 초 등)를 빼거나 추가하는 깨끗하고 멋진 방법을 얻을 수 있다고 생각 합니다.

현재 시간에서 5 일을 빼고 결과를 날짜로 가져 오는 예 :

new Date(Instant.now().minus(5, ChronoUnit.DAYS).toEpochMilli());

1 시간을 빼고 15 분을 더하는 또 다른 예 :

Date.from(Instant.now().minus(Duration.ofHours(1)).plus(Duration.ofMinutes(15)));

정확도가 더 필요한 경우 인스턴스는 최대 나노초를 측정합니다. 나노초 부분을 조작하는 방법 :

minusNano()
plusNano()
getNano()

또한 Date는 Instant만큼 정확하지 않습니다.


1
또는 맛에 따라 약간 짧습니다.Date.from(Instant.now().minus(5, ChronoUnit.DAYS))
Ole VV

1
좋은! 네 말이 맞아 실제로 이것을 사용하기 위해 답변을 업데이트하고 java.time.Duration 클래스의 사용법을 보여줍니다.이 경우에도 매우 강력합니다.
Yordan Boev

0

Eli Courtwright의 두 번째 해결책은 잘못입니다.

Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, -days);
date.setTime(c.getTime().getTime());

2
Eli 솔루션의 함수 이름은 addDays; 그의 해결책은 맞습니다. 날짜에서 일을 빼려면에 대해 음수 값을 전달합니다 days.
Thomas Upton

글쎄, 그것은 함수를 만들 때 프로그래머가 지정 해야하는 것입니다. : P
user178973
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.