시간을 00:00:00으로 설정


121

Java에서 시간을 재설정하는 데 문제가 있습니다. 주어진 날짜에 대해 시간을 00:00:00으로 설정하고 싶습니다.

이것은 내 코드입니다.

/**
     * Resets milliseconds, seconds, minutes and hours from the provided date
     *
     * @param date
     * @return
     */
    public static Date trim(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR, 0);

        return calendar.getTime();
    }

문제는 때로 시간이 12:00:00있고 때로는 그럴 때가 00:00:00있고 데이터베이스에서 저장된 07.02.2013 00:00:00엔터티와 저장된 실제 엔터티 시간을 12:00:00쿼리 할 때 쿼리가 실패 한다는 것입니다 .

알아 12:00:00 == 00:00:00!

AppEngine을 사용하고 있습니다. AppEngine 버그, 문제 또는 기타 문제입니까? 아니면 다른 것에 의존합니까?


다른 로케일과 관련이있을 수 있습니까? 아니면 항상 같은 PC에서 발생합니까?
LostBoy

appengine에 배포 할 때 발생합니다.
Adelin 2013

시간 단축을위한 다양한 솔루션 : stackoverflow.com/a/1908955/2646526
heenenee

참고로, 같은 귀찮은 된 날짜 - 시간 수업 java.util.Date, java.util.Calendar그리고 java.text.SimpleDateFormat지금 기존 에 의해 대체, java.time의 자바 8 자바 9 페이지에 내장 된 클래스 오라클 튜토리얼 .
Basil Bourque

1
calendar.set(Calendar.HOUR_OF_DAY, 0);내 목적을 위해을 사용 했는데 잘 작동합니다.
hariprasad 19

답변:


209

대신 다른 상수를 Calendar.HOUR사용하고 Calendar.HOUR_OF_DAY.

calendar.set(Calendar.HOUR_OF_DAY, 0);

Calendar.HOUR0-11 (AM / PM과 함께 사용)을 Calendar.HOUR_OF_DAY사용하고 0-23을 사용합니다.

Javadocs를 인용하려면 :

public static final int HOUR

오전 또는 오후 시간을 나타내는 get 및 set 필드 번호입니다. HOUR는 12 시간제 (0-11)에 사용됩니다. 정오와 자정은 12가 아닌 0으로 표시됩니다. 예를 들어 오후 10 : 04 : 15.250에 HOUR는 10입니다.

public static final int HOUR_OF_DAY

시간을 나타내는 get 및 set 필드 번호입니다. HOUR_OF_DAY는 24 시간 제로 사용됩니다. 예를 들어 오후 10 : 04 : 15.250에 HOUR_OF_DAY는 22입니다.

테스트 ( "현재"는 현재 태평양 일광 절약 시간 2013 년 7 월 23 일 14:55 경) :

public class Main
{
   static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static void main(String[] args)
    {
        Calendar now = Calendar.getInstance();
        now.set(Calendar.HOUR, 0);
        now.set(Calendar.MINUTE, 0);
        now.set(Calendar.SECOND, 0);
        System.out.println(sdf.format(now.getTime()));
        now.set(Calendar.HOUR_OF_DAY, 0);
        System.out.println(sdf.format(now.getTime()));
    }
}

산출:

$ javac Main.java
$ java Main
2013-07-23 12:00:00
2013-07-23 00:00:00

3
@JarrodRoberson 그러나을 사용 Calendar.HOUR하면 PM을 AM으로 설정하지 않고 12:00 정오로 둡니다.
rgettman 2013

시간, 분, 초로 LocalDate를 구성하는 데 도움을 줄 수 있습니까? 한 가지 옵션은 DateTime을 따르는 것입니다.
Woody

11
HOUR 및 HOUR_OF_DAY 필드를 만든 사람은 채찍질을 당하고 배급을 받아야합니다.
AndroidDev 2015 년

1
오전 / 오후를 발명 한 @AndroidDev도 마찬가지입니다 ... 이것은 비 메트릭 표준에도 적용됩니다.
Dediqated

1
참고로, 같은 귀찮은 된 날짜 - 시간 수업 java.util.Date, java.util.Calendar그리고 java.text.SimpleDateFormat지금 기존 에 의해 대체, java.time의 자바 8 자바 9 페이지에 내장 된 클래스 오라클 튜토리얼 .
Basil Bourque

29

java.time

java.timeJava 8 이상에 내장 된 프레임 워크를 사용합니다 . 튜토리얼을 참조하십시오 .

import java.time.LocalTime;
import java.time.LocalDateTime;

LocalDateTime now = LocalDateTime.now(); # 2015-11-19T19:42:19.224
# start of a day
now.with(LocalTime.MIN); # 2015-11-19T00:00
now.with(LocalTime.MIDNIGHT); # 2015-11-19T00:00

시간 (시, 분, 초 등)이 필요하지 않은 경우 LocalDate클래스 사용을 고려하십시오 .

LocalDate.now(); # 2015-11-19

이 질문이 처음 제기 된 이후 Java 1.8이 릴리스 되었기 때문에 이것은 새로운 응답이어야합니다.
Matt forsythe

LocalDateTime이것을 위해 사용하기에 정확히 잘못된 클래스 입니다. 시간대 또는 UTC로부터의 오프셋 개념이 없기 때문에 순간을 나타낼 수 없습니다. 전화는 LocalDateTime.now거의 의미가 없습니다. ZonedDateTime대신 사용하십시오 . 그렇지 않으면 중요한 시간대 문제를 무시하고 있습니다. 우선, 일부 구역의 일부 날짜 는 00:00에 시작 하지 않습니다 !
Basil Bourque

12

이 작업을 수행하는 데 사용하는 몇 가지 유틸리티 함수가 있습니다.

/**
 * sets all the time related fields to ZERO!
 *
 * @param date
 *
 * @return Date with hours, minutes, seconds and ms set to ZERO!
 */
public static Date zeroTime( final Date date )
{
    return DateTimeUtil.setTime( date, 0, 0, 0, 0 );
}

/**
 * Set the time of the given Date
 *
 * @param date
 * @param hourOfDay
 * @param minute
 * @param second
 * @param ms
 *
 * @return new instance of java.util.Date with the time set
 */
public static Date setTime( final Date date, final int hourOfDay, final int minute, final int second, final int ms )
{
    final GregorianCalendar gc = new GregorianCalendar();
    gc.setTime( date );
    gc.set( Calendar.HOUR_OF_DAY, hourOfDay );
    gc.set( Calendar.MINUTE, minute );
    gc.set( Calendar.SECOND, second );
    gc.set( Calendar.MILLISECOND, ms );
    return gc.getTime();
}

6

JAVA 8 방법 :

LocalDateTime localDateTime = LocalDateTime.now().truncatedTo(ChronoUnit.HOURS);

그러나 이미 존재하는 날짜를 편집하는 것이 훨씬 더 유용합니다.


1
LocalDateTime시간대 또는 UTC로부터의 오프셋 개념이 없기 때문에 순간을 나타낼 수 없습니다. 전화는 LocalDateTime.now거의 의미가 없습니다. ZonedDateTime대신 사용해야합니다 .
Basil Bourque

3

주로 다음과 같이 DateFormat 구성 요소에 시간대를 설정하는 것이 좋습니다.

DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));

그런 다음 0 밀리 초를 포맷터에 전달하여 "00:00:00"시간을 얻을 수 있습니다.

String time = dateFormat.format(0);

또는 Date 객체를 만들 수 있습니다.

Date date = new Date(0); // also pass milliseconds
String time = dateFormat.foramt(date);

또는 캘린더 구성 요소를 사용하여 더 많은 가능성을 가질 수 있지만 캘린더 인스턴스에 대해 시간대를 GMT로 설정해야합니다.

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.US);
calendar.set(Calendar.HOUR_OF_DAY, 5);
calendar.set(Calendar.MINUTE, 37);
calendar.set(Calendar.SECOND, 27);

dateFormat.format(calendar.getTime());

2

tl; dr

myJavaUtilDate                                 // The terrible `java.util.Date` class is now legacy. Use *java.time* instead.
.toInstant()                                   // Convert this moment in UTC from the legacy class `Date` to the modern class `Instant`.
.atZone( ZoneId.of( "Africa/Tunis" ) )         // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone).
.toLocalDate()                                 // Extract the date-only portion.
.atStartOfDay( ZoneId.of( "Africa/Tunis" ) )   // Determine the first moment of that date in that zone. The day does *not* always start at 00:00:00.

java.time

JSR 310에 정의 된 최신 java.time 클래스로 몇 년 전에 대체되었던 끔찍한 오래된 날짜-시간 클래스를 사용하고 있습니다.

DateInstant

A는 java.util.DateUTC의 순간을 나타냅니다. 대체는 Instant. 이전 클래스에 추가 된 새 변환 메서드를 호출합니다.

Instant instant = myJavaUtilDate.toInstant() ;

시간대

새 시간을 의미 할 시간대를 지정하십시오.

지정 적절한 시간대 이름 의 형식 Continent/Region예컨대, America/Montreal, Africa/Casablanca, 또는 Pacific/Auckland. EST또는 같은 2-4 자의 약어 IST는 표준 시간대 가 아니고 , 표준화되지 않았으며, 고유하지도 않은 (!)이므로 절대 사용하지 마십시오 .

ZoneId z = ZoneId.of( "America/Montreal" ) ;

ZonedDateTime

을 적용 ZoneId받는 Instant를 얻을 ZonedDateTime. 같은 순간, 타임 라인의 같은 지점이지만 벽시계 시간은 다릅니다.

ZonedDateTime zdt = instant.atZone( z ) ;

시간 변경

시간 변경을 요청하셨습니다. a LocalTime를 적용하여 모든 시간 부분 (시, 분, 초, 분수 초)을 변경합니다. 새 ZonedDateTime값은 원본을 기반으로 인스턴스화됩니다. java.time의 수업이 사용하는 불변의 객체를 제공하는 패턴을 스레드 안전을 .

LocalTime lt = LocalTime.of( 15 , 30 ) ;  // 3:30 PM.
ZonedDateTime zdtAtThreeThirty = zdt.with( lt ) ; 

하루의 첫 순간

하지만 특별히 00:00을 요청하셨습니다. 그래서 분명히 당신은 하루의 첫 순간을 원합니다. 주의 : 일부 구역의 어떤 날은 00:00:00에 시작하지 않습니다. DST (일광 절약 시간)와 같은 예외로 인해 01:00:00과 같은 다른 시간에 시작할 수 있습니다.

하자 java.time는 첫 순간을 결정합니다. 날짜 전용 부분을 추출하십시오. 그런 다음 첫 번째 순간을 얻기 위해 시간대를 통과하십시오.

LocalDate ld = zdt.toLocalDate() ;
ZonedDateTime zdtFirstMomentOfDay = ld.atStartOfDay( z ) ;

UTC로 조정

UTC로 돌아 가야하는 경우 Instant.

Instant instant = zdtFirstMomentOfDay.toInstant() ;

InstantDate

당신이 필요로하는 경우는 java.util.Date아직 업데이트되지 이전 코드와 상호 운용 할 수 java.time , 변환.

java.util.Date d = java.util.Date.from( instant ) ;

1

이 작업이 더 쉬울 수 있습니다 (Java 8에서).

LocalTime.ofNanoOfDay(0)

감사합니다. 지난 2 년 동안 다른 작업을 수행했고 그 전에는 Java 6/7을 사용했습니다. 저는 지금 Java로 돌아 왔고 (Groovy에서 몇 가지 작업을 한 후) Java 8 차이점을 좋아합니다.
meszias

1

Java 8 / Joda-datetime api 의 LocalDate 클래스를 사용하여 java.util.Date 시간 부분을 00:00:00으로 설정할 수 있습니다 .

Date datewithTime = new Date() ; // ex: Sat Apr 21 01:30:44 IST 2018
LocalDate localDate = LocalDate.fromDateFields(datewithTime);
Date datewithoutTime = localDate.toDate(); // Sat Apr 21 00:00:00 IST 2018

1

문자열에 00:00:00 형식이 필요한 경우 아래와 같이 SimpleDateFormat을 사용해야합니다. "h"대신 "H"사용.

Date today = new Date();
SimpleDateFormat ft = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); 
//not SimpleDateFormat("dd-MM-yyyy hh:mm:ss")
Calendar calendarDM = Calendar.getInstance();
calendarDM.setTime(today);
calendarDM.set(Calendar.HOUR, 0);
calendarDM.set(Calendar.MINUTE, 0);
calendarDM.set(Calendar.SECOND, 0);
System.out.println("Current Date: " + ft.format(calendarDM.getTime()));

//Result is: Current Date: 29-10-2018 00:00:00

0

이를 수행하는 또 다른 방법은 초없이 DateFormat을 사용하는 것입니다.

public static Date trim(Date date) {
    DateFormat format = new SimpleDateFormat("dd.MM.yyyy");
    Date trimmed = null;
    try {
        trimmed = format.parse(format.format(date));
    } catch (ParseException e) {} // will never happen
    return trimmed;
}

0

다음 중 하나를 수행 할 수 있습니다.

Calendar cal = Calendar.getInstance();
cal.set(year, month, dayOfMonth, 0, 0, 0);
Date date = cal.getTime();

0

Java8이 새로운 Date 함수를 추가함에 따라이를 쉽게 수행 할 수 있습니다.


    // If you have instant, then:
    Instant instant1 = Instant.now();
    Instant day1 = instant1.truncatedTo(ChronoUnit.DAYS);
    System.out.println(day1); //2019-01-14T00:00:00Z

    // If you have Date, then:
    Date date = new Date();
    Instant instant2 = date.toInstant();
    Instant day2 = instant2.truncatedTo(ChronoUnit.DAYS);
    System.out.println(day2); //2019-01-14T00:00:00Z

    // If you have LocalDateTime, then:
    LocalDateTime dateTime = LocalDateTime.now();
    LocalDateTime day3 = dateTime.truncatedTo(ChronoUnit.DAYS);
    System.out.println(day3); //2019-01-14T00:00
    String format = day3.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
    System.out.println(format);//2019-01-14T00:00:00


LocalDateTime시간대 또는 UTC로부터의 오프셋 개념이 없기 때문에 순간을 나타낼 수 없습니다. 전화는 LocalDateTime.now거의 의미가 없습니다. ZonedDateTime대신 사용해야합니다 .
Basil Bourque
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.