4

In my android app I use Retrofit 2

@GET("/operations")
    fun getOperationsList(
        @Query("types") typeList: List<@JvmSuppressWildcards OperationType>,
        @Query("status") statusList: List<@JvmSuppressWildcards OperationStatus>,
        @Query("from") from: Date, @Query("to") to: Date
    ): Call<List<Operation>>

And here result http request:

08-06 15:40:17.672 D/OkHttp  ( 2436): --> GET http://my_ip:8081/operations?types=payment&types=payout&status=executed&from=Tue%20Aug%2006%2015%3A40%3A17%20GMT%2B03%3A00%202019&to=Tue%20Aug%2006%2015%3A40%3A17%20GMT%2B03%3A00%202019 http/1.1

But I need to pass date params (from, to) in this format:

YYYY-MM-ddTHH:mm:ss.Z

Example:

https://some_host/operations?types=transfer&types=payment&status=executed&from=2018-07-01T19%3A13%3A51.418Z&to=2019-08-05T11%3A04%3A22.397Z

is it possible in Retrofit 2 ?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Alexei
  • 14,350
  • 37
  • 121
  • 240

3 Answers3

7

I think with custom converter (QueryConverterFactory) is better solution:

 private static Retrofit.Builder builder = new Retrofit.Builder()
            .baseUrl(BuildConfig.API_BASE_URL)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addConverterFactory(QueryConverterFactory.create())
            .client(httpClient.build());



public class QueryConverterFactory extends Converter.Factory {
    public static QueryConverterFactory create() {
        return new QueryConverterFactory();
    }

    @Override
    public Converter<?, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        if (type == Date.class) {
            return DateQueryConverter.INSTANCE;
        }
        return null;
    }

    private static final class DateQueryConverter implements Converter<Date, String> {
        static final DateQueryConverter INSTANCE = new DateQueryConverter();

        private static final ThreadLocal<DateFormat> DF = new ThreadLocal<DateFormat>() {
            @Override
            public DateFormat initialValue() {
                return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
            }
        };

        @Override
        public String convert(Date date) {
            return DF.get().format(date);
        }
    }
}

and as result param stay in Date format.

@GET("/operations")
    fun getOperationsList(
        @Query("types") typeList: List<@JvmSuppressWildcards OperationType>,
        @Query("status") statusList: List<@JvmSuppressWildcards OperationStatus>,
        @Query("from") from: Date, @Query("to") to: Date
    ): Call<List<Operation>>

and here result:

08-06 16:16:30.883 D/OkHttp  ( 8555): --> GET http://my_host:8081/operations?types=payment&types=payout&status=executed&from=2019-08-06T16%3A16%3A30&to=2019-08-06T16%3A16%3A30 http/1.1
Alexei
  • 14,350
  • 37
  • 121
  • 240
0

Use SimpleDateFormat

Example of how to use it: SimpleDateFormat("YYYY-MM-dd HH:mm:ss").format(dataObject)

More about it here

Miku
  • 567
  • 6
  • 15
  • `format` returns a string, so you can create a `SimpleDateFormat` object somewhere, and use it like this `"today is: ${sdf.format(Date())}"` – Miku Aug 06 '19 at 12:55
  • So, I need to change Date param to String param? – Alexei Aug 06 '19 at 12:57
  • Yes, you do need to do that – Miku Aug 06 '19 at 13:00
  • I add my answer.I think with ConverterFactory is better solution – Alexei Aug 06 '19 at 13:20
  • 1
    The `SimpleDateFormat` class is notoriously troublesome and considered long outdated. Today we have so much better in [`java.time`, the modern Java date and time API,](https://docs.oracle.com/javase/tutorial/datetime/) and its `DateTimeFormatter`. Yes, you can use it on Android. For older Android see [How to use ThreeTenABP in Android Project](https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project). BTW you don’t want uppercase `YYYY`. – Ole V.V. Aug 06 '19 at 14:50
0

Replace Date

@Query("from") from: Date, @Query("to") to: Date

with String

@Query("from") from: String, @Query("to") to: String

And pass date String as

val dateFormat_yyyyMMddTHHmmssZ : SimpleDateFormat = SimpleDateFormat(
        "yyyy-MM-dd'T'HH:mm:ss.'Z'", Locale.ENGLISH);

val fromDateString = dateFormat_yyyyMMddTHHmmssZ.format(date)
Jignesh Mayani
  • 6,937
  • 1
  • 20
  • 36