在改造的 RequestBody 中转换 Date 的 TimeZone
Convert TimeZone of Date in RequestBody of retrofit
我正在使用改造来调用服务器,我有这样的 requestBody:
class MyRequestBody {
String id;
Date date;
}
我想转换requestBody中日期对象的时区。
我试过这些东西:
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS zzz")
.create();
Retrofit.Builder adapterBuilder = new Retrofit
.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonCustomConverterFactory.create(gson))
class GsonCustomConverterFactory extends Converter.Factory
{
public static GsonCustomConverterFactory create(Gson gson) {
return new GsonCustomConverterFactory(gson);
}
private final Gson gson;
private final GsonConverterFactory gsonConverterFactory;
private GsonCustomConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
this.gson = gson;
this.gsonConverterFactory = GsonConverterFactory.create(gson);
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
if(type.equals(String.class))
return new GsonResponseBodyConverterToString<Object>(gson, type);
else
return gsonConverterFactory.responseBodyConverter(type, annotations, retrofit);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return gsonConverterFactory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
}
}
但是上面的代码只能控制日期的模式,不能控制时区。
我也想更改时区。
谢谢!
我找到了问题的解决方案。
我用了 TypeAdapter
.
class DateConverter extends TypeAdapter<Date> {
private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
@Override
public void write(JsonWriter out, Date date) throws IOException {
if (date == null) {
out.nullValue();
} else {
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
out.value(simpleDateFormat.format(date));
}
}
}
然后将此 Adapter 设置为 Gson
Gson gson = new GsonBuilder()
.registerTypeAdapter(Date.class, new DateConverter())
.create();
Retrofit.Builder adapterBuilder = new Retrofit
.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonCustomConverterFactory.create(gson))
感谢评论中的帮助
java.time
Date
class 设计不佳且早已过时。我知道你现在无法避免它。可能您从尚未升级到 java.time 的遗留 API、现代 Java 日期和时间 API.
获得了 Date
SimpleDateFormat
class更糟,是臭名昭著的捣蛋鬼。而你可以避免这个。
class DateConverter extends TypeAdapter<Date> {
@Override
public void write(JsonWriter out, Date date) throws IOException {
if (date == null) {
out.nullValue();
} else {
String dateTimeString = date.toInstant()
.atOffset(ZoneOffset.UTC)
.format(DateTimeFormatter.RFC_1123_DATE_TIME);
out.value(dateTimeString);
}
}
}
java.time 甚至为您正在编写的格式提供了一个内置的格式化程序。所以不需要编写我们自己的格式模式字符串,这很好,因为它总是一个容易出错的任务。我还喜欢在代码中明确转换为 UTC 的事实。 reader 更清楚发生了什么。
Link: Oracle tutorial: Date Time 解释如何使用 java.time.
我正在使用改造来调用服务器,我有这样的 requestBody:
class MyRequestBody {
String id;
Date date;
}
我想转换requestBody中日期对象的时区。
我试过这些东西:
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS zzz")
.create();
Retrofit.Builder adapterBuilder = new Retrofit
.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonCustomConverterFactory.create(gson))
class GsonCustomConverterFactory extends Converter.Factory
{
public static GsonCustomConverterFactory create(Gson gson) {
return new GsonCustomConverterFactory(gson);
}
private final Gson gson;
private final GsonConverterFactory gsonConverterFactory;
private GsonCustomConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
this.gson = gson;
this.gsonConverterFactory = GsonConverterFactory.create(gson);
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
if(type.equals(String.class))
return new GsonResponseBodyConverterToString<Object>(gson, type);
else
return gsonConverterFactory.responseBodyConverter(type, annotations, retrofit);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return gsonConverterFactory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
}
}
但是上面的代码只能控制日期的模式,不能控制时区。 我也想更改时区。 谢谢!
我找到了问题的解决方案。
我用了 TypeAdapter
.
class DateConverter extends TypeAdapter<Date> {
private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
@Override
public void write(JsonWriter out, Date date) throws IOException {
if (date == null) {
out.nullValue();
} else {
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
out.value(simpleDateFormat.format(date));
}
}
}
然后将此 Adapter 设置为 Gson
Gson gson = new GsonBuilder()
.registerTypeAdapter(Date.class, new DateConverter())
.create();
Retrofit.Builder adapterBuilder = new Retrofit
.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonCustomConverterFactory.create(gson))
感谢评论中的帮助
java.time
Date
class 设计不佳且早已过时。我知道你现在无法避免它。可能您从尚未升级到 java.time 的遗留 API、现代 Java 日期和时间 API.
Date
SimpleDateFormat
class更糟,是臭名昭著的捣蛋鬼。而你可以避免这个。
class DateConverter extends TypeAdapter<Date> {
@Override
public void write(JsonWriter out, Date date) throws IOException {
if (date == null) {
out.nullValue();
} else {
String dateTimeString = date.toInstant()
.atOffset(ZoneOffset.UTC)
.format(DateTimeFormatter.RFC_1123_DATE_TIME);
out.value(dateTimeString);
}
}
}
java.time 甚至为您正在编写的格式提供了一个内置的格式化程序。所以不需要编写我们自己的格式模式字符串,这很好,因为它总是一个容易出错的任务。我还喜欢在代码中明确转换为 UTC 的事实。 reader 更清楚发生了什么。
Link: Oracle tutorial: Date Time 解释如何使用 java.time.