programing

하루의 시작 시간과 종료 시간을 어떻게 구합니까?

firstcheck 2022. 7. 5. 00:07
반응형

하루의 시작 시간과 종료 시간을 어떻게 구합니까?

하루의 시작 시간과 종료 시간을 어떻게 구합니까?

다음과 같은 코드는 정확하지 않습니다.

 private Date getStartOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DATE);
    calendar.set(year, month, day, 0, 0, 0);
    return calendar.getTime();
}

private Date getEndOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DATE);
    calendar.set(year, month, day, 23, 59, 59);
    return calendar.getTime();
}

그것은 밀리초 단위로 정확하지 않다.

자바 8


public static Date atStartOfDay(Date date) {
    LocalDateTime localDateTime = dateToLocalDateTime(date);
    LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
    return localDateTimeToDate(startOfDay);
}

public static Date atEndOfDay(Date date) {
    LocalDateTime localDateTime = dateToLocalDateTime(date);
    LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
    return localDateTimeToDate(endOfDay);
}

private static LocalDateTime dateToLocalDateTime(Date date) {
    return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}

private static Date localDateTimeToDate(LocalDateTime localDateTime) {
    return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}

업데이트: 이 두 가지 방법을 Java 유틸리티 클래스에 추가했습니다.

다음 위치에 있는 Maven Central Repository에 있습니다.

<dependency>
  <groupId>com.github.rkumsher</groupId>
  <artifactId>utils</artifactId>
  <version>1.3</version>
</dependency>

Java 7 이전 버전


Apache Commons 사용

public static Date atEndOfDay(Date date) {
    return DateUtils.addMilliseconds(DateUtils.ceiling(date, Calendar.DATE), -1);
}

public static Date atStartOfDay(Date date) {
    return DateUtils.truncate(date, Calendar.DATE);
}

Apache Commons 미포함

public Date atEndOfDay(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();
}

public Date atStartOfDay(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();
}

dr;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 접근방식을 사용합니다.시작은 포함하지만 끝은 배타적입니다.이 접근법은 하루의 마지막 1초를 설명하지 못하는 코드의 결함을 해결합니다.

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로 만, 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 라이브러리를 추가하여 해당 클래스를 사용하여 이 쌍을 나타낼 수 있습니다.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은 이러한 목적을 위한 메서드를 제공합니다.java.time에서도 마찬가지로,LocalDate::atStartOfDay.

StackOverflow에서 "joda half-open"을 검색하여 자세한 설명과 예를 확인하십시오.

Bill Schneider가 작성한 이 게시물, 시간 간격기타 범위는 반쯤 열려 있어야 합니다.

레거시 날짜/시간 클래스 사용 안 함

java.util.날짜 및.캘린더 수업은 귀찮기로 악명 높다.그들을 피하세요.

java.time 클래스를 사용합니다.java.time 프레임워크는 매우 성공적인 조다 타임 라이브러리의 공식 후계입니다.

java.time

java.time 프레임워크는 Java 8 이후에 포함되어 있습니다.ThreeTen-Backport 프로젝트에서 Java 6 및 7로 백포트되었으며 ThreeTenABP 프로젝트에서는 Android로 더욱 수정되었습니다.

는 분해능이 나노초인 UTC 타임라인상의 순간입니다.

Instant instant = Instant.now();

시간대를 적용하여 특정 지역의 벽시계를 가져옵니다.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

하루의 첫 순간을 얻기 위해 수업과 그 방법을 살펴보세요.

ZonedDateTime zdtStart = zdt.toLocalDate().atStartOfDay( zoneId );

Half-Open 접근방식을 사용하여 다음날의 첫 순간을 얻습니다.

ZonedDateTime zdtTomorrowStart = zdtStart.plusDays( 1 );

Java의 모든 날짜 유형(현대 및 레거시) 표

java에는 java.time이 없습니다.IntervalJoda-Time에 대해 아래에 설명된 것과 같은 클래스입니다.그러나 ThreeTen-Extra 프로젝트는 추가 클래스로 java.time을 확장합니다.이 프로젝트는 향후 java.time에 추가될 수 있는 검증의 장입니다.클래스 중 하나가 있습니다.Interval Instant이렇게 뽑을 수 .InstantZonedDateTime★★★★★★★★★★★★★★★★★★.

Interval today = Interval.of( zdtStart.toInstant() , zdtTomorrowStart.toInstant() );

java.time 정보

java.time 프레임워크는 Java 8 이후에 포함되어 있습니다.이러한 클래스는 , 및 등 문제가 많은 오래된 레거시 날짜 시간 클래스를 대체합니다.

자세한 내용은 Oracle 자습서를 참조하십시오.또한 Stack Overflow를 검색하여 많은 예와 설명을 확인하십시오.사양은 JSR 310입니다.

현재 유지보수 모드에 있는 조다 타임 프로젝트는 java.time 클래스로의 이행을 권장합니다.

java.time 객체를 데이터베이스와 직접 교환할 수 있습니다.JDBC 4.2 이후준거한JDBC 드라이버를 사용합니다.스트링도 필요 없고java.sql.*반.휴지 상태 5 및 JPA 2.2는 java.time을 지원합니다.

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


조다 타임

업데이트: Joda-Time 프로젝트는 유지보수 모드로 전환되었으며 java.time 클래스로의 이행을 권장합니다.역사를 위해 이 부분은 그대로 두겠습니다.

Joda-Time에는 다양한 방법으로 시간 범위를 나타내는 세 가지 클래스가 있습니다.Interval,Period,그리고.Duration. ANInterval우주의 연대표에 특정한 시작과 끝이 있습니다.이것은 "하루"를 나타내려는 우리의 요구에 부합합니다.

우리는 메서드라고 부른다.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로 변환할 수 있습니다.날짜.

java.util.Date date = todayStart.toDate();

getEndOfDay에서는 다음을 추가할 수 있습니다.

calendar.set(Calendar.MILLISECOND, 999);

수학적으로는 하루의 끝을 지정할 수 없지만, "다음 날의 시작 전"이라고 말하는 것 외에는 지정할 수 없습니다.

그래서 이렇게 말하는 대신if(date >= getStartOfDay(today) && date <= getEndOfDay(today)), 다음과 같이 말할 필요가 있습니다.if(date >= getStartOfDay(today) && date < getStartOfDay(tomorrow))이것은 훨씬 더 확실한 화질입니다(밀리초의 정밀도에 대해서는 걱정할 필요가 없습니다).

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
// end of a day
now.with(LocalTime.MAX); // 2015-11-19T23:59:59.999999999

Java 8 또는 ThreeTenABP

존 날짜 시간

ZonedDateTime curDate = ZonedDateTime.now();

public ZonedDateTime startOfDay() {
    return curDate
    .toLocalDate()
    .atStartOfDay()
    .atZone(curDate.getZone())
    .withEarlierOffsetAtOverlap();
}

public ZonedDateTime endOfDay() {

    ZonedDateTime startOfTomorrow =
        curDate
        .toLocalDate()
        .plusDays(1)
        .atStartOfDay()
        .atZone(curDate.getZone())
        .withEarlierOffsetAtOverlap();

    return startOfTomorrow.minusSeconds(1);
}

// based on https://stackoverflow.com/a/29145886/1658268

Local Date Time(로컬 날짜 시간)

LocalDateTime curDate = LocalDateTime.now();

public LocalDateTime startOfDay() {
    return curDate.atStartOfDay();
}

public LocalDateTime endOfDay() {
    return startOfTomorrow.atTime(LocalTime.MAX);  //23:59:59.999999999;
}

// based on https://stackoverflow.com/a/36408726/1658268

그게 도움이 됐으면 좋겠어요.

java8 java.time을 사용하여 하루의 시작을 찾는 추가 방법입니다.ZonedDateTime을 경유하지 않고LocalDateTime는 단순히 을 DAYS로.

zonedDateTimeInstance.truncatedTo( ChronoUnit.DAYS );

Java 8에서는 다음 단일 행 문이 작동합니다.이 예에서는 UTC 시간대를 사용합니다.현재 사용하고 있는 Time Zone을 변경하는 것을 검토해 주십시오.

System.out.println(new Date());

final LocalDateTime endOfDay       = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
final Date          endOfDayAsDate = Date.from(endOfDay.toInstant(ZoneOffset.UTC));

System.out.println(endOfDayAsDate);

final LocalDateTime startOfDay       = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
final Date          startOfDayAsDate = Date.from(startOfDay.toInstant(ZoneOffset.UTC));

System.out.println(startOfDayAsDate);

출력과의 시차가 없는 경우. 험::ZoneOffset.ofHours(0)

프레임워크에 의존하지 않는 또 하나의 솔루션은 다음과 같습니다.

static public Date getStartOfADay(Date day) {
    final long oneDayInMillis = 24 * 60 * 60 * 1000;
    return new Date(day.getTime() / oneDayInMillis * oneDayInMillis);
}

static public Date getEndOfADay(Date day) {
    final long oneDayInMillis = 24 * 60 * 60 * 1000;
    return new Date((day.getTime() / oneDayInMillis + 1) * oneDayInMillis - 1);
}

UTC 기반 시간이 반환된다는 점에 주의해 주세요.

이 코드를 사용해 봤는데 잘 작동해요!

final ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
final ZonedDateTime startofDay =
    now.toLocalDate().atStartOfDay(ZoneOffset.UTC);
final ZonedDateTime endOfDay =
    now.toLocalDate().atTime(LocalTime.MAX).atZone(ZoneOffset.UTC);

조금 늦은 건 알지만 Java 8의 경우 OffsetDateTime(TimeZone, Nanoseconds 등 많은 장점을 제공하는 것)을 사용하고 있다면 다음 코드를 사용할 수 있습니다.

OffsetDateTime reallyEndOfDay = someDay.withHour(23).withMinute(59).withSecond(59).withNano(999999999);
// output: 2019-01-10T23:59:59.999999999Z
private Date getStartOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DATE);
    calendar.setTimeInMillis(0);
    calendar.set(year, month, day, 0, 0, 0);
    return calendar.getTime();
    }

private Date getEndOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DATE);
    calendar.setTimeInMillis(0);
    calendar.set(year, month, day, 23, 59, 59);
    return calendar.getTime();
    }

calendar.setTimeInMillis(0), 최대 밀리초까지의 정확도를 제공합니다.

이 「 」인 , 최단 응답.TZ:

LocalDateTime start = LocalDate.now(TZ).atStartOfDay()
LocalDateTime end = start.plusDays(1)

「 」를 사용해 합니다.isAfter() ★★★★★★★★★★★★★★★★★」isBefore() 를 하여 합니다.toEpochSecond() ★★★★★★★★★★★★★★★★★」toInstant()★★★★★★★★★★★★★★★★★★.

Instant 변수 유형이 필요했고 타임존이 항상 모든 것을 변경하는 것을 방해했기 때문에 모든 솔루션에 몇 가지 불편함이 있었습니다.그리고 솔루션을 조합하는 것은 좋은 선택이라고 생각했습니다.

        LocalDate today = LocalDate.now();
        Instant startDate = Instant.parse(today.toString()+"T00:00:00Z");
        Instant endDate = Instant.parse(today.toString()+"T23:59:59Z");

그 결과 우리는

        startDate = 2020-01-30T00:00:00Z
        endDate = 2020-01-30T23:59:59Z

도움이 됐으면 좋겠다

가장 쉬운 방법은 다음과 같습니다.

// Joda Time

DateTime dateTime=new DateTime(); 

StartOfDayMillis = dateTime.withMillis(System.currentTimeMillis()).withTimeAtStartOfDay().getMillis();
EndOfDayMillis = dateTime.withMillis(StartOfDayMillis).plusDays(1).minusSeconds(1).getMillis();

이 밀리는 달력으로 변환할 수 있습니다.Joda Time의 요건에 따라 Instant 또는 LocalDate를 선택합니다.

 //this will work for user in time zone MST with 7 off set or UTC with saving time 

 //I have tried all the above and they fail the only solution is to use some math
 //the trick is to rely on $newdate is time()     //strtotime is corrupt it tries to read to many minds
 //convert to time to use with javascript*1000
 
 $dnol = strtotime('today')*1000;
 $dn = ($newdate*1000)-86400000;
 $dz=$dn/86400000;      //divide into days
 $dz=floor($dz);     //filter off excess time
 $dzt=$dz*86400000;     // put back into days UTC
 $jsDate=$dzt*1+(7*3600000);     // 7 is the off set you can store the 7 in database
 $dzt=$dzt-3600000;      //adjusment for summerTime UTC additional table for these dates will drive you crazy
 //solution get users [time off sets] with browser, up date to data base for user with ajax when they ain't lookin



 <?php
 $t=time();
 echo($t . "<br>");
 echo(date("Y-m-d",$t));
 echo '<BR>'.$dnol;
 echo '<BR>'.$dzt.'<BR>';
 echo(date("Y-m-d",$dzt/1000));      //convert back for php /1000
 echo '<BR>';
 echo(date('Y-m-d h:i:s',$dzt/1000));

 ?>

다음 코드는 OP의 원래 공식을 사용하여 ms의 부정확성을 조정합니다.

    private static Date getStartOfDay() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DATE);
        calendar.set(year, month, day, 0, 0, 0);
        long approximateTimestamp = calendar.getTime().getTime();
        long extraMillis = (approximateTimestamp % 1000);
        long exactTimestamp = approximateTimestamp - extraMillis;
        return new Date(exactTimestamp);
    }

    private static Date getEndOfDay() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DATE);
        calendar.set(year, month, day, 23, 59, 59);
        long approximateTimestamp = calendar.getTime().getTime();
        long extraMillis = (approximateTimestamp % 1000);
        long exactTimestamp = approximateTimestamp - extraMillis + 999;
        return new Date(exactTimestamp);
    }

이 스레드의 다른 많은 응답과 달리 이전 버전의 Java 및 Android API와 호환됩니다.

public static Date beginOfDay(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);

    return cal.getTime();
}

public static Date endOfDay(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.set(Calendar.HOUR_OF_DAY, 23);
    cal.set(Calendar.MINUTE, 59);
    cal.set(Calendar.SECOND, 59);
    cal.set(Calendar.MILLISECOND, 999);

    return cal.getTime();
}
Date date = new Date();
LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);

타임스탬프:

Timestamp startTs = Timestamp.valueOf(startOfDay);
Timestamp endTs = Timestamp.valueOf(endOfDay);

언급URL : https://stackoverflow.com/questions/10308356/how-to-obtain-the-start-time-and-end-time-of-a-day

반응형