2014 년 Java 8이 출시 된 이래로, 우리의 고대 Java.util.date는 더 이상 Java의 운영 날짜와 시간을위한 유일한 선택이 아닙니다.
실제로, Java의 관련 날짜와 시간의 API는 항상 세계에 의해 비판을 받았습니다. 디자인 부서가 불분명하기 때문일뿐만 아니라 종종 날짜와 시간을 모두 처리 할 수 있으며, 이는 매우 혼란 스럽습니다. 또한 특정 연도, 개월 및 날짜는 다음과 같이 인간에 대한 저장됩니다.
종종 특정 연도 및 월 가치를 얻을 때 정확한 연도, 월 및 날짜 정보를 얻기 위해 해당 작업을 수행해야합니다. Java 8까지, 우리는 제 3 자 오픈 소스 라이브러리 Joda Time의 훌륭한 디자인을 빌려 날짜와 시간 API를 재 설계했습니다. 이전과 비교할 때 사용하기가 100 배 더 쉽다고 말할 수 있습니다. 모든 관련 API 인터페이스는 패키지 java.time에 있습니다.
고대 날짜 및 시간 인터페이스
시간 정보를 나타내는 날짜
세계의 모든 컴퓨터는 길이의 긴 정수를 사용 하며이 정수의 가치는 영국의 GMT에 비해 밀리 초의 수입니다 (1970 년 1 월 1 일 0 : 0 : 00). 예를 들어:
public static void main (String [] args) {// 1970 년 1 월 1 일 00:00:00 GMT. 날짜 = 새 날짜 (1000); System.out.println (날짜);}출력 결과 :
// 1970-1-1 8 : 00 : 01thu 1 월 01 01 08:00:01 CST 1970
많은 사람들이 표준 시간 1 초 전에 1000을 의미하는 이유는 왜 시간이 8 시간 더 지나가는가?
이것은 "시간대"와 관련이 있습니다. 그리니치에 위치한 경우 결과는 예상대로 진행되지만 우리는 중국의 8 학군에 위치하고 있으며 시간은 8 시간 일찍이므로 다른 시간 구역을 기반으로 한 기본 값은 다릅니다.
날짜 클래스는 이전에 많은 역할을 수행했습니다. 소스 코드에서 시간을 작동시킬 수있는 메소드, 연도, 월 및 일을 수행 할 수있는 메소드, 심지어 시간대를 관리 할 수 있음을 알 수 있습니다. 날짜 및 시간 관련 작업만으로 충분하다고 말할 수 있습니다.
그러나 이것은 세상입니다. 당신이 너무 많이 관심이 있다면, 당신은 자연스럽게 모든 것을 다룰 수 없을 것입니다. 현재 많은 방법의 설계는 그리 합리적이지 않습니다. 우리는 또한 이전에 그것을 말했고, 그것은 심지어 약간 반 인간입니다. 따라서 현재 날짜 클래스의 방법의 거의 80%가 버려졌으며 @deprecated로 표시됩니다.
현재 Sun Company의 현재 위치는 순간을 나타내는 것이므로 내부 위치는 해당 정수의 밀리 초 주변을 중심으로되며 더 이상 다양한 연간 달력 시간대 및 기타 정보에 초점을 맞추지 않아야합니다.
날짜는 두 가지 생성자를 통해 개체를 인스턴스화 할 수 있습니다.
비공개 과도 연속; 공개 날짜 () {this (System.CurrentTimeMillis ());} 공개 날짜 (긴 날짜) {fasttime = date;}여기서 빠른 속성 속성은 시간에 해당하는 밀리 초 수를 저장합니다. 두 생성자는 여전히 매우 간단합니다. 매개 변수가없는 생성자가 호출되면 가상 머신은 시스템의 현재 시간 값으로 FastTime을 할당합니다.
폐기되지 않은 몇 가지 다른 방법이 있습니다.
그 후 JDK1.8에 새로 추가되는 다른 두 가지 방법이 있으며, 새로운 인터페이스를 Java 8으로 변환하는 데 사용되며 나중에 도입됩니다.
Almanac을 설명하는 캘린더
캘린더는 연도, 월, 일 등과 같은 날짜 정보를 나타내는 데 사용됩니다. 추상 클래스이므로 인스턴스 객체는 일반적으로 다음 4 가지 공장 방법을 통해 얻습니다.
공개 정적 캘린더 getinstance () 공개 정적 캘린더 getinstance (Timezone Zone) 공개 정적 캘린더 getinstance (Locale Alocale) 공개 정적 캘린더 getinstance (Timezone Zone, Locale Alocale)
실제로 동일한 내부 방법이 결국 다음과 같습니다.
개인 정적 달력 CreateCalendar (Timezone Zone, Locale Alocale)
이 방법에는 두 가지 매개 변수가 필요합니다. 하나는 시간대이고 다른 하나는 국가와 언어입니다. 즉, 캘린더 인스턴스를 구축하려면 적어도이 두 매개 변수 정보가 필요합니다. 그렇지 않으면 시스템 기본 시간대 또는 언어 정보가 사용됩니다.
시간과 연도, 월 및 일일 정보가 다른 시간 영역과 국가 언어가 다르게 출력하기 때문에, 이는 캘린더 인스턴스가 시간대와 국가 정보를 전달 해야하는 이유이기도합니다. 예를 참조하십시오 :
public static void main (String [] args) {Calendar Calendar = calendar.getInstance (); System.out.println (calendar.gettime ()); Calendar Calendar1 = Calendar.getInstance (Timezone.getTimezone ( "gmt"), locale.english); System.out.println (Calendar1.get (calendar.year) + ":" + calendar1.get (calendar.hour) + ":" + calendar1.get (calendar.minute)); }출력 결과 :
4 월 21 일 10:32:20 CST 20182018 : 2 : 32
보시다시피, 첫 번째 출력은 시스템의 기본 시간대와 국가의 현재 시간이며, 두 번째 달력 인스턴스는 그리니치 시간대 (0 시간 구역)에 위치하고 있으며 결과는 8 시간 차이로 분명합니다. 왜냐하면 우리는 0 시간 영역보다 8 시간 일찍이되기 때문에 8 시간 차이가 있습니다.
어떤 사람들은 두 번째 달력 인스턴스의 출력이 첫 번째 달력 인스턴스처럼 직접 간결하게 호출하는 대신 두 번째 달력 인스턴스의 출력이 스플 라이스에 복잡한 이유를 궁금해 할 수 있습니까?
여기에는 일정의 내부 구현이 포함되며 함께 살펴 보겠습니다.
보호 된 장기; 공개 최종 날짜 gettime () {return new 날짜 (gettimeinmillis ());}날짜와 마찬가지로 캘린더는 내부에서 시간 정보를 유지하고 gettime 메소드는 실제로이 시간을 기준으로 날짜 객체를 작성하고 반환합니다.
일반적으로 캘린더 인스턴스를 작성하면 시간 정보를 전달하지 않으므로 인스턴스가 초기화되면 프로그램은 시스템의 기본 시간대와 현재 시간을 기준으로 밀리 초 숫자를 계산하여 시간에 할당합니다.
따라서 시간 속성 값이 수동으로 수정되지 않은 모든 캘린더 인스턴스 내부에서는 시간 값이 그 당시 기본 시간대의 시간 값입니다. 다시 말해, gettime의 출력 결과는 현재 인스턴스에 해당하는 시간대 정보를 무시합니다. 이는 캘린더 설계의 결함이기도합니다. 이로 인해 두 캘린더 인스턴스의 gettime 출력 값이 인스턴스가 초기화 될 때 시스템의 실행 시간에만 의존하기 때문입니다.
캘린더는 또한 많은 정적 상수와 일부 속성 배열을 정의합니다.
공개 최종 정적 int 시대 = 0; 공개 최종 정적 int 연도 = 1; 공개 최종 정적 int Month = 2; 공개 최종 정적 int week_of_year = 3; public final static int week_of_month = 4; 공개 최종 정적 int 날짜 = 5; .... 보호 된 int 필드 []; 보호 된 boolean isset []; ...
날짜에 대한 모든 관련 정보는 속성 배열에 저장되며 이러한 정적 상수의 값은 종종 인덱스 값을 나타냅니다. Get 메소드를 통해 속성 색인을 전달하고 속성의 값을 반환합니다. 예를 들어:
Calendar mycalendar = calendar.getinstance (); int 년 = mycalendar.get (calendar.year);
여기서 GET 메소드는 실제로 필드를 직접 반환 값으로 취하는 것입니다. 필드 속성 배열은 캘린더 인스턴스가 초기화 될 때 시간대와 언어에 따라 시스템별로 계산 및 할당됩니다. 항상 시스템 기본 시간대를 기반으로하는 시간과 달리 지정한 시간대에 따라 계산됩니다.
나는 개인적으로 캘린더의 디자인이 우아하고 불합리한 측면을 가지고 있다고 생각합니다. 결국, 그것은 "골동품"이며 결국 교체 될 것입니다.
DateFormat 형식 변환
이전 예제 중 하나에서 볼 수 있듯이 캘린더에 대한 예상 형식으로 날짜 정보를 출력하는 것은 매우 번거 롭고 수동으로 접합해야합니다. 우리의 dateformat은 형식화 된 문자열과 DateTimes 사이의 변환을 처리하는 데 사용됩니다.
달력과 마찬가지로 DateFormat도 추상 클래스입니다. 공장 방법을 통해 인스턴스 객체를 생성해야합니다. 주로 다음 공장 방법이 있습니다.
// 프로세스 시간 변환 공개 최종 정적 날짜 format getTimeInstance () // 프로세스 날짜 변환 공개 최종 정적 날짜 format getDateInstance () // 시간과 날짜 공개 최종 정적 날짜 format getDateTimeStance ()를 처리 할 수 있습니다.
물론, 그들은 각각 고유 한 과부하 방법을 가지고 있으며, 나중에 세부 사항을 볼 것입니다.
DateFormat, 형식 및 구문 분석 방법에는 두 가지 유형이 있습니다.
공개 최종 문자열 형식 (날짜) 공개 날짜 구문 분석 (문자열 소스)
형식 메소드는 날짜 개체를 문자열로 포맷하는 데 사용되며 구문 분석 방법은 형식의 문자열을 날짜 개체로 바꾸는 데 사용됩니다. 예를 들어:
public static void main (String [] args) {Calendar Calendar = calendar.getInstance (); dateformat dateformat = dateformat.getDateTimeStance (); system.out.println (dateformat.format (calendar.gettime ());}출력 결과 :
2018-4-21 16:58:09
분명히, 공장으로 구성된 DateFormat 인스턴스는 출력 형식 형식 컨텐츠를 사용자 정의 할 수 없습니다. 즉 출력 문자열 형식이 고정되어 있으며 경우에 따라 특별한 요구를 충족시킬 수 없습니다. 일반적으로 구현 클래스 중 하나 인 SimpledateFormat을 직접 사용합니다.
SimpleDateFormat을 사용하면 날짜 문자의 출력 형식을 사용자 정의하기 위해 인스턴스를 구성 할 때 패턴 매개 변수를 전달할 수 있습니다. 예를 들어:
public static void main (string [] args) {dateformat dateformat = new SimpledateFormat ( "yyyyy 년 mm month dd day"); system.out.println (dateformat.format (new date ());}출력 결과 :
2018 년 4 월 21 일
안에,
물론 문자열 날짜를 변환하는 것이 매우 편리합니다. 맞춤형 모드는 허용되지만 직접 설정 한 패턴을 준수해야합니다. 그렇지 않으면 프로그램이 성공적으로 구문 분석 할 수 없습니다. 예를 들어:
public static void main (String [] args) {String str = "2018 년 4 월 21 일 토요일"; dateformat sdateformat = new simpledateformat ( "yyyy 년 m 달 dd 일 hh point mm point e"); sdateformat.parse (str); System.out.println (sdateformat.getCalendar (). gettime ());}출력 결과 :
4 월 21 일 17:17:00 CST 2018
분명히, 프로그램은 문자열을 올바르게 구문 분석하고 DateFormat 내부에 저장된 캘린더 객체로 변환합니다.
일반적으로 날짜, 캘린더 및 DateFormat은 일반적인 시간 및 날짜 문제를 처리 할 수 있었지만 필연적으로 여전히 번거롭고 사용하기가 어렵습니다.
공간 제한으로 인해 다음 기사에서 Java 8의 새로운 날짜 및 시간 API를 비교하고 더 우아한 디자인과 간단한 작동이 있음을 알게됩니다.