如何使用 Retrofit 将使用 Z 和 T 格式化的日期发送到 API?

How to send Date formatted with Z and T to an API using Retrofit?

我的 API -

有以下示例路径

base_url/path/{country}/path/path?from=2020-03-01T00:00:00Z&to=2020-03-02T00:00:00Z

所以我需要使用 Z 和 T 格式传递 2 个 Date 对象,但我真的不知道如何将新的 Kotlin Date() 对象格式化为这些 Z 和 T 格式。

我目前的get方法-

@GET("path/{country}/path/path/")
    suspend fun getCountryModelByDate(
        @Path("country") country: String,
        @Query("from") from : String,
        @Query("to") to : String
    ): Model

但是当我尝试像下面这样测试我的方法时 -

class RemoteDataSource(private val api: Api) {

    suspend fun getCountryModelByDate(): Resource<Model> {
        return try {
            Resource.Success(coronaVirusApi.getCovidDeathsByDeathFromCountry("italy", Date().toString(), Date().toString()))
        } catch (exception: Exception) {
            Resource.Exception(exception)
        }
    }

}

这导致我收到以下 404 错误,请查看正在发送的 URL -

Response{protocol=h2, code=404, message=, url=https://api.covid19api.com/country/italy/status/deaths/?from=Tue%20Nov%2017%2010%3A47%3A30%20GMT%2B02%3A00%202020&to=Tue%20Nov%2017%2010%3A47%3A30%20GMT%2B02%3A00%202020}

所以我的问题是 -

  1. 如何将 Kotlin Date 对象格式化为 Z 和 T 格式,就像我 API 需要的那样?
  2. 如何将格式化的日期发送到我的查询中而不被乱码?

Instant.toString() 来自 java.time

您的 TZ 格式是 ISO 8601。您可能需要参考底部的 link。 java.time 的 classes,现代 Java 日期和时间 API,通过其 toString 方法生成 ISO 8601。使用 Instant class。 Java中的简要演示:

    Instant i = Instant.now();
    System.out.println(i);

示例输出:

2020-11-18T09:31:33.613965Z

如果 Instant 像您一样在 UTC 中落在午夜,输出将类似于:

2020-11-18T00:00:00Z

在第一种情况下,秒上存在小数点对于您的 API 可能不是问题,因为根据 ISO 8601 标准,分数是可选的。如果您想摆脱它,最简单的方法是截断 Instant:

    Instant instantToPrint = i.truncatedTo(ChronoUnit.SECONDS);
    System.out.println(instantToPrint);

2020-11-18T09:31:33Z

How can I make the instant object always return T00:00:00Z as this is what my API requires?

编辑:鉴于您已经有一个时间正好落在所需的 UTC 日期,只需截断为整天即可:

    Instant instantToPrint = i.truncatedTo(ChronoUnit.DAYS);

2020-11-18T00:00:00Z

不过,问题是你的约会对象来自哪里。在日历中使用 java.time 一天将由 LocalDate 表示,因此我们需要转换。

    LocalDate fromDate = LocalDate.of(2020, Month.MARCH, 1);
    Instant fromDateTimeUtc = fromDate.atStartOfDay(ZoneOffset.UTC).toInstant();
    System.out.println(fromDateTimeUtc);

2020-03-01T00:00:00Z

  1. How can I send the formatted date into my query without it being gibrished out?

我认为 URL 中的冒号需要进行 URL 编码(协议后面的冒号除外,https:// 中的冒号除外)。所以应该变成%3AInstant 中的其余字符串应该清晰易读。

链接