이 날짜 형식은 무엇입니까? 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
우리는 왜 작은 따옴표 주위 필요합니까 T와 Z?
— 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의 의미는 동일하므로 UTC 를 Z로 변경하면 유효한 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.Date와 Joda 타임 프로젝트는 현대에 의해 년 전 대체되었다 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.