You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决字符串转指定格式Date类型时的格式回退问题?

问题核心:Date对象本身不存储格式信息

兄弟,你这里的关键误解是:Date类型本身根本不保存任何格式信息——它本质上只是一个代表时间点的数字(从1970-01-01 00:00:00 UTC开始的毫秒数)。你看到的"EEE MMM dd hh:mm:ss zzz yyyy"格式,只是调用Date.toString()时JVM默认输出的格式化字符串,并不是Date对象的“格式”。

你之前的操作:解析成Date→格式化为字符串→再解析回Date,其实是在做无用功——第二次解析得到的Date还是原来的时间点,只是toString()默认输出了那个长格式而已。


正确的解决思路

根据你的需求,分两种情况处理:

1. 你需要的是「只保留年月日(时分秒为0)的Date对象」

如果你要的是一个代表当天0点的Date(而非字符串),不需要来回格式化解析,直接解析后把时分秒毫秒清零即可:

import java.util.{Date, Calendar, SimpleDateFormat}

def getDateWithYMDOnly(dateStr: String): Date = {
  val initialDateFormat = new SimpleDateFormat("EEE MMM dd hh:mm:ss zzz yyyy")
  // 先解析原始字符串得到Date
  val parsedDate = initialDateFormat.parse(dateStr)
  
  // 使用Calendar把时分秒毫秒清零,得到当天起始时间的Date
  val calendar = Calendar.getInstance()
  calendar.setTime(parsedDate)
  calendar.set(Calendar.HOUR_OF_DAY, 0) // 24小时制的小时,设为0
  calendar.set(Calendar.MINUTE, 0)
  calendar.set(Calendar.SECOND, 0)
  calendar.set(Calendar.MILLISECOND, 0)
  
  calendar.getTime()
}

使用示例:

val inputDateStr = "Wed Jan 01 14:30:45 GMT 2025"
val targetDate = getDateWithYMDOnly(inputDateStr)

// 如果你需要用yyyy-MM-dd格式展示,只需要格式化它即可
val finalFormatter = new SimpleDateFormat("yyyy-MM-dd")
println(finalFormatter.format(targetDate)) // 输出:2025-01-01

2. 推荐:使用Java 8+的现代日期API(更安全、更清晰)

SimpleDateFormat是线程不安全的,而且设计上有很多缺陷。建议改用Java 8引入的java.time包下的API,比如LocalDate(专门表示年月日的类型,完全符合你的需求):

import java.time.LocalDate
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.util.Locale

def parseToLocalDate(dateStr: String): LocalDate = {
  // 定义原始字符串的格式,注意指定Locale.ENGLISH避免本地化问题
  val initialFormatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH)
  // 解析为带时区的时间,再转换为LocalDate(只保留年月日)
  val zonedTime = ZonedDateTime.parse(dateStr, initialFormatter)
  zonedTime.toLocalDate()
}

使用示例:

val inputDateStr = "Wed Jan 01 14:30:45 GMT 2025"
val localDate = parseToLocalDate(inputDateStr)

// 格式化为目标字符串
val targetFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
println(localDate.format(targetFormatter)) // 输出:2025-01-01

再次强调关键

不管是Date还是LocalDate,它们都只是时间/日期的数据载体,格式是在展示时通过格式化工具生成的字符串。你永远不可能得到一个“自带yyyy-MM-dd格式的Date对象”——格式和对象本身是分离的。

内容的提问来源于stack exchange,提问作者Cassie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:54:34