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

Android Retrofit:URL传递DateTime时的日期格式问题

解决Retrofit中URL路径参数日期格式问题

问题核心

Gson的setDateFormat仅负责JSON数据的序列化/反序列化,而URL路径中的@Path参数是独立处理的,因此直接配置Gson对路径里的日期参数完全无效。

方案一:使用Java 8+时间API(推荐)

Java原生Date类已过时,建议改用java.time.LocalDateTime(需时区则用ZonedDateTime),配合自定义转换器处理路径参数格式化:

  1. 替换API接口中的日期类型
@POST("api/updateStarted/{id}/{started}")
suspend fun updateStarted(
    @Path("id") id: Int,
    @Path("started", encoded = false) started: LocalDateTime
): Response<Int>

必须加上encoded = false,避免Retrofit自动转义我们已格式化好的日期字符串

  1. 编写自定义路径转换器
    创建Converter.Factory实现LocalDateTime到目标格式字符串的转换:
class LocalDateTimePathConverter : Converter.Factory() {
    private val dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")

    override fun stringConverter(
        type: Type,
        annotations: Array<Annotation>,
        retrofit: Retrofit
    ): Converter<*, String>? {
        return if (type == LocalDateTime::class.java) {
            Converter { value ->
                (value as LocalDateTime).format(dateFormatter)
            }
        } else null
    }
}
  1. 配置Retrofit并添加转换器
    注意删除你代码中重复添加的GsonConverterFactory.create()(会覆盖之前的日期格式配置):
val gson = GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss").create()

val apiClient: ApiClient = Retrofit.Builder()
    .addConverterFactory(GsonConverterFactory.create(gson))
    .addConverterFactory(LocalDateTimePathConverter()) // 添加上自定义路径转换器
    .baseUrl(API_BASE_URL)
    .client(getHttpClient(API_USERNAME, API_PASSWORD))
    .build()
    .create(ApiClient::class.java)

方案二:继续使用Date类(不推荐)

如果必须保留Date类型,同样需要自定义路径转换器:

  1. 修改API接口
@POST("api/updateStarted/{id}/{started}")
suspend fun updateStarted(
    @Path("id") id: Int,
    @Path("started", encoded = false) started: Date
): Response<Int>
  1. 编写Date转字符串的转换器
class DatePathConverter : Converter.Factory() {
    private val dateFormatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US)

    override fun stringConverter(
        type: Type,
        annotations: Array<Annotation>,
        retrofit: Retrofit
    ): Converter<*, String>? {
        return if (type == Date::class.java) {
            Converter { value ->
                dateFormatter.format(value as Date)
            }
        } else null
    }
}
  1. 添加到Retrofit构建器
    和方案一一致,将自定义转换器加入Retrofit配置,同时清理重复的Gson转换器配置。

额外注意事项

  • 若需要带时区的日期格式(如2023-01-28T02:03:04+08:00),方案一可改用ZonedDateTime并调整格式化模板;方案二则为SimpleDateFormat设置对应时区。
  • 务必确保@Path参数的encoded = false配置,否则Retrofit会将日期中的T、:等字符转义为URL编码,导致格式不符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:30:41