자바 8 새로운 기능 의 스 레 드 보안 날짜 클래스
자바 8 의 새로운 기능 중 하나 로 날짜 클래스 가 추 가 됩 니 다.
프로젝트 개발 과정 에서 시간 처 리 를 자주 하 는데 정말 잘 사용 하 셨 나 요?알 리 바 바 개발 매 뉴 얼 에서 static 수식 Simple DateFormat 을 사용 하지 않 는 것 을 이해 하 십 니까?
이 글 을 읽 으 면 다음 과 같은 것 을 알 게 될 것 이다.
Date 대신 Instant,Calendar 대신 LocalDateTime,SimpleDateFormatter 대신 DateFormatter 를 사용 할 수 있 습 니 다.
SimpleDateFormat 스 레 드 가 안전 하지 않 습 니 다.
Date 를 포맷 하지 않 으 면 인쇄 된 날짜 의 가 독성 이 떨 어 집 니 다.
Tue Sep 10 09:34:04 CST 2019
Simple DateFormat 을 사용 하여 시간 을 포맷 하지만 Simple DateFormat 은 스 레 드 가 안전 하지 않 은 Simple DateFormat 의 format 방법 으로 원본 코드 를 최종 호출 합 니 다.
private StringBuffer format(Date date, StringBuffer toAppendTo,
FieldDelegate delegate) {
// Convert input date to time field list
calendar.setTime(date);
boolean useDateFormatSymbols = useDateFormatSymbols();
for (int i = 0; i < compiledPattern.length; ) {
int tag = compiledPattern[i] >>> 8;
int count = compiledPattern[i++] & 0xff;
if (count == 255) {
count = compiledPattern[i++] << 16;
count |= compiledPattern[i++];
}
switch (tag) {
case TAG_QUOTE_ASCII_CHAR:
toAppendTo.append((char)count);
break;
case TAG_QUOTE_CHARS:
toAppendTo.append(compiledPattern, i, count);
i += count;
break;
default:
subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols);
break;
}
}
return toAppendTo;
}
주의calendar.setTime(date);
,Calendar 류 는 기본적으로 final 로 장식 되 어 있 으 며,calendar 는 공유 변수 이 며,이 공유 변 수 는 라인 보안 제 어 를 하지 않 았 습 니 다.여러 스 레 드 가 같은 Simple DateFormat 대상 을 동시에 사용 할 때[예 를 들 어 static 로 장 식 된 Simple DateFormat 은 보통 도구 류 에 패키지 되 어 재 활용]format 방법 을 호출 할 때 여러 스 레 드 가 calendar.setTime 방법 을 동시에 호출 합 니 다.한 스 레 드 가 time 값 을 설정 한 지 다른 스 레 드 가 설정 한 time 값 을 바로 수정 하여 되 돌아 오 는 포맷 시간 이 잘못 되 었 을 수 있 습 니 다.다 중 동시 다발 상황 에서 Simple DateFormat 을 사용 하려 면 특히 주의해 야 합 니 다.
Simple DateFormat 은 format 방법 이 스 레 드 가 안전 하지 않 은 것 을 제외 하고 parse 방법 도 스 레 드 가 안전 하지 않 습 니 다.parse 방법 은 실제 적 으로 alb.estable(calendar).getTime()방법 을 호출 하여 분 석 했 습 니 다.alb.estable(calendar)방법 은 주로 완성 되 었 습 니 다.
SimpleDateFormat 스 레 드 안전 을 어떻게 보장 합 니까?
자바 8 새로운 날짜 와 시간 API
자바 프로그램 을 사용 하여 데이터 베 이 스 를 조작 할 때,우 리 는 데이터베이스 형식 과 자바 형식 을 매 핑 해 야 한다.다음 표 는 데이터베이스 형식 과 자바 신 구 API 의 매 핑 관계 입 니 다.
데이터베이스
대응 하 는 자바 클래스(구)
대응 하 는 자바 클래스(신규)
DATETIME
java.util.Date
LocalDateTime
DATE
java.sql.Date
LocalDate
TIME
java.sql.Time
LocalTime
TIMESTAMP
java.sql.Timestamp
LocalDateTime
LocalDate
년 월 일 만 얻 을 수 있 습 니 다.
//
LocalDate localDate = LocalDate.now();
//
LocalDate localDate1 = LocalDate.of(2019, 9, 10);
// 、 、 、
int year = localDate.getYear();
int year1 = localDate.get(ChronoField.YEAR);
Month month = localDate.getMonth();
int month1 = localDate.get(ChronoField.MONTH_OF_YEAR);
int day = localDate.getDayOfMonth();
int day1 = localDate.get(ChronoField.DAY_OF_MONTH);
DayOfWeek dayOfWeek = localDate.getDayOfWeek();
int dayOfWeek1 = localDate.get(ChronoField.DAY_OF_WEEK);
LocalTime몇 시 몇 분 몇 초 밖 에 못 받 아 요.
// LocalTime
LocalTime localTime = LocalTime.of(13, 51, 10);
LocalTime localTime1 = LocalTime.now();
//
int hour = localTime.getHour();
int hour1 = localTime.get(ChronoField.HOUR_OF_DAY);
//
int minute = localTime.getMinute();
int minute1 = localTime.get(ChronoField.MINUTE_OF_HOUR);
//
int second = localTime.getSecond();
int second1 = localTime.get(ChronoField.SECOND_OF_MINUTE);
LocalDateTime년 월 일 분 초 를 가 져 오 는 것 은 LocalDate+LocalTime 과 같 습 니 다.
//
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime localDateTime1 = LocalDateTime.of(2019, Month.SEPTEMBER, 10, 14, 46, 56);
//LocalDate+LocalTime-->LocalDateTime
LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime);
LocalDateTime localDateTime3 = localDate.atTime(localTime);
LocalDateTime localDateTime4 = localTime.atDate(localDate);
// LocalDate
LocalDate localDate2 = localDateTime.toLocalDate();
// LocalTime
LocalTime localTime2 = localDateTime.toLocalTime();
ZonedDateTimeLocalDateTime
항상 현지 날짜 와 시간 을 표시 하고 시간 대 를 가 진 날짜 와 시간 을 표시 하려 면 우 리 는ZonedDateTime
이 필요 하 다.간단하게
ZonedDateTime
를LocalDateTime
더하기ZoneId
로 이해 할 수 있다.ZoneId
는java.time
도 입 된 새로운 시간 대 유형 으로 주의 와 낡은java.util.TimeZone
의 차이 점 이다.대상 만 들 기
ZonedDateTime
//
ZonedDateTime zbj = ZonedDateTime.now();
//
ZonedDateTime zny = ZonedDateTime.now(ZoneId.of("America/New_York"));
결과:2019-09-15T20:58:18.786182+08:00[Asia/Shanghai]
2019-09-15T08:58:18.788860-04:00[America/New_York]
다른 생 성 방식 은 하나
LocalDateTime
에 하나ZoneId
를 추가 하면ZonedDateTime
로 변 할 수 있 습 니 다.
LocalDateTime ldt = LocalDateTime.of(2019, 9, 15, 15, 16, 17);
ZonedDateTime zbj = ldt.atZone(ZoneId.systemDefault());
ZonedDateTime zny = ldt.atZone(ZoneId.of("America/New_York"));
시간 대 전환시간 대 를 바 꾸 려 면 먼저 하나의
ZonedDateTime
대상 이 필요 하 다.그 다음 에withZoneSameInstant()
을 통 해 관련 시간 대 를 다른 시간 대 로 바 꾸 고 전환 한 후에 날짜 와 시간 은 상응 하 게 조정 된다.
ZonedDateTime zbj = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
// :
ZonedDateTime zny = zbj.withZoneSameInstant(ZoneId.of("America/New_York"));
ZonedDateTime
여전히plusDays()
등 가감 조작 을 제공 했다.특히 시간 대가 바 뀔 때 여름 캠프 가 존재 하기 때문에 날짜 가 다 를 수 있 으 므 로 주의해 야 한다.이것 은 베 이 징 시간 9 월 15 일의 전환 결과 이다.
2019-09-15T21:05:50.187697+08:00[Asia/Shanghai]
2019-09-15T09:05:50.187697-04:00[America/New_York]
이것 은 베 이 징 시간 11 월 15 일의 전환 결과 이다.
2019-11-15T21:05:50.187697+08:00[Asia/Shanghai]
2019-11-15T08:05:50.187697-05:00[America/New_York]
두 차례 전 환 된 뉴욕 시간 은 1 시간의 여름 시차 가 있다.시간 대 에 관련 되 었 을 때 는 절대 스스로 시 차 를 계산 하지 마라.그렇지 않 으 면 여름 캠프 를 정확하게 처리 하기 어렵다.
ZonedDateTime
이 있 으 면 이 를 현지 시간 으로 바 꾸 는 것 이 매우 간단 하 다.
ZonedDateTime zdt = ...
LocalDateTime ldt = zdt.toLocalDateTime();
LocalDateTime
로 전환 할 때 시간 대 정 보 를 직접 버 렸 다.Instant
초 또는 시간 스탬프 가 져 오기
// Instant
Instant instant = Instant.now();
//
long currentSecond = instant.getEpochSecond();
//
long currentMilli = instant.toEpochMilli();
long l = System.currentTimeMillis();
System.currentTimeMillis()도 밀리초 수 를 얻 을 수 있 습 니 다.날짜 계산
LocalDate,LocalTime,LocalDateTime,Instant 는 가 변 대상 이 며,이 대상 을 수정 하면 복사 본 을 되 돌려 줍 니 다.
연수,월 수,일수 등 을 증 가·감소 하고,LocalDateTime 의 경우
// LocalDate、LocalTime、LocalDateTime、Instant
LocalDateTime localDateTime = LocalDateTime.of(2019, Month.SEPTEMBER, 10,
14, 46, 56);
//
localDateTime = localDateTime.plusYears(1);
localDateTime = localDateTime.plus(1, ChronoUnit.YEARS);
//
localDateTime = localDateTime.minusMonths(1);
localDateTime = localDateTime.minus(1, ChronoUnit.MONTHS);
// with
// 2020
localDateTime = localDateTime.withYear(2020);
// 2022
localDateTime = localDateTime.with(ChronoField.YEAR, 2022);
// 、
이 달의 마지막 날 이 며칠 인지,다음 주말 이 며칠 인지 궁금 할 때 가 있 는데 제 공 된 시간 과 날짜 API 를 통 해 빠르게 답 을 얻 을 수 있 습 니 다.
LocalDate localDate = LocalDate.now();
LocalDate localDate1 = localDate.with(TemporalAdjusters.firstDayOfYear());
예 를 들 어 firstDayOfYear()를 통 해 현재 년 의 첫날 날 짜 를 되 돌 렸 고 많은 방법 이 있 습 니 다.여기 서 예 를 들 어 설명 하지 않 습 니 다.포맷 시간
DateTimeFormatter 는 기본적으로 다양한 포맷 방식 을 제공 합 니 다.기본 값 으로 요 구 를 만족 시 키 지 못 하면 DateTimeFormatter 의 ofPattern 방법 으로 사용자 정의 포맷 방식 을 만 들 수 있 습 니 다.
LocalDate localDate = LocalDate.of(2019, 9, 10);
String s1 = localDate.format(DateTimeFormatter.BASIC_ISO_DATE);
String s2 = localDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
//
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String s3 = localDate.format(dateTimeFormatter);
해석 시간Simple DateFormat 에 비해 DateTimeFormatter 는 스 레 드 가 안전 합 니 다.
LocalDate localDate1 = LocalDate.parse("20190910", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate localDate2 = LocalDate.parse("2019-09-10", DateTimeFormatter.ISO_LOCAL_DATE);
SimpleDateFormat 대신 DateTimeFormatter오래된
Date
대상 을 사용 할 때,우 리 는SimpleDateFormat
으로 포맷 하여 표시 합 니 다.새로운LocalDateTime
또는ZonedLocalDateTime
을 사용 할 때 포맷 디 스 플레이 를 하려 면DateTimeFormatter
을 사용 해 야 합 니 다.SimpleDateFormat
와 달리DateTimeFormatter
변 하지 않 는 대상 일 뿐만 아니 라 스 레 드 가 안전 하 다.SimpleDateFormat
스 레 드 가 안전 하지 않 기 때문에 사용 할 때 방법 내부 에 새로운 부분 변 수 를 만 들 수 밖 에 없습니다.DateTimeFormatter
인 스 턴 스 만 만 들 고 여기저기 서 참조 할 수 있 습 니 다.
// 1:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 2:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E, yyyy-MMMM-dd HH:mm:ss", Locale.US);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E, yyyy-MMMM-dd HH:mm:ss", Locale.CHINA);
DateTimeFormatter 바 텀 원리DateTimeFormatter 스 레 드 가 안전 합 니까?왜?
원본 코드:
분명 한 것 은 final 수식 류 를 통 해 계승 할 수 없고 final 수식 변 수 는 가 변 류 를 만 들 었 습 니 다.String 과 유사 하여 스 레 드 가 안전 할 뿐만 아니 라 효율 적 입 니 다.전역 적 으로 하나의 대상 만 있 고 여러 스 레 드 가 참조 할 수 있 습 니 다.
format 와 parse 스 레 드 보안 대체
LocalDateTime 의 format 와 parse 방법 을 사용 하여 대응 하 는 DateTimeFormatter 대상 인 자 를 입력 합 니 다.실제 적 으로 DateTimeFormatter 의 format 와 parse 방법 을 호출 하여 날짜 포맷 과 해석 을 실현 하 는 것 이 안전 합 니 다.
DateTimeFormatter 클래스 는 LocalDateTime 의 날짜 변 수 를 해석 하여 StringBuilder 로 되 돌려 줍 니 다.LocalDateTime 등 새로 나 온 날짜 클래스 는 모두 final 수식 클래스 로 계승 할 수 없 으 며,대응 하 는 날짜 변 수 는 모두 final 수식 클래스,즉 가 변 클래스 입 니 다.값 을 한 번 부여 한 후 에는 가 변 적 이지 않 고 다 중 스 레 드 데이터 문제 가 존재 하지 않 습 니 다.
자바 8 의 새로운 특성 에 관 한 스 레 드 보안 날짜 류 에 관 한 글 은 여기까지 소개 되 었 습 니 다.자바 8 스 레 드 보안 날짜 류 에 관 한 내용 은 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 저 희 를 많이 사랑 해 주세요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.