java转换自/到asn1 dateTimes

时间:2017-09-26 06:16:08

标签: java utc

在我的框架中,我需要转换为Java日期和ASN1 UTC时间(广义时间)。我尝试过SimpleDateFormat和OffsetDateTime。是否有明确的简单方法来获得两个方向? asn1中的字节是字符字节。例如下面,我需要以字节为单位的“YYMMDDhhmmssZ”。

由于第一个答案的变化,解码测试通过以下内容:

@Test
public void testUTCTimeDecode() throws IOException {
    byte[] bytes = new byte[] {48, 55, 48, 51, 50, 50, 49, 53, 53, 56, 49, 55, 90};
    ByteArrayInputStream derStream = new ByteArrayInputStream(bytes);

    Date testDate = new Date(OffsetDateTime.parse("2007-03-22T15:58:17+00:00").toEpochSecond() * 1000);

    byte[] decodeBytes = new byte[bytes.length];
    derStream.read(decodeBytes);

    OffsetDateTime actual = OffsetDateTime.parse(
            new String(decodeBytes),
            DateTimeFormatter.ofPattern("uuMMddHHmmssX"));

    Date date = Date.from(actual.toInstant());
    assertTrue(date.equals(testDate));
}

我仍然遇到编码问题。这是抛出的异常和测试方法:

java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: Year
at java.time.Instant.getLong(Instant.java:603)
at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2540)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2179)
at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1746)
at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1720)
at club.callistohouse.asn1.ASN1TestModel.testUTCTimeEncode(ASN1TestModel.java:47)

以下是我正在使用的测试方法,现在已修复。

    @Test
public void testUTCTimeEncode() throws IOException {
    byte[] bytes = new byte[] {48, 55, 48, 51, 50, 50, 49, 53, 53, 56, 49, 55, 90};
    ByteArrayOutputStream derStream = new ByteArrayOutputStream();

    Date testDate = new Date(OffsetDateTime.parse("2007-03-22T15:58:17+00:00").toEpochSecond() * 1000);

    Instant instant = Instant.ofEpochMilli(testDate.getTime());
    DateTimeFormatter utcFormatter = DateTimeFormatter
               .ofPattern ( "uuMMddHHmmssX" ) 
               .withLocale( Locale.US )
               .withZone( ZoneId.of("UTC"));
    String formattedDate = utcFormatter.format(instant);
    derStream.write(formattedDate.getBytes());
    assertTrue(Arrays.equals(bytes, derStream.toByteArray()));
}

1 个答案:

答案 0 :(得分:2)

TL; DR

    OffsetDateTime expected = OffsetDateTime.of(2007, 3, 22, 15, 58, 17, 0, ZoneOffset.UTC);
    DateTimeFormatter asn1Formatter = DateTimeFormatter.ofPattern("uuMMddHHmmssX");
    OffsetDateTime actual = OffsetDateTime.parse(dateString, asn1Formatter);
    assertEquals(expected, actual);

避免过时的日期和时间类

我建议您避免使用过时的课程DateSimpleDateFormatTimeZone。您已经使用OFfsetDateTime的现代Java日期和时间API可以更好地使用。特别是混合使用这两个API,必然会产生令人困惑的代码。

例如,如果您最终需要一个古老的Date对象用于旧版API,则只需在最后一刻从Instant转换为Date,以最大限度地减少对旧API的使用

您格式化模式字符串

中的错误

格式模式字符串中有两个错误:

  1. 您不能使用大写YY。这是基于周的年份,仅适用于周数。使用小写yyuu,并注意两位数年份将被解释为2000年至2099年。
  2. 格式模式字母Z与区域偏移Z不匹配。请改用格式模式中的X