날짜 문자열이 있고 java Date API를 사용하여 일반 날짜로 구문 분석하고 싶습니다. 다음은 내 코드입니다.
public static void main(String[] args) {
String date="2010-10-02T12:23:23Z";
String pattern="yyyy-MM-ddThh:mm:ssZ";
SimpleDateFormat sdf=new SimpleDateFormat(pattern);
try {
Date d=sdf.parse(date);
System.out.println(d.getYear());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
그러나 예외가 있습니다. java.lang.IllegalArgumentException: Illegal pattern character 'T'
문자열을 분할하고 수동으로 구문 분석 해야하는지 궁금합니다.
BTW, 나는 T의 양쪽에 작은 따옴표 문자를 추가하려고했습니다.
String pattern="yyyy-MM-dd'T'hh:mm:ssZ";
또한 작동하지 않습니다.
답변
Java 8 이상 업데이트
이제 가장 최신 버전의 Java를 Instant.parse("2015-04-28T14:23:38.521Z")
사용 Instant
하지 않고 사용해야하기 때문에 이제 간단하게 올바른 작업을 수행 할 수 있습니다 java.util.Date
.
DateTimeFormatter
대신에 사용해야합니다SimpleDateFormatter
.
원래 답변 :
아래 설명은 형식이 나타내는 내용으로 여전히 유효합니다. 그러나 Java 8이 어디에나 사용되기 전에 작성되었으므로 Java 8 이상을 사용하는 경우 사용해서는 안되는 이전 클래스를 사용합니다.
이것은 다음과 같이 후행 입력과 함께 작동합니다 Z
.
패턴에서
T
로 이스케이프'
양쪽에서 .
Z
끝에 대한 패턴 은 실제로XXX
JavaDoc에 문서화되어 있으며SimpleDateFormat
실제로Z
는 이전TimeZone
정보 의 마커
이기 때문에 사용 방법에 대해서는 명확하지 않습니다 .
Q2597083.java
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class Q2597083
{
/**
* All Dates are normalized to UTC, it is up the client code to convert to the appropriate TimeZone.
*/
public static final TimeZone UTC;
/**
* @see <a href="http://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations">Combined Date and Time Representations</a>
*/
public static final String ISO_8601_24H_FULL_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
/**
* 0001-01-01T00:00:00.000Z
*/
public static final Date BEGINNING_OF_TIME;
/**
* 292278994-08-17T07:12:55.807Z
*/
public static final Date END_OF_TIME;
static
{
UTC = TimeZone.getTimeZone("UTC");
TimeZone.setDefault(UTC);
final Calendar c = new GregorianCalendar(UTC);
c.set(1, 0, 1, 0, 0, 0);
c.set(Calendar.MILLISECOND, 0);
BEGINNING_OF_TIME = c.getTime();
c.setTime(new Date(Long.MAX_VALUE));
END_OF_TIME = c.getTime();
}
public static void main(String[] args) throws Exception
{
final SimpleDateFormat sdf = new SimpleDateFormat(ISO_8601_24H_FULL_FORMAT);
sdf.setTimeZone(UTC);
System.out.println("sdf.format(BEGINNING_OF_TIME) = " + sdf.format(BEGINNING_OF_TIME));
System.out.println("sdf.format(END_OF_TIME) = " + sdf.format(END_OF_TIME));
System.out.println("sdf.format(new Date()) = " + sdf.format(new Date()));
System.out.println("sdf.parse(\"2015-04-28T14:23:38.521Z\") = " + sdf.parse("2015-04-28T14:23:38.521Z"));
System.out.println("sdf.parse(\"0001-01-01T00:00:00.000Z\") = " + sdf.parse("0001-01-01T00:00:00.000Z"));
System.out.println("sdf.parse(\"292278994-08-17T07:12:55.807Z\") = " + sdf.parse("292278994-08-17T07:12:55.807Z"));
}
}
다음과 같은 출력을 생성합니다.
sdf.format(BEGINNING_OF_TIME) = 0001-01-01T00:00:00.000Z
sdf.format(END_OF_TIME) = 292278994-08-17T07:12:55.807Z
sdf.format(new Date()) = 2015-04-28T14:38:25.956Z
sdf.parse("2015-04-28T14:23:38.521Z") = Tue Apr 28 14:23:38 UTC 2015
sdf.parse("0001-01-01T00:00:00.000Z") = Sat Jan 01 00:00:00 UTC 1
sdf.parse("292278994-08-17T07:12:55.807Z") = Sun Aug 17 07:12:55 UTC 292278994
답변
tl; dr
java.time.Instant
클래스를 사용 하여 UTC로 순간을 나타내는 표준 ISO 8601 형식으로 텍스트를 구문 분석 하십시오 .
Instant.parse( "2010-10-02T12:23:23Z" )
ISO 8601
해당 형식은 날짜-시간 문자열 형식에 대한 ISO 8601 표준에 의해 정의됩니다 .
양자 모두:
- Java 8 이상에 내장 된 java.time 프레임 워크 ( Tutorial )
- Joda-Time 라이브러리
… 문자열 구문 분석 및 생성에는 기본적으로 ISO 8601 형식을 사용하십시오.
일반적으로 이전 java.util.Date를 사용하지 않아야합니다. /.Calendar & java.text.SimpleDateFormat 클래스 번거롭고 혼란스럽고 결함이 있으므로 . 상호 운용이 필요한 경우 이리저리로 변환 할 수 있습니다.
java.time
Java 8 이상에는 새로운 java.time 프레임 워크 가 내장되어 있습니다. Joda-Time 에서 영감을 얻어 JSR 310 에서 정의 하고 ThreeTen-Extra 프로젝트 에서 확장했습니다 .
Instant instant = Instant.parse( "2010-10-02T12:23:23Z" ); // `Instant` is always in UTC.
이전 클래스로 변환하십시오.
java.util.Date date = java.util.Date.from( instant ); // Pass an `Instant` to the `from` method.
시간대
필요한 경우 시간대를 지정할 수 있습니다.
ZoneId zoneId = ZoneId.of( "America/Montreal" ); // Define a time zone rather than rely implicitly on JVM’s current default time zone.
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId ); // Assign a time zone adjustment from UTC.
변하게 하다.
java.util.Date date = java.util.Date.from( zdt.toInstant() ); // Extract an `Instant` from the `ZonedDateTime` to pass to the `from` method.
조다 타임
업데이트 : Joda-Time 프로젝트는 현재 유지 보수 모드입니다. 팀은 java.time 으로의 마이그레이션을 조언합니다. 클래스 .
Joda-Time 2.8의 예제 코드는 다음과 같습니다.
org.joda.time.DateTime dateTime_Utc = new DateTime( "2010-10-02T12:23:23Z" , DateTimeZone.UTC ); // Specifying a time zone to apply, rather than implicitly assigning the JVM’s current default.
이전 클래스로 변환하십시오. juDate에는 시간대를 지정할 수 없으므로 지정된 시간대는 변환시 손실됩니다.
java.util.Date date = dateTime_Utc.toDate(); // The `toDate` method converts to old class.
시간대
필요한 경우 시간대를 지정할 수 있습니다.
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTime_Montreal = dateTime_Utc.withZone ( zone );
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 클래스는 어디서 구할 수 있습니까?
- 자바 SE 8 , 자바 SE 9 , 나중에
- 내장.
- 번들로 구현 된 표준 Java API의 일부입니다.
- Java 9에는 몇 가지 사소한 기능과 수정 사항이 추가되었습니다.
- Java SE 6 및 Java SE 7
- 대부분의 java.time 기능은 ThreeTen-Backport 에서 Java 6 & 7로 백 포트됩니다. .
- 기계적 인조 인간
- java.time 클래스의 최신 버전의 Android 번들 구현.
- 이전 Android (<26)의 경우 ThreeTenABP 프로젝트 는 위에서 언급 한 ThreeTen-Backport를 채택합니다 . ThreeTenABP 사용 방법…을 참조하십시오 .
ThreeTen – 추가 프로젝트 추가 클래스와 java.time를 확장합니다. 이 프로젝트는 향후 java.time에 추가 될 수있는 입증 된 근거입니다. 당신은 여기에 몇 가지 유용한 클래스와 같은 찾을 수 있습니다 Interval
, YearWeek
, YearQuarter
, 그리고 더 .
답변
이 그대로 – – 지금은 위의 두 가지 답변입니다 그리고 그들은 모두 오래이다 (그리고 , TL 박사 나는 새로운 사용하기 시작 내 경험에서 요약을 쓰기 때문에, 너무 짧은 IMHO) java.time의 (라이브러리를 적용 Java 버전에 대한 다른 답변에서 언급 한 바와 같이 8 이상). ISO 8601 은 날짜를 쓰는 표준 방법을 설정합니다. YYYY-MM-DD
따라서 날짜-시간 형식은 다음과 같으며 (밀리 초의 경우 0, 3, 6 또는 9 자리 일 수 있음) 서식 문자열이 필요하지 않습니다.
import java.time.Instant;
public static void main(String[] args) {
String date="2010-10-02T12:23:23Z";
try {
Instant myDate = Instant.parse(date);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
나는 그것을 필요로하지 않았지만 연도를 질문에서 코드로 얻는 것처럼 :
까다 롭고 Instant
직접적으로 할 수 없으며 Calendar
질문을 통해 수행 할 수 있습니다 . 현재 연도의 정수 값을 Java 및 Java 로 변환하십시오. 달력에 시간이 있지만 형식이 고정되어 있으므로 IMHO는 하위 문자열을 사용하는 것이 더 간단합니다.
myDate.toString().substring(0,4);