转换UTC字符串为HH:mm格式时抛出Unparseable Date错误求助
解决UTC时间戳转HH:mm格式时的Unparseable Date错误
嘿,我来帮你搞定这个日期格式化的问题!你的核心问题在于多做了一步没必要的字符串解析操作,而且解析时用的格式和Date.toString()的输出格式不匹配,才导致了Unparseable Date错误。下面给你详细分析和解决方案:
问题根源
你通过new Date(Long.parseLong(sunrise)*1000)得到了正确的Date对象,但之后把Date.toString()的输出(比如"Thu Mar 22 05:5...")拿去解析成HH:mm格式。这个字符串的完整格式是EEE MMM dd HH:mm:ss zzz yyyy(比如"Thu Mar 22 05:57:12 GMT 2018"),如果你的解析器没有匹配这个完整格式,就会抛出解析错误。而且这一步完全是多余的——我们可以直接从Date对象或原始时间戳生成HH:mm格式,根本不需要先转成字符串再解析。
推荐解决方案:直接格式化Date/时间戳
方式1:Java 8+ 推荐使用DateTimeFormatter(线程安全)
这是现在Java处理日期的首选方式,线程安全且API更清晰:
// 从原始UTC时间戳直接转换(推荐,少一步Date对象转换) long sunriseTimestamp = 1521698232L; Instant instant = Instant.ofEpochSecond(sunriseTimestamp); // 指定时区为UTC,避免本地时区干扰 DateTimeFormatter hhmmFormatter = DateTimeFormatter.ofPattern("HH:mm") .withZone(ZoneId.of("UTC")); String sunriseHHmm = hhmmFormatter.format(instant); System.out.println(sunriseHHmm); // 输出:05:57
如果已经有了Date对象,也可以直接转换:
Date setSunrise = new Date(Long.parseLong("1521698232") * 1000); Instant instant = setSunrise.toInstant(); DateTimeFormatter hhmmFormatter = DateTimeFormatter.ofPattern("HH:mm") .withZone(ZoneId.of("UTC")); String sunriseHHmm = hhmmFormatter.format(instant);
方式2:传统SimpleDateFormat(注意非线程安全)
如果你还在使用Java 8之前的版本,可以用SimpleDateFormat,但要注意它不是线程安全的,不要在多线程环境下共享实例:
Date setSunrise = new Date(Long.parseLong("1521698232") * 1000); SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); // 必须指定时区为UTC,否则会默认使用本地时区,导致时间偏差 sdf.setTimeZone(TimeZone.getTimeZone("UTC")); String sunriseHHmm = sdf.format(setSunrise); System.out.println(sunriseHHmm); // 输出:05:57
不推荐但可行:解析Date.toString()的字符串
如果你一定要处理那个setString,必须先匹配它的完整格式解析成Date,再格式化:
String setString = "Thu Mar 22 05:57:12 GMT 2018"; // 匹配Date.toString()的完整格式,必须指定英文Locale避免解析失败 SimpleDateFormat parseFormatter = new SimpleDateFormat( "EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH ); Date date = parseFormatter.parse(setString); // 再格式化为HH:mm SimpleDateFormat formatFormatter = new SimpleDateFormat("HH:mm"); formatFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); String sunriseHHmm = formatFormatter.format(date);
这种方式多了一次解析操作,效率更低,还容易因为Locale或时区问题出错,所以非常不推荐。
内容的提问来源于stack exchange,提问作者JoeBoggs
相关产品推荐
相关产品推荐

