【问题标题】:What does NNN mean in date format <YYMMDDhhmmssNNN><C|D|G|H>?NNN 在日期格式 <YYMMDDhhmmssNNN><C|D|G|H> 中是什么意思?
【发布时间】:2021-12-23 17:26:18
【问题描述】:

嗨,我有日期格式,我想转换为正确的 GMT 日期:

该日期的样本值: 210204215026000C

我得到 NNN 部分的解释:

NNN     If flag is C or D then NNN is the number of hours relativeto GMT,
        if flag is G or H, NNN is the number of quarter hours relative to GMT
C|D|G|H C and G = Ahead of GMT, D and H = Behind GMT

但我不知道相对于 GMT 的小时数如何以 3 位数字显示?它应该是 2 位数,因为我知道与 GMT 相关的小时数的偏移量是从 0 到 23,以及相对于 GMT 的四分之一小时是什么意思?

我想使用 Scala 或 Java。

【问题讨论】:

  • 格林威治标准时间偏移量可能是例如 +05:30,所以我猜这是 22 刻钟。但这仍然是最多两位数。

标签: datetime gmt


【解决方案1】:

我不知道他们为什么要为偏移量留出 3 位数字。我同意你的观点,所有情况下 2 位数就足够了。也许他们只是想非常确定他们永远不会耗尽空间,也许他们甚至做得有点过头了。只要实际值在java.time.ZoneOffset 可以处理的范围内(+/-18 小时),3 位数就不是问题。在您的示例中,NNN000,因此距格林威治标准时间 0 小时,这当然可以且易于处理。

一刻钟就是一刻钟。正如 Salman A 在评论中提到的,格林威治之前 22 刻钟意味着 +05:30 的偏移量,目前在斯里兰卡和印度使用。如果字符串的生产者想使用这个选项,他们可以提供最多 72 个数字(仍然可以轻松地在 2 位以内)。 18 * 4 = 72,所以 18 小时等于 72 刻钟。想象一下 2 位数太少的情况,考虑 25 小时的偏移量。我认为这不现实,另一方面,没有人能保证它永远不会发生。

Java解决方案:如何解析并转换为GMT时间

我正在使用这些常量:

private static final Pattern DATE_PATTERN
        = Pattern.compile("(\\d{12})(\\d{3})(\\w)");
private static final DateTimeFormatter FORMATTER
        = DateTimeFormatter.ofPattern("uuMMddHHmmss");
private static final int SECONDS_IN_A_QUARTER_HOUR
        = Math.toIntExact(Duration.ofHours(1).dividedBy(4).getSeconds());

像这样解析和转换:

    String sampleValue = "210204215026000C";
    Matcher matcher = DATE_PATTERN.matcher(sampleValue);
    if (matcher.matches()) {
        LocalDateTime ldt = LocalDateTime.parse(matcher.group(1), FORMATTER);
        int offsetAmount = Integer.parseInt(matcher.group(2));
        char flag = matcher.group(3).charAt(0);

        // offset amount denotes either hours or quarter hours
        boolean quarterHours = flag == 'G' || flag == 'H';
        boolean negative = flag == 'D' || flag == 'H';
        if (negative) {
            offsetAmount = -offsetAmount;
        }
        ZoneOffset offset = quarterHours
                ? ZoneOffset.ofTotalSeconds(offsetAmount * SECONDS_IN_A_QUARTER_HOUR)
                : ZoneOffset.ofHours(offsetAmount);

        OffsetDateTime dateTime = ldt.atOffset(offset);
        OffsetDateTime gmtDateTime = dateTime.withOffsetSameInstant(ZoneOffset.UTC);

        System.out.println("GMT time: " + gmtDateTime);
    }
    else {
        System.out.println("Invalid value: " + sampleValue);
    }

输出是:

格林威治标准时间:2021-02-04T21:50:26Z

我认为我的代码涵盖了所有有效的情况。您可能想要验证该标志确实是 C、D、G 或 H,并且还要处理来自解析和创建 ZoneOffset 的潜在 DateTimeExceptionNumberFormatExceptionNumberFormatException 不应该发生)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-22
    • 2014-03-09
    • 2010-09-11
    • 2013-07-16
    • 2020-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多