IT박스

콜론 구분 기호가있는 시간대에 대한 Java SimpleDateFormat?

itboxs 2020. 12. 3. 07:40
반응형

콜론 구분 기호가있는 시간대에 대한 Java SimpleDateFormat?


다음 형식의 날짜가 있습니다. 2010-03-01T00:00:00-08:00

나는 그것을 구문 분석하기 위해 다음 SimpleDateFormats를 던졌습니다.

private static final SimpleDateFormat[] FORMATS = {
        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"), //ISO8601 long RFC822 zone
        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz"), //ISO8601 long long form zone
        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"), //ignore timezone
        new SimpleDateFormat("yyyyMMddHHmmssZ"), //ISO8601 short
        new SimpleDateFormat("yyyyMMddHHmm"),
        new SimpleDateFormat("yyyyMMdd"), //birthdate from NIST IHE C32 sample
        new SimpleDateFormat("yyyyMM"),
        new SimpleDateFormat("yyyy") //just the year
    };

다음과 같은 형식을 사용하는 편리한 방법이 있습니다.

public static Date figureOutTheDamnDate(String wtf) {
    if (wtf == null) {
        return null;
    }
    Date retval = null;
    for (SimpleDateFormat sdf : FORMATS) {
        try {
            sdf.setLenient(false)
            retval = sdf.parse(wtf);
            System.out.println("Date:" + wtf + " hit on pattern:" + sdf.toPattern());
            break;
        } catch (ParseException ex) {
            retval = null;
            continue;
        }
    }

    return retval;
}

패턴에 맞는 것처럼 보이지만 yyyyMMddHHmm날짜를 Thu Dec 03 00:01:00 PST 2009.

이 날짜를 구문 분석하는 올바른 패턴은 무엇입니까?

업데이트 : 시간대 구문 분석이 필요하지 않습니다. 영역간에 이동하는 시간에 민감한 문제가있을 것으로 예상하지 않지만 "-08 : 00"영역 형식을 구문 분석하려면 어떻게해야합니까 ????

단위 테스트 :

@Test
public void test_date_parser() {
    System.out.println("\ntest_date_parser");
    //month is zero based, are you effing kidding me
    Calendar d = new GregorianCalendar(2000, 3, 6, 13, 00, 00);
    assertEquals(d.getTime(), MyClass.figureOutTheDamnDate("200004061300"));
    assertEquals(new GregorianCalendar(1950, 0, 1).getTime(), MyClass.figureOutTheDamnDate("1950"));
    assertEquals(new GregorianCalendar(1997, 0, 1).getTime(),  MyClass.figureOutTheDamnDate("199701"));
    assertEquals(new GregorianCalendar(2010, 1, 25, 15, 19, 44).getTime(),   MyClass.figureOutTheDamnDate("20100225151944-0800"));

    //my machine happens to be in GMT-0800
    assertEquals(new GregorianCalendar(2010, 1, 15, 13, 15, 00).getTime(),MyClass.figureOutTheDamnDate("2010-02-15T13:15:00-05:00"));
    assertEquals(new GregorianCalendar(2010, 1, 15, 18, 15, 00).getTime(), MyClass.figureOutTheDamnDate("2010-02-15T18:15:00-05:00"));

    assertEquals(new GregorianCalendar(2010, 2, 1).getTime(), MyClass.figureOutTheDamnDate("2010-03-01T00:00:00-08:00"));
    assertEquals(new GregorianCalendar(2010, 2, 1, 17, 0, 0).getTime(), MyClass.figureOutTheDamnDate("2010-03-01T17:00:00-05:00"));
}

단위 테스트의 출력 :

test_date_parser
Date:200004061300 hit on pattern:yyyyMMddHHmm
Date:1950 hit on pattern:yyyy
Date:199701 hit on pattern:yyyyMM
Date:20100225151944-0800 hit on pattern:yyyyMMddHHmmssZ
Date:2010-02-15T13:15:00-05:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss
Date:2010-02-15T18:15:00-05:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss
Date:2010-03-01T00:00:00-08:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss
Date:2010-03-01T17:00:00-05:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss

JodaTimeDateTimeFormat구출 :

String dateString = "2010-03-01T00:00:00-08:00";
String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";
DateTimeFormatter dtf = DateTimeFormat.forPattern(pattern);
DateTime dateTime = dtf.parseDateTime(dateString);
System.out.println(dateTime); // 2010-03-01T04:00:00.000-04:00

(시간 및 시간대 차이는 toString()GMT-4에 있고 로케일을 명시 적으로 설정하지 않았기 때문입니다)

java.util.Date그냥 사용 하고 싶다면 DateTime#toDate():

Date date = dateTime.toDate();

기다리 JDK7 ( JSR-310 ) JSR-310 referrence 구현이라고 ThreeTen 당신은 표준 Java SE API의 더 나은 포맷을 원하는 경우 (잘하면 자바 8로를 만들 것입니다). 전류는 SimpleDateFormat실제로 시간대 표기법에서 콜론을 먹지 않습니다.

업데이트 : 업데이트에 따라 분명히 시간대가 필요하지 않습니다. 이것은 SimpleDateFormat. Z패턴에서 생략 ( )하십시오.

String dateString = "2010-03-01T00:00:00-08:00";
String pattern = "yyyy-MM-dd'T'HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
Date date = sdf.parse(dateString);
System.out.println(date); // Mon Mar 01 00:00:00 BOT 2010

(내 시간대에 따라 정확함)


Java 7을 사용한 경우 다음 날짜 시간 패턴을 사용할 수 있습니다. 이 패턴은 Java의 이전 버전에서 지원되지 않는 것 같습니다.

String dateTimeString  = "2010-03-01T00:00:00-08:00";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
Date date = df.parse(dateTimeString);

자세한 내용은을 참조 SimpleDateFormat문서 .


다음은 내가 사용한 스 니펫 SimpleDateFormat입니다. 다른 사람이 혜택을 누릴 수 있기를 바랍니다.

public static void main(String[] args) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") {
        public StringBuffer format(Date date, StringBuffer toAppendTo, java.text.FieldPosition pos) {
            StringBuffer toFix = super.format(date, toAppendTo, pos);
            return toFix.insert(toFix.length()-2, ':');
        };
    };
    // Usage:
    System.out.println(dateFormat.format(new Date()));
}

산출:

- Usual Output.........: 2013-06-14T10:54:07-0200
- This snippet's Output: 2013-06-14T10:54:07-02:00

또는 ... 더 간단하고 다른 패턴을 사용하는 것이 좋습니다.

SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
// Usage:
System.out.println(dateFormat2.format(new Date()));

산출:

- This pattern's output: 2013-06-14T10:54:07-02:00

이에 대한 문서를 참조하십시오 .


이것을 시도해보십시오.

Date date = javax.xml.bind.DatatypeConverter.parseDateTime("2013-06-01T12:45:01+04:00").getTime();

Java 8에서

OffsetDateTime dt = OffsetDateTime.parse("2010-03-01T00:00:00-08:00");

JDK 1.7 이상을 사용할 수 있으면 다음을 시도하십시오.

public class DateUtil {
    private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");

    public static String format(Date date) {
        return dateFormat.format(date);
    }

    public static Date parse(String dateString) throws AquariusException {
        try {
            return dateFormat.parse(dateString);
        } catch (ParseException e) {
            throw new AquariusException(e);
        }
    }
}

문서 : https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html 은 새로운 시간대 형식 "XXX"(예 : -3 : 00)를 지원합니다.

JDK 1.6은 "z"(예 : NZST), "zzzz"(예 : 뉴질랜드 표준시), "Z"(예 : +1200) 등의 다른 시간대 형식 만 지원합니다.


tl; dr

OffsetDateTime.parse( "2010-03-01T00:00:00-08:00" )

세부

BalusC대답 은 정확하지만 이제 Java 8에서 구식입니다.

java.time

java.time의 프레임 워크는 모두 Joda 타임 라이브러리의 후속와 자바 (java.util.Date/.Calendar & java.text.SimpleDateFormat에)의 초기 버전에 번들로 이전 번잡 한 날짜 - 시간 수업입니다.

ISO 8601

입력 데이터 문자열은 ISO 8601 표준 을 준수 합니다.

java.time 클래스는 날짜-시간 값의 텍스트 표현을 구문 분석 / 생성 할 때 기본적으로 ISO 8601 형식을 사용합니다. 따라서 형식화 패턴을 정의 할 필요가 없습니다.

OffsetDateTime

OffsetDateTime클래스는 어떤 특별한 조정 타임 라인에 순간을 나타내는 오프셋에서-UTC . 입력에서 오프셋은 일반적으로 북미 서부 해안의 대부분에서 사용되는 UTC보다 8 시간 늦습니다.

OffsetDateTime odt = OffsetDateTime.parse( "2010-03-01T00:00:00-08:00" );

날짜 만 원하는 것 같으며이 경우 LocalDate클래스를 사용합니다 . 그러나 데이터, (a) 시간 및 (b) 시간대를 삭제한다는 점을 명심하십시오. 실제로 날짜는 시간대의 컨텍스트 없이는 의미가 없습니다 . 주어진 순간에 날짜는 전 세계적으로 다릅니다. 예를 들어 파리의 자정 직후는 몬트리올에서 여전히 "어제"입니다. 따라서 날짜-시간 값을 고수하는 것이 좋지만 원하는 LocalDate경우 쉽게 변환 할 수 있습니다 .

LocalDate localDate = odt.toLocalDate();

시간대

원하는 시간대를 알고 있으면 적용하십시오. 시간대는 오프셋 일광 절약 시간 (DST) 과 같은 예외 사항을 처리하는 데 사용할 규칙 입니다. 을 적용하는 것은 ZoneId우리에게 도착 ZonedDateTime개체를.

ZoneId zoneId = ZoneId.of( "America/Los_Angeles" );
ZonedDateTime zdt = odt.atZoneSameInstant( zoneId );

문자열 생성

ISO 8601 형식의 문자열을 생성하려면 toString.

String output = odt.toString();

다른 형식의 문자열이 필요한 경우 java.util.format 패키지 사용을 위해 Stack Overflow를 검색하십시오 .

다음으로 변환 java.util.Date

피하는 java.util.Date것이 가장 좋지만 필요한 경우 변환 할 수 있습니다. java.util.Date.from를 전달하는 위치 와 같이 이전 클래스에 추가 된 새 메서드를 호출합니다 Instant. An InstantUTC 의 타임 라인에있는 순간입니다 . 우리는 Instant우리의 OffsetDateTime.

java.util.Date utilDate = java.util.Date( odt.toInstant() );

java.time 정보

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

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

자세한 내용은 Oracle Tutorial을 참조하십시오 . 그리고 많은 예제와 설명을 위해 Stack Overflow를 검색하십시오. 사양은 JSR 310 입니다.

java.time 객체를 데이터베이스와 직접 교환 할 수 있습니다 . JDBC 4.2 이상을 준수 하는 JDBC 드라이버를 사용하십시오 . 문자열이나 클래스 가 필요하지 않습니다 .java.sql.*

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

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


Thanks acdcjunior for your solution. Here's a little optimized version for formatting and parsing :

public static final SimpleDateFormat XML_SDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.FRANCE)
{
    private static final long serialVersionUID = -8275126788734707527L;

    public StringBuffer format(Date date, StringBuffer toAppendTo, java.text.FieldPosition pos)
    {            
        final StringBuffer buf = super.format(date, toAppendTo, pos);
        buf.insert(buf.length() - 2, ':');
        return buf;
    };

    public Date parse(String source) throws java.text.ParseException {
        final int split = source.length() - 2;
        return super.parse(source.substring(0, split - 1) + source.substring(split)); // replace ":" du TimeZone
    };
};

You can use X in Java 7.

https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

static final SimpleDateFormat DATE_TIME_FORMAT = 
        new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

static final SimpleDateFormat JSON_DATE_TIME_FORMAT = 
        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");

private String stringDate = "2016-12-01 22:05:30";
private String requiredDate = "2016-12-01T22:05:30+03:00";

@Test
public void parseDateToBinBankFormat() throws ParseException {
    Date date = DATE_TIME_FORMAT.parse(stringDate);
    String jsonDate = JSON_DATE_TIME_FORMAT.format(date);

    System.out.println(jsonDate);
    Assert.assertEquals(jsonDate, requiredDate);
}

Try setLenient(false).

Addendum: It looks like you're recognizing variously formatted Date strings. If you have to do entry, you might like looking at this example that extends InputVerifier.


Since an example of Apache FastDateFormat(click for the documentations of versions:2.6and3.5) is missing here, I am adding one for those who may need it. The key here is the pattern ZZ(2 capital Zs).

import java.text.ParseException
import java.util.Date;
import org.apache.commons.lang3.time.FastDateFormat;
public class DateFormatTest throws ParseException {
    public static void main(String[] args) {
        String stringDateFormat = "yyyy-MM-dd'T'HH:mm:ssZZ";
        FastDateFormat fastDateFormat = FastDateFormat.getInstance(stringDateFormat);
        System.out.println("Date formatted into String:");
        System.out.println(fastDateFormat.format(new Date()));
        String stringFormattedDate = "2016-11-22T14:30:14+05:30";
        System.out.println("String parsed into Date:");
        System.out.println(fastDateFormat.parse(stringFormattedDate));
    }
}

Here is the output of the code:

Date formatted into String:
2016-11-22T14:52:17+05:30
String parsed into Date:
Tue Nov 22 14:30:14 IST 2016

Note: The above code is of Apache Commons' lang3. The class org.apache.commons.lang.time.FastDateFormat does not support parsing, and it supports only formatting. For example, the output of the following code:

import java.text.ParseException;
import java.util.Date;
import org.apache.commons.lang.time.FastDateFormat;
public class DateFormatTest {
    public static void main(String[] args) throws ParseException {
        String stringDateFormat = "yyyy-MM-dd'T'HH:mm:ssZZ";
        FastDateFormat fastDateFormat = FastDateFormat.getInstance(stringDateFormat);
        System.out.println("Date formatted into String:");
        System.out.println(fastDateFormat.format(new Date()));
        String stringFormattedDate = "2016-11-22T14:30:14+05:30";
        System.out.println("String parsed into Date:");
        System.out.println(fastDateFormat.parseObject(stringFormattedDate));
    }
}

will be this:

Date formatted into String:
2016-11-22T14:55:56+05:30
String parsed into Date:
Exception in thread "main" java.text.ParseException: Format.parseObject(String) failed
    at java.text.Format.parseObject(Format.java:228)
    at DateFormatTest.main(DateFormatTest.java:12)

If date string is like 2018-07-20T12:18:29.802Z Use this

SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

참고URL : https://stackoverflow.com/questions/2375222/java-simpledateformat-for-time-zone-with-a-colon-separator

반응형