JAVA Calendar 클래스의 areFieldsSet 등의 행위

7105 단어 calendarJava
이 글은 내가 자바의 경험치가 낮은 학습 과정에서 신경 쓴 일들을 필기한 것이다.
자바 사람들한테는 상식일 것 같은데 캘린더급areFieldsSet 속성을 언급한 단락을 잘 못 봐서 썼어요.

계기.


날짜 검사의 논리를 만들기 위해 다음과 같은 테스트 클래스를 만들었습니다.
testCode1
    public static void calendarCompare() {
        Calendar calChange = Calendar.getInstance();//カレンダー1
        calChange.set(2015, 3, 25);//日付を変更
        Calendar calNow = Calendar.getInstance();//カレンダー2 現在日時のカレンダー
        if(calNow.compareTo(calChange) > 0){//判定式
            throw new IllegalArgumentException("未来日付は指定できません。");
        }
    }
이 판정식에서 엉뚱한 행동(또는'<'의 방향만 틀렸다)이었기 때문에 set 방법이 달력 1에 정확하게 반영되었는지 의심하여 디버거로 조사를 시작했다.이때 다양한 행동을 알았기 때문에 미리 기록해 둔다.

디버거로 Calendar 동작 보기


달력의 실례를 캡처합니다.


set 방법이 실행된 후의 캡처입니다.
-fields의 값은 바뀌었지만time의 값은 업데이트되지 않았습니다.
- areFieldsSet이라는 속성이 가짜로 변하는 것에 신경을 많이 썼어요.


참고 자료를 찾아보았다


Calendar 클래스의 관련 속성 및 메서드를 참조하여 조사했습니다.
https://docs.oracle.com/javase/jp/7/api/java/util/Calendar.html#fields
4
  • fields ・ 이 캘린더에 현재 설정된 시간을 기준으로 하는 캘린더 필드 값입니다
  • 4
  • 시간... 현재 달력에 설정된 시간입니다
  • 4
  • isTimeset・time의 값은 유효할 때 진짜입니다.field[]의 항목을 수정하면 time가 잘못됩니다

  • areFieldsSet·fields가 현재 설정된 시간과 동기화되어 있으면 진짜입니다.
    (상세 정보)field[]가 현재 설정된 시간과 동기화될 때 진짜입니다.가짜의 경우, 다음에 필드 값을 얻으려고 시도할 때, 시간 값에서 모든 필드를 다시 계산합니다.
  • 동작에 대한 고찰


    Calendar 클래스가 처리하는 날짜와 시간의 실제 상황은 시간 속성이 가지고 있는 밀리초 단위의 시간입니다.이 값을 업데이트할 때, 달력 필드 = 필드의 값부터 계산합니다.
    잘 어울리지만 이런 느낌
    사용자<>fields<>time
    이 경우 사용자 > fileds는 즉시 반영되지만,fields > time는 즉시 반영되지 않고 getTime () 와 같은 요청이 읽히는 시간에 계산되어 반영됩니다.
    즉 타임과fields가 업데이트할 때 비동기적인 기간이 있을 때 이 상태를 나타내는 표지는areFieldsSet이다.
    자세히 보면 set 방법의 설명에도 이렇게 쓰여 있다.
    set(f,value)에서 달력 필드 f가value로 변경됩니다.또한 내부 구성원 변수가 설정되어 필드 f가 수정되었음을 표시합니다.달력 필드 f는 즉시 바뀌지만, 달력의 시간 값 (밀리초) 은 get (, getTime (), getTimeInMillis (,dd () 또는 roll () 을 호출하기 전에 다시 계산되지 않습니다.이렇게 하면 set () 를 여러 번 호출해도 불필요한 계산을 하지 않습니다.set () 를 사용하여 달력 필드를 변경할 때, 달력 필드, 달력 필드 값과 달력 시스템이 다른 필드를 변경할 수 있습니다.또한 get(f)에서 달력 필드를 다시 계산한 후 set 방법으로 설정한value가 반드시 되돌아오지 않습니다.이 세부 사항들은 구체적인 달력 종류에 의해 결정된다.
    set 방법은 날짜와 시간을 설정하기 위해 필드를 여러 번 호출할 가능성이 있기 때문에 get 방법을 호출할 때 다시 계산하는 것은 낭비하지 않겠죠.

    판정식 동작은요?


    궁금한 건 처음 시작하는 테스트코드 1반에서 사용하는 판정식(compoareTo)은 어떨까?그러니까
    comporaeTo는 밀리초 간의 비교이기 때문에 필드부터 타임을 재계산해야 하는데 Debuga에서 보면 areFieldsSet=진짜.
    어떻게 비교했어요?
    확실히 위의 set 방법의 참조도 comporaeTo가 재계산에 들어간 대상이 없다.
    신경 쓰여서,calendar.클라스 속을 들여다보았다.
    Calendar.class
        private int compareTo(long t) {
            long thisTime = getMillisOf(this);
            return (thisTime > t) ? 1 : (thisTime == t) ? 0 : -1;
        }
        private static long getMillisOf(Calendar calendar) {
            if (calendar.isTimeSet) {
                return calendar.time;
            }
            Calendar cal = (Calendar) calendar.clone();
            cal.setLenient(true);
            return cal.getTimeInMillis();
        }
    
    일부러 비교하려고 만든 크론인데 타임 값을 계산해서 버린 것 같아요.
    비교적 비파괴적이죠... 다른 예는 몰라서 결국 추측일 뿐이죠.근데 이 순환을 비교하면 무거울 것 같은데.

    끝맺다


    자바에 대한 날짜는 아직 파악하기 어렵다.
    나는 첫 번째 투고에 보기 싫은 점이 있을 것 같아서 참고할 만한 것이 있다면.

    좋은 웹페이지 즐겨찾기