it-source

왜 2020년 3월 30일과 3월 1일의 차이가 29일이 아닌 28일을 잘못 제공하는가?

criticalcode 2023. 1. 13. 19:48
반응형

왜 2020년 3월 30일과 3월 1일의 차이가 29일이 아닌 28일을 잘못 제공하는가?

TimeUnit.DAYS.convert(
   Math.abs(
      new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").parse("30-03-2020 00:00:00").getTime() - 
      new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").parse("1-03-2020 00:00:00").getTime()
   ),
   TimeUnit.MILLISECONDS)

결과는 28인데 반해 29가 되어야 합니다.

시간대/장소가 문제일 수 있습니까?

문제는 서머타임 교대제(2020년 3월 8일 일요일) 때문에 이 날짜들 사이에 28일과 23시간이 있다는 것입니다. TimeUnit.DAYS.convert(...) 는 결과를 28일로 잘라냅니다.

문제를 확인하려면(미국 동부 표준시)

SimpleDateFormat fmt = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
long diff = fmt.parse("30-03-2020 00:00:00").getTime() -
            fmt.parse("1-03-2020 00:00:00").getTime();

System.out.println(diff);
System.out.println("Days: " + TimeUnit.DAYS.convert(Math.abs(diff), TimeUnit.MILLISECONDS));
System.out.println("Hours: " + TimeUnit.HOURS.convert(Math.abs(diff), TimeUnit.MILLISECONDS));
System.out.println("Days: " + TimeUnit.HOURS.convert(Math.abs(diff), TimeUnit.MILLISECONDS) / 24.0);

산출량

2502000000
Days: 28
Hours: 695
Days: 28.958333333333332

수정하려면 DST가 없는 시간대를 사용합니다(: UTC:

SimpleDateFormat fmt = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
long diff = fmt.parse("30-03-2020 00:00:00").getTime() -
            fmt.parse("1-03-2020 00:00:00").getTime();

산출량

2505600000
Days: 29
Hours: 696
Days: 29.0

이 문제의 원인은 이미 안드레아스의 대답에 언급되어 있다.

문제는 정확히 무엇을 세고 싶은가이다.실제 차이는 28이 아니라 29여야 한다고 말하고 "위치/구역 시간이 문제가 될 수 있는지" 물어보면 실제로 무엇을 세고 싶은지 알 수 있습니다.시간대의 차이를 없애고 싶은 모양이군요.

시간대와 시간대가 없이 날짜만 계산하고 싶으시겠죠.

자바 8

다음 예에서는 시간대와 시간대가 없는 날짜인 정확히 그 값을 나타내는 클래스를 사용하고 있습니다.LocalDate.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d-MM-yyyy HH:mm:ss");
LocalDate start = LocalDate.parse("1-03-2020 00:00:00", formatter);
LocalDate end = LocalDate.parse("30-03-2020 00:00:00", formatter);

long daysBetween = ChronoUnit.DAYS.between(start, end);

주의:ChronoUnit,DateTimeFormatter그리고.LocalDate 태그에 따르면 사용할 수 없는 Java 8 이상이 필요합니다.하지만, 아마도 미래의 독자들에게는 그럴 것이다.

Ole V.V.에서 언급했듯이, Java 8 날짜 및 시간 API 기능을 Java 6 및 7로 백포트하는 ThreeTen Backport도 있습니다.

언급URL : https://stackoverflow.com/questions/60071278/why-does-the-difference-between-30-march-and-1-march-2020-erroneously-give-28-da

반응형