日期格式<YYMMDDhhmmssNNN><C|D|G|H>中NNN含义及转GMT方案
疑问解答
1. 为什么用3位NNN存储偏移量
- 统一字段长度:不管是小时偏移还是15分钟偏移的场景,字段长度固定为3位,不需要处理可变长度解析,大幅降低逻辑复杂度和出错概率。
- 兼容扩展:3位长度可以覆盖更大的偏移范围,哪怕后续出现非常规时区偏移需求也可以兼容,同时前导零的存在也避免了数据截断导致的解析错误。
2. 「number of quarter hours relative to GMT」的含义
1个quarter hour就是15分钟,该含义是指相对于GMT的偏移量以15分钟为单位计数,比如偏移+8小时对应8*4=32个季度小时,偏移+5小时30分钟对应5*4 + 2=22个季度小时,这种设计可以支持非整小时的时区偏移。
转换实现方案
注:示例中两位年默认按2000+解析,如有19xx的年份需求,可调整DateTimeFormatter的年份映射规则
Java 8+ 实现
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class SpecialDateConverter { private static final DateTimeFormatter LOCAL_DT_FORMAT = DateTimeFormatter.ofPattern("yyMMddHHmmss"); public static LocalDateTime convertToGmt(String specialDateStr) { // 拆分输入字段 String localDtPart = specialDateStr.substring(0, 12); int nnn = Integer.parseInt(specialDateStr.substring(12, 15)); char flag = specialDateStr.charAt(15); // 解析本地日期时间 LocalDateTime localDt = LocalDateTime.parse(localDtPart, LOCAL_DT_FORMAT); // 计算偏移总秒数 int offsetSeconds; if (flag == 'C' || flag == 'D') { offsetSeconds = nnn * 3600; // 单位为小时 } else if (flag == 'G' || flag == 'H') { offsetSeconds = nnn * 900; // 单位为15分钟 } else { throw new IllegalArgumentException("无效标志位:" + flag); } // 按方向调整得到GMT时间 if (flag == 'C' || flag == 'G') { // 本地时间领先GMT,GMT=本地时间-偏移量 return localDt.minusSeconds(offsetSeconds); } else { // 本地时间落后GMT,GMT=本地时间+偏移量 return localDt.plusSeconds(offsetSeconds); } } public static void main(String[] args) { // 测试示例输入 System.out.println(convertToGmt("210204215026000C")); // 输出:2021-02-04T21:50:26 } }
Scala 实现
import java.time.LocalDateTime import java.time.format.DateTimeFormatter object SpecialDateConverter { private val localDtFormat: DateTimeFormatter = DateTimeFormatter.ofPattern("yyMMddHHmmss") def convertToGmt(specialDateStr: String): LocalDateTime = { val localDtPart = specialDateStr.take(12) val nnn = specialDateStr.slice(12, 15).toInt val flag = specialDateStr.charAt(15) val localDt = LocalDateTime.parse(localDtPart, localDtFormat) val offsetSeconds = flag match { case 'C' | 'D' => nnn * 3600 case 'G' | 'H' => nnn * 900 case _ => throw new IllegalArgumentException(s"无效标志位:$flag") } if (flag == 'C' || flag == 'G') localDt.minusSeconds(offsetSeconds) else localDt.plusSeconds(offsetSeconds) } def main(args: Array[String]): Unit = { // 测试示例输入 println(convertToGmt("210204215026000C")) // 输出:2021-02-04T21:50:26 } }
内容的提问来源于stack exchange,提问作者code
相关产品推荐
相关产品推荐

