Excel에서 날짜를 나타내는 숫자를 Java Date 객체로 변환
Excel에 날짜 열이 있지만 Java 응용 프로그램에서 읽을 때 숫자로 값이 표시됩니다.
예
Excel 날짜
1/1/2013
로 알고 있습니다.
41275.00
내 자바 애플리케이션에서 숫자를 날짜로 변환하는 방법은 무엇입니까?
다음은 Excel 날짜를 Java 날짜로 변환하는 최소한의 작업 예제입니다.
Date javaDate= DateUtil.getJavaDate((double) 41275.00);
System.out.println(new SimpleDateFormat("MM/dd/yyyy").format(javaDate));
어느 쪽이 돌아옵니까?
01/01/2013
다음 패키지도 가져와야 합니다.
java.text.SimpleDateFormat
java.util.Date
tl;dr
최신 java.time 클래스를 사용합니다.
LocalDate // Represent a date-only vaule, without time-of-day and without time zone.
.of( 1899 , Month.DECEMBER , 30 ) // Specify epoch reference date used by *some* versions of Excel. Beware: Some versions use a 1904 epoch reference. Returns a `LocalDate` object.
.plusDays( // Add a number of days.
(long) Double.parseDouble( "41275.00" ) // Get a number of whole days from your input string.
) // Returns another instance of a `LocalDate`, per Immutable Objects pattern, rather than altering the original.
.toString() // Generate text representing the value of this `LocalDate` in standard ISO 8601 format.
2013-01-01
java.time
최신 솔루션은 초기 버전의 Java와 함께 번들된 끔찍한 레거시 날짜-시간 클래스를 대체하는 java.time 클래스를 사용합니다.
에포크 기준일 : 1899-12-30
이 문서에 따르면 Microsoft Excel의 이 값은 UTC에서 1900-01-01의 epoch 참조 이후의 일 수입니다.내부적으로, 실제 참조 날짜는 이 위키백과 페이지에 문서화된 1899년 12월 30일입니다.
주의하세요, 일부 Excel 버전(macOS의 이전 버전?)은 1904년에 다른 시대를 사용합니다.
코드의 어딘가에 에포크 참조를 설정합니다.
final static public LocalDate EXCEL_EPOCH_REFERENCE =
LocalDate.of( 1899 , Month.DECEMBER , 30 )
; // Beware: Some versions of Excel use a 1904 epoch reference.
계산을 해라.
입력 문자열을 다음과 같이 구문 분석합니다.BigDecimal
정확성을 위해 (더 빠른 실행을 위해 정확성을 대체하는 부동 소수점 유형을 선택합니다.)
BigDecimal countFromEpoch = new BigDecimal( "41275.00" );
Epoch 참조 날짜에 전체 일 수를 추가합니다.
long days = countFromEpoch.longValue(); // Extract the number of whole days, dropping the fraction.
LocalDate localDate = EXCEL_EPOCH_REFERENCE.plusDays( days );
localDate.toString(): 2013-01-01
java.time 정보
java.time 프레임워크는 Java 8 이상에 내장되어 있습니다.이러한 클래스는 , , 및 와 같은 문제가 있는 오래된 기존 날짜/시간 클래스를 대체합니다.
자세한 내용은 오라클 튜토리얼을 참조하십시오.그리고 스택 오버플로를 검색하여 많은 예와 설명을 찾습니다.사양은 JSR 310입니다.
현재 유지보수 모드에 있는 Joda-Time 프로젝트는 java.time 클래스로 마이그레이션할 것을 권장합니다.
java.time 개체를 데이터베이스와 직접 교환할 수 있습니다.JDBC 4.2 이상을 준수하는 JDBC 드라이버를 사용합니다.문자열이 필요하지 않고, 필요하지 않습니다.java.sql.*
반.최대 절전 모드 5 및 JPA 2.2는 java.time을 지원합니다.
java.time 클래스는 어디서 얻습니까?
- Java SE 8, Java SE 9, Java SE 10, Java SE 11 이상 - 번들 구현이 포함된 표준 Java API의 일부입니다.
- 자바 9는 몇 가지 사소한 기능과 수정 사항을 제공했습니다.
- Java SE 6 및 Java SE 7
- 대부분의 java.time 기능은 스리 텐 백포트에서 Java 6 및 7로 백포트됩니다.
- 안드로이드
- 최신 버전의 Android(26+)는 java.time 클래스의 번들 구현을 제공합니다.
- 초기 Android(<26)의 경우 API desugaring으로 알려진 프로세스가 Android에 원래 내장되지 않은 java.time 기능의 하위 집합을 가져옵니다.
- 디슈가링이 당신에게 필요한 것을 제공하지 않는다면 스리텐ABP 프로젝트는 스리 텐 백포트(위에서 언급)를 Android에 적용합니다.ThreeTenABP 사용 방법을 참조하십시오.
Apache POI에는 해당 http://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/DateUtil.html, , 특히 http://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/DateUtil.html#getJavaDate(double) 에 대한 일부 유틸리티가 있습니다.
참고 Excel 저장소의 날짜는 1900년 이후(경우에 따라 1904년부터일 수 있음)의 일수(소수일 수 포함)입니다.http://support.microsoft.com/kb/180162 을 참조하십시오.
많은 사용자가 이미 지적했듯이 Excel은 날짜와 시간을 1900년 1월 0일 이후의 일 수와 24시간 중 일부를 나타내는 숫자로 저장합니다.ddddd.tttttt
.
이를 직렬 날짜 또는 직렬 날짜 시간이라고 합니다.
그러나 여기서의 답변은 기존 라이브러리에서 메소드를 사용할 준비가 되었다는 점을 제외하고 이야기의 일부만 나타냅니다.
Microsoft의 링크된 문서로는 더 이상 명확하지 않습니다.
MS DATEVALUE 함수 상태:
Excel은 계산에 사용할 수 있도록 날짜를 순차적 일련 번호로 저장합니다.기본적으로 1900년 1월 1일은 일련 번호 1이고, 2008년 1월 1일은 1900년 1월 1일 이후 39,447일이기 때문에 일련 번호 39448입니다.
자, 저는 이 진술을 확인할 것입니다.
LocalDate testDate = LocalDate.of(1900, Month.JANUARY, 1).plusDays(39447);
System.out.println(testDate);// prints 2008-01-02
1900년 1월 1일로부터 39,447일 후에 정말로...2008년 1월 2일!
왜 그런 것일까요?
Excel의 날짜가 한 시대(1899년 12월 30일 또는 1900년 1월 1일 또는 1904년...)에서 시작하는 날짜 수로 표시된다는 사실은 이야기의 일부에 불과합니다.
저는 여기서 궁극적인 답을 찾았습니다: Excel의 날짜와 시간(어떤 신이든 누구든 이 사람들을 축복할 수 있습니다.
Excel에서 날짜 루틴을 구현한 개발자들은 Lotus 1-2-3의 동일한 알려진 문제와의 호환성을 위해 의도적으로 버그를 도입했습니다.
그들은 1900년을 윤년으로 취급했지만 그렇지 않습니다. 1900년 1월 28일을 초과하는 날짜는 실제 날짜보다 하루 더 많습니다.
이것이 Excel이 2008년 1월 1일을 39448이라는 숫자로 나타낸다고 생각하는 이유입니다. 1900년 1월 0일 이후 39,448대이기 때문입니다(그렇습니다, Excel은 0으로 생각합니다). 즉 39,447일 + 1900년 1월 29일입니다.
또한 Excel은 직렬 날짜의 날짜 부분을 1904년 1월 0일 이후의 일 수로 처리할 수 있습니다. 이 모드를 1904-모드 또는 1904-시스템이라고 하며 Macintosh 시스템과의 호환성을 위해 사용됩니다.
Excel 날짜는 시간대 정보를 포함하지 않으므로 시간대 정보 없이 /와 LocalDateTime
같은 Java 클래스를 사용하는 것이 좋습니다.
글쎄요, 실제로 - 요즘에는 - 1900년 12월 30일부터 시작하는 엑셀 시대를 계산할 수 있지만 그렇지 않습니다.
Excel 데모 - 날짜 형식은 dd/mm/yyyy입니다.
날짜가 왼쪽에 숫자로 삽입되었습니다.
필수 변환에 적합한 클래스:
public class SerialDate {
//days from 1899-12-31 to Instant.EPOCH (1970-01-01T00:00:00Z)
public static final long EPOCH = -25568L;
private long serialDays;
private double serialTime;
private long epochDays;
private long daySeconds;
/**
* @param date number of Excel-days since <i>January 0, 1899</i>
*/
public SerialDate(long date) {
serialDays = date;
if (date > 59)//Lotus123 bug
--date;
epochDays = EPOCH + date;
}
/**
* @param date number of days since <i>January 0, 1899</i> with a time fraction
*/
public SerialDate(double date) {
this((long)date);
serialTime = date - serialDays;
daySeconds = Math.round(serialTime * 24 * 60 * 60);
}
/**
* @return days since 1970-01-01
*/
public long toEpochDays() {
return epochDays;
}
/**
* @return seconds of the day for this SerialDate
*/
public long toDaySeconds() {
return daySeconds;
}
/**
* @return a value suitable for an Excel date
*/
public double getSerialDate() {
return serialTime + serialDays;
}
}
사용 예:
LocalDate dt = LocalDate.ofEpochDay(new SerialDate(41275).toEpochDays());
System.out.println(dt);//prints 2013-01-01
SerialDate sd = new SerialDate(33257.415972222225);
LocalDateTime dt = LocalDateTime.of(
LocalDate.ofEpochDay(sd.toEpochDays()),
LocalTime.ofSecondOfDay(sd.toDaySeconds()));
System.out.println(dt);//prints 1991-01-19T09:59
Excel의 일련 날짜는 1900년 1월 1일 이후의 일 수입니다.날짜를 다시 파악하기 위해서는 일련번호를 일 단위로 추가해야 합니다.
종속성이 없는 Java 8용
```
/*
1900-1-0 0
1900-1-1 1
1900-1-2 2
1900-1-3 3
*/
int days = 43323;
LocalDate start = LocalDate.of(1900, 1, 1);
LocalDate today = LocalDate.of(2018, 8, 11);
// days to date
LocalDate date = start.plusDays(days).minusDays(2);
System.out.println(date);
// date to days
long days1 = ChronoUnit.DAYS.between(start, today) + 2;
System.out.println(days1);
```
LocalDateTime의 SerialDate 클래스 예제에 따라 다음 코드를 사용했습니다.
// somewhere as double static
LocalDateTime EXCEL_START = LocalDateTime.of(1899, 12, 30, 0, 0);
Double doubleValue = 44705.416666666664; // input
long days = doubleValue.longValue();
long seconds = Math.round((doubleValue - days) * 24 * 60 * 60);
LocalDateTime converted = EXCEL_START
.plusDays(days)
.plusSeconds(seconds); //2022-05-24T10:00
언급URL : https://stackoverflow.com/questions/19028192/converting-number-representing-a-date-in-excel-to-a-java-date-object
'sourcetip' 카테고리의 다른 글
Vuex 작업 - Axios 반환 오류 (0) | 2023.06.22 |
---|---|
data.frame을 사용해야 합니까, 아니면 matrix를 사용해야 합니까? (0) | 2023.06.22 |
앱스토어에서 iOS 앱을 제거하는 방법 (0) | 2023.06.22 |
Firebase 클라우드 함수 "클라이언트에 이 서버에서 URL/200을 가져올 권한이 없습니다." (0) | 2023.06.22 |
NodeJS 앱 구조(전체 자바스크립트 스택)에 대해 명확하게 알고 싶습니다. (0) | 2023.06.22 |