[java] 오늘 자정과 내일 자정의 Java Date 객체를 만드는 방법은 무엇입니까?

내 코드에서 오늘 일어난 모든 일을 찾아야합니다. 따라서 오늘 00:00 am (오늘 아침 자정)부터 12:00 pm (오늘 자정)까지의 날짜와 비교해야합니다.

알아 …

Date today = new Date(); 

… 지금 당장. 그리고 …

Date beginning = new Date(0);

… 1970 년 1 월 1 일에 제로 타임을 얻습니다. 그러나 오늘 제로 시간과 제로 시간을 얻는 쉬운 방법은 무엇입니까?

최신 정보; 나는 이것을했지만 분명히 더 쉬운 방법이 있습니까?

Calendar calStart = new GregorianCalendar();
calStart.setTime(new Date());
calStart.set(Calendar.HOUR_OF_DAY, 0);
calStart.set(Calendar.MINUTE, 0);
calStart.set(Calendar.SECOND, 0);
calStart.set(Calendar.MILLISECOND, 0);
Date midnightYesterday = calStart.getTime();

Calendar calEnd = new GregorianCalendar();
calEnd.setTime(new Date());
calEnd.set(Calendar.DAY_OF_YEAR, calEnd.get(Calendar.DAY_OF_YEAR)+1);
calEnd.set(Calendar.HOUR_OF_DAY, 0);
calEnd.set(Calendar.MINUTE, 0);
calEnd.set(Calendar.SECOND, 0);
calEnd.set(Calendar.MILLISECOND, 0);
Date midnightTonight = calEnd.getTime();



답변

java.util.Calendar

// today    
Calendar date = new GregorianCalendar();
// reset hour, minutes, seconds and millis
date.set(Calendar.HOUR_OF_DAY, 0);
date.set(Calendar.MINUTE, 0);
date.set(Calendar.SECOND, 0);
date.set(Calendar.MILLISECOND, 0);

// next day
date.add(Calendar.DAY_OF_MONTH, 1);

JDK 8-java.time.LocalTime 및 java.time.LocalDate

LocalTime midnight = LocalTime.MIDNIGHT;
LocalDate today = LocalDate.now(ZoneId.of("Europe/Berlin"));
LocalDateTime todayMidnight = LocalDateTime.of(today, midnight);
LocalDateTime tomorrowMidnight = todayMidnight.plusDays(1);

조다 타임

JDK <8을 사용하는 경우 API가 정말 좋기 때문에 Joda Time을 권장합니다 .

DateTime date = new DateTime().toDateMidnight().toDateTime();
DateTime tomorrow = date.plusDays(1);

Joda Time 2.3 버전 DateMidnight더 이상 사용되지 않으므로 다음을 사용하십시오.

DateTime today = new DateTime().withTimeAtStartOfDay();
DateTime tomorrow = today.plusDays(1).withTimeAtStartOfDay();

JVM의 현재 기본 시간대를 원하지 않으면 시간대를 전달하십시오.

DateTimeZone timeZone = DateTimeZone.forID("America/Montreal");
DateTime today = new DateTime(timeZone).withTimeAtStartOfDay(); // Pass time zone to constructor.


답변

완전성을 위해 Java 8 을 사용하는 truncatedTo경우 Instant클래스 의 메소드를 사용하여 UTC 자정을 얻을 수도 있습니다 .

Instant.now().truncatedTo(ChronoUnit.DAYS);

Javadoc에 작성된

예를 들어, MINUTES 단위로 자르면 가장 가까운 분으로 반올림하여 초와 나노초를 0으로 설정합니다.

도움이 되길 바랍니다.


답변

자정을 찾는 가장 쉬운 방법 :

Long time = new Date().getTime();
Date date = new Date(time - time % (24 * 60 * 60 * 1000));

다음날:

Date date = new Date(date.getTime() + 24 * 60 * 60 * 1000);


답변

기억, Date표현하는 데 사용되지 않습니다 날짜를 (!). 날짜를 나타내려면 달력이 필요합니다. 이:

Calendar c = new GregorianCalendar();

Calendar현재 시간대의 현재 날짜를 나타내는 인스턴스 를 만듭니다 . 이제 필요한 것은로 설정하여 하루 (시, 분, 초 및 밀리 초) 아래의 모든 필드를 잘라내는 것 0입니다. 오늘 자정이되었습니다.

이제 다음 날 자정을 얻으려면 하루를 추가해야합니다.

c.add(Calendar.DAY_OF_MONTH, 1);

86400그 동안 발생할 수있는 여름 시간으로 인해 초 또는 24 시간 을 추가하는 것은 올바르지 않습니다.

업데이트 : 그러나이 문제를 처리하는 가장 좋아하는 방법 은 Commons Lang의 DateUtils 클래스 를 사용하는 것입니다 .

Date start = DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH))
Date end = DateUtils.addDays(start, 1);

그것은 Calendar무대 뒤에서 사용 합니다 …


답변

이 방법들이 도움이 될 것입니다.

public static Date getStartOfDay(Date date) {
     Calendar calendar = Calendar.getInstance();
     calendar.setTime(date);
     calendar.set(Calendar.HOUR_OF_DAY, 0);
     calendar.set(Calendar.MINUTE, 0);
     calendar.set(Calendar.SECOND, 0);
     calendar.set(Calendar.MILLISECOND, 0);
     return calendar.getTime();
 }

public static Date getEndOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.HOUR_OF_DAY, 23);
    calendar.set(Calendar.MINUTE, 59);
    calendar.set(Calendar.SECOND, 59);
    calendar.set(Calendar.MILLISECOND, 999);
    return calendar.getTime();
}


답변

JodaTime 2.3부터는 toDateMidnight()더 이상 사용되지 않습니다.

에서 2.2에서 2.3로 업그레이드

    2.2 이후의 지원 중단
    ----------------------
    -DateMidnight [# 41]
     이 수업은 개념에 결함이 있습니다
     일부 시간대에서는 자정 시간이 가끔 발생하지 않습니다.
     이는 일광 절약 시간 제로 00:00부터 01:00까지입니다.
     DateMidnight는 기본적으로 자정에 시간이 고정 된 DateTime입니다.
     LocalDate를 고려할 때 이러한 개념은 일반적으로 사용하기에 좋지 않은 개념입니다.
     DateMidnight를 LocalDate로 교체
     또는 withTimeAtStartOfDay () 메소드를 사용하여 DateTime으로 바꾸십시오.

다음은 toDateMidnight()메소드 가없는 샘플 코드 입니다.

암호

DateTime todayAtMidnight = new DateTime().withTimeAtStartOfDay();
System.out.println(todayAtMidnight.toString("yyyy-MM-dd HH:mm:ss"));

출력 ( 현지 시간대에 따라 다를 수 있음 )

2013-09-28 00:00:00


답변

다른 답변, 특히 arganzhengjava.time 답변이 정확 합니다. 일부 언급했듯이, 오래된 java.util.Date/.Calendar 클래스는 잘못 설계되고 혼란스럽고 번거로우므로 피해야합니다. 그것들은 java.time 클래스에 의해 대체되었습니다.

자정시간 범위를 다루는 전략에 대한 메모를 추가하겠습니다 .

반 오픈

날짜-시간 작업에서 시간 범위는 종종 “하프-오픈”접근 방식을 사용하여 정의됩니다. 이 접근법에서 시작은 포괄적 인 반면 결말은 독점적 입니다. 이렇게하면 문제가 해결되고 일관되게 사용하면 날짜-시간 처리에 대한 추론이 훨씬 쉬워집니다.

해결 된 한 가지 문제는 하루의 끝을 정의하는 것입니다. 오늘의 마지막 순간 23:59:59.999( 밀리 초 )입니까? 아마도 java.util.Date 클래스 (최초의 Java에서; 번거 로움 –이 클래스를 피하십시오!)에서 그리고 매우 성공적인 Joda-Time 라이브러리에서. 그러나 Postgres와 같은 데이터베이스와 같은 다른 소프트웨어에서 마지막 순간은 23:59:59.999999( 마이크로 초 )입니다. 그러나 java.time 프레임 워크 (Java 8 이상에 내장되어 Joda-Time의 후속 제품)와 같은 다른 소프트웨어와 H2 Database 와 같은 일부 데이터베이스 에서는 마지막 순간이 23:59.59.999999999( 나노초 ) 일 수 있습니다 . 머리카락을 나누는 대신 마지막 순간이 아니라 첫 순간 만 생각하십시오.

Half-Open에서 하루는 하루 의 첫 순간부터 시작하여 다음 날의 첫 순간 까지는 포함되지 않습니다 . 따라서 다음과 같이 생각하십시오.

… 오늘 00:00 am (오늘 아침 자정)부터 12:00 pm (오늘 자정)까지.

… 이런 생각…

오늘의 첫 순간부터 내일의 첫 순간까지는 포함하지 않음 :
(> = 00:00:00.0today AND < 00:00:00.0tomorrow)

데이터베이스 작업에서이 방법은 SQL 에서 연산자 를 사용 하지 않음 을 의미 합니다.BETWEEN

하루의 시작

또한 하루 중 첫 순간이 항상 시간 이 아닙니다00:00:00.0 . 일부 시간대의 일광 절약 시간 (DST) 및 기타 이상 현상은 하루가 시작되는 다른 시간을 의미 할 수 있습니다.

따라서 java.time 클래스를 호출하여 하루의 시작을 결정하는 작업을 수행하십시오 LocalDate::atStartOfDay( ZoneId ). 우리는을 통해 우회 할 수 있도록 LocalDate하고 다시 ZonedDateTime이 예제 코드에서 볼 수 있습니다.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime todayStart = now.toLocalDate().atStartOfDay( zoneId );
ZonedDateTime tomorrowStart = todayStart.plusDays( 1 );

옵션의 전달에 유의하십시오 ZoneId. 생략하면 JVM의 현재 기본 시간대가 내재적으로 적용됩니다. 명시 적으로하는 것이 좋습니다.

시간대는 날짜-시간 작업에 중요합니다. 질문과 다른 답변은 시간대를 의식적으로 처리하지 않기 때문에 잠재적으로 결함이 있습니다.

변하게 하다

당신이 경우 해야한다 java.util.Date가 나 .Calendar를 사용, 그 오래된 클래스에 추가 된 새로운 변환 방법을 찾습니다.

java.util.Date utilDate = java.util.Date.from( todayStart.toInstant() );
java.util.GregorianCalendar gregCal = java.util.GregorianCalendar.from( todayStart );

시간의 경간

그건 그렇고, 오랜 시간 동안 많은 일을하고 있다면 다음을 살펴보십시오.

  • Duration
  • Period
  • Interval
    Interval클래스는 java.time 프레임 워크의 확장 인 ThreeTen-Extra 프로젝트에 있습니다. 이 프로젝트는 향후 java.time에 추가 될 수있는 입증 된 근거입니다.
    Interval todayMontreal = Interval.of( todayStart.toInstant() , tomorrowStart.toInstant() );

java.time에 대하여

java.time의 프레임 워크는 나중에 자바 8에 내장되어 있습니다. 이 클래스는 까다로운 기존에 대신 기존 과 같은 날짜 – 시간의 수업을 java.util.Date, Calendar, SimpleDateFormat.

Joda 타임 프로젝트는 지금에 유지 관리 모드 의로 마이그레이션을 조언 java.time의 클래스.

자세한 내용은 Oracle Tutorial을 참조하십시오 . 많은 예제와 설명을 보려면 스택 오버플로를 검색하십시오. 사양은 JSR 310 입니다.

java.time 객체를 데이터베이스와 직접 교환 할 수 있습니다 . JDBC 4.2 이상을 준수 하는 JDBC 드라이버를 사용하십시오 . 문자열이 필요없고 수업이 필요 없습니다 .java.sql.*

java.time 클래스는 어디서 구할 수 있습니까?

ThreeTen – 추가 프로젝트 추가 클래스와 java.time를 확장합니다. 이 프로젝트는 향후 java.time에 추가 될 수있는 입증 된 근거입니다. 당신은 여기에 몇 가지 유용한 클래스와 같은 찾을 수 있습니다 Interval, YearWeek, YearQuarter, 그리고 .