GregorianCalendar 클래스에서 이상한 동작을 겪었고 실제로 내가 나쁜 일을하고 있는지 궁금했습니다.
초기화 날짜의 월에 달력을 설정하려는 달보다 실제 최대 값이 더 큰 경우에만 추가됩니다.
예제 코드는 다음과 같습니다.
// today is 2010/05/31
GregorianCalendar cal = new GregorianCalendar();
cal.set(Calendar.YEAR, 2010);
cal.set(Calendar.MONTH, 1); // FEBRUARY
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
cal.set(Calendar.HOUR_OF_DAY, cal.getActualMaximum(Calendar.HOUR_OF_DAY));
cal.set(Calendar.MINUTE, cal.getActualMaximum(Calendar.MINUTE));
cal.set(Calendar.SECOND, cal.getActualMaximum(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, cal.getActualMaximum(Calendar.MILLISECOND));
return cal.getTime(); // => 2010/03/03, wtf
캘린더 초기화 날짜가 31 일 (월)이고 2 월 (28 일)로 설정된 월이 엉망이어서 문제가 발생한다는 것을 알고 있습니다. 수정은 쉽지만 (년과 월을 설정하기 전에 day_of_month를 1로 설정), 이것이 실제로 원하는 행동인지 궁금합니다. 어떤 생각?
- 답변 # 1
- 답변 # 2
예, 이것이 작동하는 방식입니다. 당신이
GregorianCalendar
에서 시작하는 경우 정확한 날짜를 가지고 있고 일관성이 없어서 수정하면 얻은 결과를 신뢰할 수 없습니다.getActualMaximum(..)
에 관한 문서에 따르면 상태는 다음과 같습니다. 와이즈 비즈그래서 작동해야하지만 일관된 값으로 공급해야합니다.2010 년 2 월 31 일이 정확하지 않으며 날짜 값에 의존하는 항목 (예 :
For example, if the date of this instance is February 1, 2004, the actual maximum value of the DAY_OF_MONTH field is 29 because 2004 is a leap year, and if the date of this instance is February 1, 2005, it's 28.
그러므로 모든 사람이 항상 JodaTime을 사용한다고 말하면 .. :)
- 답변 # 3
원하는 행동이 아니라고 확신합니다. 나는 그들이 수업을 할 때 그 유스 케이스를 실제로 생각한 사람이 아무도 없다고 확신합니다. 중요한 것은 캘린더는 내부 상태에 매우 큰 문제가 있으며 모든 설정된 방법에서 모든 잠재적 전환을 관리하는 방법입니다.
프로젝트에서 JodaTime 또는 JSR-310을 사용할 수없는 경우 Calendar 클래스를 사용할 때 단위 테스트를 많이 수행하십시오. 이 경우 캘린더 코드는 코드를 실행하는 달의 요일 또는 시간에 따라 다르게 작동합니다.
- 답변 # 4
아마도
getActualMaximum
당신을 위해 그것을 정렬합니다. 아래 코드를 실행할 때 예외가 발생합니다.그렇지 않으면 Joda가 더 나은 답변입니다.
setLenient(boolean lenient)
- 답변 # 5
현대적인 답변에 기여하고 싶습니다.
import java.util.Calendar; public class CalTest { public static void main(String[] args) { // today is 2010/05/31 Calendar cal = Calendar.getInstance(); cal.setLenient(false); cal.set(Calendar.YEAR, 2010); cal.set(Calendar.MONTH, 1); // FEBRUARY cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); cal.set(Calendar.HOUR_OF_DAY, cal.getActualMaximum(Calendar.HOUR_OF_DAY)); cal.set(Calendar.MINUTE, cal.getActualMaximum(Calendar.MINUTE)); cal.set(Calendar.SECOND, cal.getActualMaximum(Calendar.SECOND)); cal.set(Calendar.MILLISECOND, cal.getActualMaximum(Calendar.MILLISECOND)); System.out.println(cal.getTime()); } }
내 시간대로 실행하면 다음과 같이 인쇄됩니다.
와이즈 비즈실행 한 연도 및 월에 상관없이 인쇄물이 동일합니다. 시간대에 대한 종속성은 유감 스럽지만
ZonedDateTime endOfFebruary2010 = LocalDate.of(2010, Month.MARCH, 1) .atStartOfDay(ZoneId.systemDefault()) .minusNanos(1); System.out.println(endOfFebruary2010);
와 같이 원하는 시간대를 지정하여 언급 할 수 있습니다. .2010-02-28T23:59:59.999999999+01:00[Europe/Copenhagen]
필수적으로 구식
ZoneId.of("Asia/Oral")
가 필요한 경우 객체 (이 경우에만)를 변환하십시오 :
와이즈 비즈java.time
몇 달 동안 며칠 만 필요한 경우 (이는 중복 질문으로 요청 됨) :
와이즈 비즈java.util.Date
알다시피, 당신의 진짜 질문은 :
와이즈 비즈아무것도없는
Date oldFashionedDate = Date.from(endOfFebruary2010.toInstant()); System.out.println(oldFashionedDate);
는 그것이 원하는 행동이라고 강력하게 믿는다 생성자는 현재 날짜와 현재 시간을 반환합니다. 그리고 그Sun Feb 28 23:59:59 CET 2010
이것이 열악한 디자인이라고 생각한다면, 우리는 많은 사람들과 동의합니다. 이것이 또한
YearMonth ym = YearMonth.of(2011, Month.FEBRUARY); int numDays = ym.lengthOfMonth(); System.out.println(numDays);
를 대체하는 이유였습니다. 그리고28
…I was wondering is this really was the wanted behaviour. Any thoughts ?
GregorianCalendar
를 사용할 필요가 없습니다 다시. 예약 : 우리 도구는 여전히 Java 1.7에 의존합니다Calender.set()
Java 7에서 잘 작동합니다. 적어도6만 있으면됩니다.Java 8 이상 및 최신 Android 기기 (API 레벨 26부터)에 최신 API가 내장되어 있습니다.
Java 6 및 7에서는 새 클래스의 백 포트 인 ThreeTen Backport를 가져옵니다 (ThreeTen for JSR 310;하단의 링크 참조).
On (이전) Android는 Android 버전의 ThreeTen Backport를 사용합니다. 이름이 ThreeTenABP입니다.
링크Calendar
에서 날짜 및 시간 클래스를 가져와야합니다. 하위 패키지 포함Oracle tutorial :
GregorianCalendar
사용법을 설명하는 Date Time .JSR (Java Specification Request) 310, 여기서
java.time
처음 설명되었습니다.Wyzwyz의 백 포트 인 ThreeTen Backport 프로젝트 Java 6 및 7로 (JSR-310 용 ThreeTen)
ThreeTenABP, ThreeTen Backport의 Android 버전
질문 : Android 프로젝트에서 ThreeTenABP를 사용하는 방법에 대한 자세한 설명과 함께
Calendar
관련 자료
- python - hidden_layer_sizes를 사용한 GridSearchCV의 이상한 동작
- web scraping - 파이썬&bs4 - 이상한 행동, 스크레이퍼가 멈추지 않고 잠시 후 작동 중지
- javascript - + 연산자의 이상한 동작은 어디에서 발생합니까?
- r - 목록에서 이름의 이상한 동작
- 각도 애니메이션 상태 이상한 동작
- c - 매핑 된 파일에 파이썬 쓰기 - 이상한 행동
- 컨텐츠 지원을위한 Spring Tool Suite 이상한 동작
- database - $or 및 $text의 MongoDB 집계 이상한 동작
- ios - 핀치 제스처를 사용하여 텍스트 필드를 축소 한 후 텍스트 필드에 입력 할 때 이상한 동작이 있습니까?
- c++ - 인덱싱을 사용하여 벡터 요소가 설정된 경우 이상한 동작
- python - 목록에서 숫자를 교환 한 다음 목록 이해를 사용할 때 이상한 동작
- ios - searchController를 사용하여 tableView의 이상한 스크롤 동작
- Go로 XML 파일을 구문 분석하면 이상한 동작이 있습니다
- mysql - 이상한 행동 - 동일한 sql에 대해 phpmyadmin 및 vs 2017의 다른 결과
- oracle - PB의 이상한 행동
- generics - C # EF Core QueryableExtensionsFirstOrDefaultAsync 이상한 동작
- sorting - mongodb - 페이지 매김으로 복제가 발생하는 이상한 동작
- php - jquery는 행동 양식에서 이상한 행동을 대체합니다
- c# - 연결 문자열 EF 코드 첫 번째 이상한 동작
- OpenCv의 폴더에서 여러 이미지 읽기 (python)
- 파이썬 셀레늄 모든 "href"속성 가져 오기
- html - 자바 스크립트 - 클릭 후 변경 버튼 텍스트 변경
- javascript - 현재 URL에서 특정 div 만 새로 고침/새로 고침
- JSP에 대한 클래스를 컴파일 할 수 없습니다
- JavaScript 변수를 HTML div에 '출력'하는 방법
- git commit - 자식 - 로컬 커밋 된 파일에 대한 변경을 취소하는 방법
- jquery - JavaScript로 현재 세션 값을 얻으시겠습니까?
- javascript - swiperjs에서 정지, 재생 버튼 추가
- python - 화면에서 찾은 요소를 찾을 수없는 경우 셀레늄
현재 날짜/시간의 실제 최대 값을 가져옵니다. 5 월 31 일은 2 월 28 일보다 3 일이 더 많으므로 3 월 3 일로 이동합니다.
Calendar#clear()
에 전화해야합니다 그것을 얻거나 만든 후에 :결과 :
(내 시간대에 따라 맞음)
답 중 하나에서 말했듯이,
java.util.Calendar
그리고Date
서사시 실패입니다. 집중적 인 날짜/시간 작업을 수행 할 때는 JodaTime을 고려하십시오.