Android中使用SimpleDateFormat解析带时区日期字符串的问题
正确解析带时区偏移的日期字符串到Date类型
首先,你的代码里有个关键问题:SimpleDateFormat的Z模式匹配的是不带冒号的时区格式(比如+1100),但你要解析的字符串时区部分是+11:00(带冒号),直接用Z会导致解析失败。另外,SimpleDateFormat是线程不安全的,在多线程场景下容易出问题,更推荐使用Java 8及以上的java.time新日期API。下面给你两种解决方案:
方案一:修复SimpleDateFormat的用法
如果因为项目限制必须使用SimpleDateFormat,把格式模式里的Z改成XXX,XXX专门匹配带冒号的时区偏移格式(比如+11:00):
public Resident(String address, String dob, String email, String postcode, String firstname, String surname, String provider, String familynumber) { this.address = address; // 用XXX匹配带冒号的时区 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); try { String fullDobStr = dob + "T00:00:00+11:00"; Date parsedDate = sdf.parse(fullDobStr); // 把解析后的Date赋值给类的对应字段 this.dob = parsedDate; } catch (ParseException e) { // 这里可以根据业务需求处理异常,比如打印日志、设置默认值或抛出业务异常 e.printStackTrace(); } }
⚠️ 注意:SimpleDateFormat是非线程安全的,不要把它定义为静态变量或者在多线程环境下共享同一个实例,最好每次使用时创建新实例,或者用ThreadLocal来维护实例。
方案二:使用Java 8+的java.time API(强烈推荐)
java.time包是Java 8引入的新日期时间API,解决了旧API的线程安全问题,而且设计更合理,能更好地处理时区和日期时间信息。我们可以用OffsetDateTime来解析带时区偏移的字符串,若需要兼容旧代码的Date类型,也可以轻松转换:
import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; public Resident(String address, String dob, String email, String postcode, String firstname, String surname, String provider, String familynumber) { this.address = address; // 定义全局可复用的DateTimeFormatter(线程安全) DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX"); try { String fullDobStr = dob + "T00:00:00+11:00"; // 解析成带时区偏移的OffsetDateTime OffsetDateTime offsetDateTime = OffsetDateTime.parse(fullDobStr, formatter); // 如果需要转换成java.util.Date(兼容旧逻辑) Date parsedDate = Date.from(offsetDateTime.toInstant()); this.dob = parsedDate; // 更推荐的做法:直接存储OffsetDateTime,它能保留时区偏移信息,而Date只是一个时间戳 // this.dobDateTime = offsetDateTime; } catch (Exception e) { e.printStackTrace(); // 自定义异常处理逻辑 } }
额外优化
DateTimeFormatter是线程安全的,可以把它定义为类的静态常量,避免每次创建实例浪费资源:
private static final DateTimeFormatter DOB_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
内容的提问来源于stack exchange,提问作者Damon
相关产品推荐
相关产品推荐

