如何使用Scala的f插值器格式化Java LocalDate?
实现Scala f插值器支持LocalDate格式化
方法一:自定义日期插值器
如果想贴近你最初设想的$dt:YYYY-MM-dd语法,可以创建一个自定义插值器,专门处理LocalDate的格式化:
import java.time.LocalDate import java.time.format.DateTimeFormatter object DateInterpolator { implicit class DateStringContext(sc: StringContext) { def date(args: Any*): String = { sc.parts.zip(args).map { case (part, dt: LocalDate) => // 提取part末尾的日期格式模式 val patternMatch = """:([YMD]+(?:[-/][YMD]+)*)$""".r.findFirstMatchIn(part) patternMatch match { case Some(m) => val pattern = m.group(1) part.replace(s":$pattern", dt.format(DateTimeFormatter.ofPattern(pattern))) case None => part + dt.toString } case (part, arg) => part + arg.toString }.mkString + sc.parts.last } } } // 使用示例 import DateInterpolator._ val dt = LocalDate.of(2024,7,28) println(date"今天的日期是$dt:YYYY-MM-dd,明天是${dt.plusDays(1)}:MM/dd/yyyy") // 输出:今天的日期是2024-07-28,明天是07/29/2024
方法二:扩展原生f插值器
如果想直接复用原生f插值器的语法,只需为LocalDate提供一个隐式的StringFormat实例,让f插值器能识别日期格式说明符:
import java.time.LocalDate import java.time.format.DateTimeFormatter import scala.util.StringFormat // 定义LocalDate的隐式格式化规则 implicit object LocalDateStringFormat extends StringFormat[LocalDate] { override def format(value: LocalDate, spec: String): String = { // 清理格式说明符,去除f插值器的位置标记等冗余内容 val cleanPattern = spec.replaceAll("""^\d+\$""", "").trim value.format(DateTimeFormatter.ofPattern(cleanPattern)) } } // 使用示例 val dt = LocalDate.of(2024,7,28) println(f"标准格式日期:$dt%YYYY-MM-dd") println(f"短格式日期:$dt%MM/dd/yy") // 输出: // 标准格式日期:2024-07-28 // 短格式日期:07/28/24
说明
- 自定义插值器的语法更贴近你最初的需求,但需要使用
date关键字替代原生的f; - 扩展原生f插值器的方式无需改变插值器关键字,只需遵循
$dt%格式的语法即可。
内容的提问来源于stack exchange,提问作者David Regan
相关产品推荐
相关产品推荐

