이 날짜 형식은 무엇입니까? 2011-08-12T20 : 17 : 46.384Z


383

다음 날짜가 2011-08-12T20:17:46.384Z있습니다.. 이것은 어떤 형식입니까? 나는 통해 자바 1.4로 구문 분석하기 위해 노력하고있어 DateFormat.getDateInstance().parse(dateStr)나는군요

java.text.ParseException : 구문 분석 할 수없는 날짜 : "2011-08-12T20 : 17 : 46.384Z"

구문 분석 을 위해 SimpleDateFormat 을 사용해야한다고 생각 하지만 형식 문자열을 먼저 알아야합니다. 내가 지금까지 그것에 대해 모두는 yyyy-MM-dd내가 무엇을 모르기 때문에, T이 문자열의 수단을 - 뭔가 시간대 관련? 이 날짜 문자열은 파일 CMIS 다운로드 히스토리 매체 유형lcmis:downloadedOn 에 표시된 태그 에서 제공 됩니다.


43
그것은이다 ISO 8601
토마스 Nurkiewicz

3
@TomaszNurkiewicz, 그렇지 않습니다. ISO8601에는 Z가 없습니다.
t1gor

4
ISO8601 doe는 끝에 Z를 허용합니다. 위의 링크를 참조하여 UTC를 찾으십시오.
Jonathan Rosenne

2
@ t1gor Z끝 부분은 짧고 UTC를Zulu 의미 합니다. 이 형식은 가장 확실 하다 의 일부 ISO 8601 표준 날짜 - 시간 텍스트 형식의 컬렉션입니다. 그런데이 표준 형식은 기본적으로 java.time 클래스 에서 사용됩니다 .
Basil Bourque

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

답변:


512

T는 날짜와 시간을 구분하기위한 리터럴이며 Z는 "Zulu 시간"(UTC)이라고도하는 "제로 시간 오프셋"을 의미합니다. 문자열에 항상 "Z"가 있으면 다음을 사용할 수 있습니다.

SimpleDateFormat format = new SimpleDateFormat(
    "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));

또는 Joda Time 을 사용하면 사용할 수 있습니다 ISODateTimeFormat.dateTime().


7
우리는 왜 작은 따옴표 주위 필요합니까 TZ?
Maroun

7
@MarounMaroun : 기본적으로 문자 그대로 문자를 원합니다 . 필요하지 않을 수도 있습니다 T(SimpleDateFormat이 알 수없는 지정자를 처리하는 방법을 기억할 수는 없지만) Z"UTC 오프셋 값"(예 : "00")이 아닌 문자 'Z'가되기를 원합니다.
Jon Skeet

2
@nyedidikeke : 링크 된 Wikipedia 페이지에서 UTC에 대한 "Zulu 표준 시간대"가 표시됩니다. 당신이 무엇을 교정하고 있다고 생각하는지 잘 모르겠습니다.
Jon Skeet

9
@ JonSkeet : 불필요한 토론을 일으킬 수 있습니다. 귀하의 답변에 반박하지는 않지만 Z 문자가 "0 UTC 오프셋"에서 초기에 나오는 Z에 주의를 기울이려고했습니다 . 문자 Z는 NATO 발음 알파벳 에서 "Zulu"라고합니다 . 차례로, UTC 제로 오프셋을 참조하는 군사적 접근 방식은 문자 Z에 고정되어 Zulu로 식별되며 Zulu 시간대로 코드화 된 이름을 얻습니다. Z의 의미를 잃지 않았으며 Zulu 시간대 (Z의 Zulu 시간대)가이를 참조하기 위해 상속 된 코드화 된 언어이기 때문에 여전히 UTC 제로 오프셋의 영역 지정자입니다.
nyedidikeke

2
@ nyedidikeke : 나는 여전히 다른 사람이 내 대답을 참조하여 구별에 관심이 있는지 여부에 동의하지 않지만 업데이트했습니다. 역사는 그 답과 크게 관련이 없기 때문에 자세한 내용은 다루지 않겠습니다.
Jon Skeet

86

tl; dr

입력 문자열이 표준 ISO 8601 형식을 사용합니다.

Instant.parse ( "2011-08-12T20:17:46.384Z" ) 

ISO 8601

이 형식은 합리적인 실제 표준 인 ISO 8601에 의해 정의됩니다 .

T시간의 일 부분에서 날짜 부분을 분리한다. Z끝에 수단 UTC를 (즉, 오프셋 - 제로 - UTC에서 시간 - 분 - 초). 가 Z있다 "줄루어"로 발음 .

java.time

초기 버전의 Java와 번들로 제공되는 이전 날짜-시간 클래스는 잘못 설계되고 혼란스럽고 번거로운 것으로 입증되었습니다. 피하십시오.

대신, Java 8 이상에 내장 된 java.time 프레임 워크를 사용하십시오 . java.time 클래스는 이전 날짜-시간 클래스와 매우 성공적인 Joda-Time 라이브러리를 모두 대체합니다.

java.time 클래스 는 날짜-시간 값의 텍스트 표현을 구문 분석 / 생성 할 때 기본적으로 ISO 8601 을 사용 합니다.

Instant클래스는 나노초 의 해상도로 타임 라인의 순간을 UTC 로 나타냅니다 . 해당 클래스는 형식 지정 패턴을 정의하지 않고도 입력 문자열을 직접 구문 분석 할 수 있습니다.

Instant instant = Instant.parse ( "2011-08-12T20:17:46.384Z" ) ;

최신 및 기존 Java의 날짜-시간 유형 테이블


java.time에 대하여

java.time의 프레임 워크는 나중에 자바 8에 내장되어 있습니다. 이 클래스는 까다로운 기존에 대신 기존 과 같은 날짜 - 시간의 수업을 java.util.Date, Calendar, SimpleDateFormat.

Joda 타임 프로젝트는 지금에 유지 관리 모드 의로 마이그레이션을 조언 java.time의 클래스.

자세한 내용은 Oracle Tutorial을 참조하십시오 . 많은 예제와 설명을 보려면 스택 오버플로를 검색하십시오. 사양은 JSR 310 입니다.

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

Java 또는 Android 버전과 함께 사용할 java.time 라이브러리 표

ThreeTen - 추가 프로젝트 추가 클래스와 java.time를 확장합니다. 이 프로젝트는 향후 java.time에 추가 될 수있는 입증 된 근거입니다. 당신은 여기에 몇 가지 유용한 클래스와 같은 찾을 수 있습니다 Interval, YearWeek, YearQuarter, 그리고 .


3
@star“줄 루어”는 군사 및 항공 전통에서 유래 한 것으로, 알파벳 AZ (“J”아님)의 25 자 (각각의 이름이 붙은 글자)는 시간대 버전을 나타냅니다 . "Zulu"영역은 UTC에서 0 시간 오프셋입니다. 참조 .
Basil Bourque

27

Java 구문 분석에 대해서는 확실하지 않지만 ISO8601입니다. http://en.wikipedia.org/wiki/ISO_8601


이 "2016-01-27T17 : 44 : 55UTC", ISO8601입니까?
user1997292

나는 그렇게 믿지 않습니다. 가깝지만 접미사로 UTC 는 허용되지 않습니다. Z 또는 시간대 오프셋 (예 : +0100)이어야합니다. Z와 UTC의 의미는 동일하므로 UTCZ로 변경하면 유효한 ISO 8601이 생성됩니다.
smparkes 2016 년

9

첫 번째 대답보다는 구문 분석하는 다른 방법이 있습니다. 그것을 구문 분석 :

(1) 당신은 날짜와 시간에 대한 정보를 잡아 싶은 경우에, 당신은 그것을 구문 분석 할 수 있습니다 ZonedDatetime(이후 자바 8 또는) Date(구) 목적 :

// ZonedDateTime's default format requires a zone ID(like [Australia/Sydney]) in the end.
// Here, we provide a format which can parse the string correctly.
DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME;
ZonedDateTime zdt = ZonedDateTime.parse("2011-08-12T20:17:46.384Z", dtf);

또는

// 'T' is a literal.
// 'X' is ISO Zone Offset[like +01, -08]; For UTC, it is interpreted as 'Z'(Zero) literal.
String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX";

// since no built-in format, we provides pattern directly.
DateFormat df = new SimpleDateFormat(pattern);

Date myDate = df.parse("2011-08-12T20:17:46.384Z");

(2) 날짜와 시간을 신경 쓰지 않고 나노 초 단위로 정보를 처리하려는 경우 다음을 사용할 수 있습니다 Instant.

// The ISO format without zone ID is Instant's default.
// There is no need to pass any format.
Instant ins = Instant.parse("2011-08-12T20:17:46.384Z");

1

Android 용 솔루션을 찾고 있다면 다음 코드를 사용하여 타임 스탬프 문자열에서 에포크 초를 얻을 수 있습니다.

public static long timestampToEpochSeconds(String srcTimestamp) {
    long epoch = 0;

    try {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            Instant instant = Instant.parse(srcTimestamp);
            epoch = instant.getEpochSecond();
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSSSS'Z'", Locale.getDefault());
            sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
            Date date = sdf.parse(srcTimestamp);
            if (date != null) {
                epoch = date.getTime() / 1000;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    return epoch;
}

샘플 입력 : 2019-10-15T05 : 51 : 31.537979Z

샘플 출력 : 1571128673


0

다음 예제를 사용할 수 있습니다.

    String date = "2011-08-12T20:17:46.384Z";

    String inputPattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";

    String outputPattern = "yyyy-MM-dd HH:mm:ss";

    LocalDateTime inputDate = null;
    String outputDate = null;


    DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern(inputPattern, Locale.ENGLISH);
    DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern(outputPattern, Locale.ENGLISH);

    inputDate = LocalDateTime.parse(date, inputFormatter);
    outputDate = outputFormatter.format(inputDate);

    System.out.println("inputDate: " + inputDate);
    System.out.println("outputDate: " + outputDate);

에 아포스트로피를 두어서는 안됩니다 Z. 그것은 그 편지를 기대하지만 무시한다는 의미입니다. 그러나 그 편지는 무시해서는 안됩니다. 이 문자는 문자열이 UTC를 의도 한 값 (0의 오프셋)이라는 중요한 정보를 제공합니다. 당신의 형식은이 중요한 사실을 버리고 있습니다. 또한이 서식 패턴을 정의 할 필요도 없습니다. 이 패턴의 포맷터가 내장되어 있습니다.
Basil Bourque

-1

이 기술은 java.util.Date를 UTC 형식 (또는 다른 형식)으로 변환 한 후 다시 변환합니다.

다음과 같이 클래스를 정의하십시오.

import java.util.Date;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class UtcUtility {

public static DateTimeFormatter UTC = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withZoneUTC();


public static Date parse(DateTimeFormatter dateTimeFormatter, String date) {
    return dateTimeFormatter.parseDateTime(date).toDate();
}

public static String format(DateTimeFormatter dateTimeFormatter, Date date) {
    return format(dateTimeFormatter, date.getTime());
}

private static String format(DateTimeFormatter dateTimeFormatter, long timeInMillis) {
    DateTime dateTime = new DateTime(timeInMillis);
    String formattedString = dateTimeFormatter.print(dateTime);
    return formattedString;
}

}

그런 다음 다음과 같이 사용하십시오.

Date date = format(UTC, "2020-04-19T00:30:07.000Z")

또는

String date = parse(UTC, new Date())

필요한 경우 UTC뿐만 아니라 다른 날짜 형식을 정의 할 수도 있습니다.


모두 java.util.DateJoda 타임 프로젝트는 현대에 의해 년 전 대체되었다 java.time의 JSR 310 여기 긴 구식이되는 조언에 정의 된 클래스.
Basil Bourque

java.time은 Java 8에서 도입되었습니다.이 질문은 특히 Java 1.4를 참조하므로 새로운 클래스의 사용을 의도적으로 피했습니다. 이 솔루션은 오래된 코드 기반을 충족시킵니다. 필자는 저자가 코드베이스를 Java 8로 옮길 수 있다고 생각하지만 항상 간단하거나 효율적이거나 필요한 것은 아닙니다.
Gapmeister66.

-1

@ John-Skeet은 나 에게이 문제를 해결할 수있는 단서를주었습니다. 젊은 프로그래머라면이 작은 문제는 놓치기 쉽고 진단하기가 어렵습니다. 그래서 나는 누군가에게 도움이되기를 바랍니다.

내 문제는 JSON에서 타임 스탬프를 금하는 다음 문자열을 구문 분석하고 아무런 영향을 미치지 않고 더 유용한 변수에 넣기를 원했습니다. 그러나 계속 오류가 발생했습니다.

따라서 다음을 고려하십시오 (ofPattern () 내부의 문자열 매개 변수에주의하십시오.

String str = "20190927T182730.000Z"

LocalDateTime fin;
fin = LocalDateTime.parse( str, DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss.SSSZ") );

오류:

Exception in thread "main" java.time.format.DateTimeParseException: Text 
'20190927T182730.000Z' could not be parsed at index 19

문제? 패턴 끝의 Z는 'T'와 마찬가지로 'Z'로 싸야합니다. 변경 "yyyyMMdd'T'HHmmss.SSSZ""yyyyMMdd'T'HHmmss.SSS'Z'"하고 그것을 작동합니다.

패턴에서 Z를 제거하면 오류가 발생했습니다.

솔직히 Java 클래스가 이것을 기대했을 것입니다.


1
이것은 이미 여기여기 에 묻고 대답되었습니다 . 그리고 당신의 해결책은 잘못되었습니다. 반면 T리터럴을하고 인용 할 필요가 Z는 (제로의) 오프셋과 요구 같은 구문 분석하는 것입니다, 또는 당신은 잘못된 결과를 얻을 수 있습니다. 나는 당신이 그것이 예상되지 않았다는 것이 무엇을 의미하는지 모르겠습니다.
Ole VV

1
아니요, 아니요, 아니요를 무시하지 마십시오 Z. 귀중한 정보를 버리고 있습니다. 시간대 또는 UTC에서 오프셋을 무시하면서 날짜-시간 값을 처리하는 것은 통화를 무시하면서 금액을 처리하는 것과 같습니다!
Basil Bourque

1
T단지 시간의 일 부분에서 날짜 부분을 분리하고, 의미를 추가하지 않습니다. Z반면에 확실히 의미를 추가합니다.
Basil Bourque

올레, 링크 주셔서 감사합니다. 분명히 읽을 것입니다. 그리고 나는 확실히 젊은이로서 잘못 될 수 있음을 받아들입니다. 모든 Im은 패턴의 문자처럼 Z를 작은 따옴표로 묶는 것이 오류를 해결했다고 말합니다. 나는 수업의 "패턴"부분을 디자인 한 사람이 'Z'(또는 다른 시간대?)와 'T'의 존재 유무에 대해 코딩 할 수 있었는지 여부에 대해 비판했다. 그들은 독특하지 않았기 때문에. Im 처리 형식은 JSON에서 문자열로 구문 분석 된 상용 API에서 온 것입니다. 그러나 그것들을 더 유용하게 만들기 위해 모든 것을 날짜 시간 달력 등으로 구문 분석해야합니다.
spencemw
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.