tl; dr
LocalDate // Represents an entire day, without time-of-day and without time zone.
.now( // Capture the current date.
ZoneId.of( "Asia/Tokyo" ) // Returns a `ZoneId` object.
) // Returns a `LocalDate` object.
.atStartOfDay( // Determines the first moment of the day as seen on that date in that time zone. Not all days start at 00:00!
ZoneId.of( "Asia/Tokyo" )
) // Returns a `ZonedDateTime` object.
하루의 시작
시간대로 표시되는 오늘의 전체 길이를 가져옵니다.
시작이 포괄적 인 Half-Open 접근 방식 사용 이고 끝은 배타적 입니다. 이 접근 방식은 하루의 마지막 순간을 설명하지 못하는 코드의 결함을 해결합니다.
ZoneId zoneId = ZoneId.of( "Africa/Tunis" ) ;
LocalDate today = LocalDate.now( zoneId ) ;
ZonedDateTime zdtStart = today.atStartOfDay( zoneId ) ;
ZonedDateTime zdtStop = today.plusDays( 1 ).atStartOfDay( zoneId ) ;
zdtStart.toString () = 2020-01-30T00 : 00 + 01 : 00 [아프리카 / 튀니지]
zdtStop.toString () = 2020-01-31T00 : 00 + 01 : 00 [아프리카 / 튀니지]
UTC에서 동일한 순간을 확인하십시오.
Instant start = zdtStart.toInstant() ;
Instant stop = zdtStop.toInstant() ;
start.toString () = 2020-01-29T23 : 00 : 00Z
stop.toString () = 2020-01-30T23 : 00 : 00Z
시간대가 아닌 UTC로 표시되는 날짜의 전체 날짜를 원하면 OffsetDateTime
.
LocalDate today = LocalDate.now( ZoneOffset.UTC ) ;
OffsetDateTime odtStart = today.atTime( OffsetTime.MIN ) ;
OffsetDateTime odtStop = today.plusDays( 1 ).atTime( OffsetTime.MIN ) ;
odtStart.toString () = 2020-01-30T00 : 00 + 18 : 00
odtStop.toString () = 2020-01-31T00 : 00 + 18 : 00
이러한 OffsetDateTime
객체는 이미 UTC로되어 있지만 toInstant
정의상 항상 UTC로되어있는 객체가 필요한 경우 호출 할 수 있습니다 .
Instant start = odtStart.toInstant() ;
Instant stop = odtStop.toInstant() ;
start.toString () = 2020-01-29T06 : 00 : 00Z
stop.toString () = 2020-01-30T06 : 00 : 00Z
팁 : 프로젝트에 ThreeTen-Extra 라이브러리를 추가 하여 해당 Interval
클래스를 사용 하여이 Instant
개체 쌍을 나타내는 데 관심이있을 수 있습니다 . 같은 비교를 위해이 클래스 이벤트 유용한 방법 abuts
, overlaps
, contains
, 등.
Interval interval = Interval.of( start , stop ) ;
interval.toString () = 2020-01-29T06 : 00 : 00Z / 2020-01-30T06 : 00 : 00Z
반 개방
mprivat 의 대답 이 맞습니다. 그의 요점은 하루의 끝을 얻으려고하지 않고 오히려 "다음 날의 시작 전"과 비교하는 것입니다. 그의 아이디어는 "Half-Open"접근 방식으로 알려져 있습니다. 여기서 시간의 범위 는 포괄적 인 시작이 있고 결말은 배타적 입니다.
- Java의 현재 날짜-시간 프레임 워크 (java.util.Date/Calendar 및 Joda-Time )는 둘 다 시대의 . 그러나 Java 8에서 새로운 JSR 310 java.time. * 클래스는 나노초 해상도를 사용합니다. 새 클래스로 전환하면 하루의 마지막 순간의 밀리 초 수를 강제하여 작성한 코드가 올바르지 않습니다.
- 다른 해상도를 사용하면 다른 소스의 데이터를 비교하는 데 오류가 발생합니다. 예를 들어, Unix 라이브러리는 일반적으로 전체 초를 사용하고 Postgres 와 같은 데이터베이스 날짜-시간을 마이크로 초로 확인합니다.
- 일부 일광 절약 시간제 변경은 자정에 발생하여 상황을 더욱 혼란스럽게 할 수 있습니다.
Joda-Time 2.3은 하루의 첫 순간을 얻기 위해 바로이 목적을위한 방법을 제공합니다 withTimeAtStartOfDay()
. 마찬가지로 java.time에서 LocalDate::atStartOfDay
.
StackOverflow에서 "joda half-open"검색더 많은 토론과 예제를 보려면 을 검색하십시오.
이 게시물을 참조하십시오. 시간 간격 및 기타 범위는 반쯤 열려 있어야합니다.Bill Schneider .
레거시 날짜-시간 클래스 피하기
java.util.Date 및 .Calendar 클래스는 문제가있는 것으로 악명이 높습니다. 그들을 피하십시오.
java.time 클래스를 사용하십시오 . java.time의 프레임 워크는 매우 성공적인의 공식 후계자 Joda 타임 라이브러리입니다.
java.time
java.time 프레임 워크는 Java 8 이상에 빌드됩니다. ThreeTen-Backport 프로젝트 에서 Java 6 및 7로 백 포팅되고 ThreeTenABP 에서 Android에 추가로 적용됨 프로젝트.
가 Instant
있는 타임 라인에 순간 UTC 의 해상도를 가진 나노초 .
Instant instant = Instant.now();
일부 지역의 벽시계 시간 을 얻으려면 시간대를 적용하십시오 .
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
하루의 첫 순간을 얻으려면 LocalDate
수업과 그 atStartOfDay
방법을 살펴보십시오 .
ZonedDateTime zdtStart = zdt.toLocalDate().atStartOfDay( zoneId );
Half-Open 접근 방식을 사용하여 다음 날의 첫 순간을 얻습니다.
ZonedDateTime zdtTomorrowStart = zdtStart.plusDays( 1 );
현재 java.time 프레임 워크에는 Interval
Joda-Time에 대해 아래에 설명 된 클래스 가 없습니다 . 그러나 ThreeTen-Extra 프로젝트는 추가 클래스로 java.time을 확장합니다. 이 프로젝트는 java.time에 향후 추가 될 수있는 가능성을 입증하는 기반입니다. 클래스 중에는 Interval
. 를 구성 Interval
하는 한 쌍의 전달하여 Instant
개체. 객체 Instant
에서 를 추출 할 수 있습니다 ZonedDateTime
.
Interval today = Interval.of( zdtStart.toInstant() , zdtTomorrowStart.toInstant() );
java.time 정보
java.time의 프레임 워크는 나중에 자바 8에 내장되어 있습니다. 이 클래스는 까다로운 기존에 대신 기존 과 같은 날짜 - 시간의 수업을 java.util.Date
, Calendar
, SimpleDateFormat
.
자세한 내용은 Oracle Tutorial을 참조하십시오 . 그리고 많은 예제와 설명을 위해 Stack Overflow를 검색하십시오. 사양은 JSR 310입니다. 입니다.
Joda 타임 프로젝트는 지금에 유지 관리 모드 의로 마이그레이션을 조언 java.time의 클래스.
java.time 객체를 데이터베이스와 직접 교환 할 수 있습니다 . JDBC 4.2 이상을 준수 하는 JDBC 드라이버를 사용하십시오 . 문자열이나 클래스 가 필요하지 않습니다 . Hibernate 5 및 JPA 2.2는 java.time을 지원 합니다 .java.sql.*
java.time 클래스는 어디서 구할 수 있습니까?
Joda-Time
업데이트 : Joda-Time 프로젝트는 현재 유지 관리 모드에 있으며 java.time 클래스 로의 마이그레이션을 권장 합니다. 이 섹션은 역사를 위해 그대로 두겠습니다.
Joda 타임은 다양한 방법으로 시간의 범위를 나타내는 세 개의 클래스가 있습니다 Interval
, Period
하고 Duration
. An Interval
은 우주의 타임 라인에 특정한 시작과 끝이 있습니다. 이것은 "하루"를 표현해야하는 우리의 필요에 부합합니다.
withTimeAtStartOfDay
시간을 0으로 설정 하는 대신 메서드를 호출합니다 . 일광 절약 시간 및 기타 예외 사항으로 인해 하루 중 첫 순간이 아닐 수 있습니다 00:00:00
.
Joda-Time 2.3을 사용한 예제 코드.
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" );
DateTime now = DateTime.now( timeZone );
DateTime todayStart = now.withTimeAtStartOfDay();
DateTime tomorrowStart = now.plusDays( 1 ).withTimeAtStartOfDay();
Interval today = new Interval( todayStart, tomorrowStart );
필요한 경우 java.util.Date로 변환 할 수 있습니다.
java.util.Date date = todayStart.toDate();