使用 Gson 将时间从 UTC 转换为其他时区失败
Conversion of time from UTC to other timezone failing with Gson
我已将我的时间戳存储为 Timestamp
在我的 MySQL 数据库中。我在使用 UTC 的服务器上检索它们,然后将这些对象转换为 json 和 Gson
。 Gson
使用 JVM 的时区,因此它在服务器上使用 UTC,这正是我想要的。
在我的客户端,我在另一个时区 ("Europe/Amsterdam"),所以我尝试在那个时区显示日期。我正在检索 json,然后使用 Gson
将其转换为对象列表。我在客户那里检索到的日期是 UTC,所以一切顺利。这些对象有一个 Date
属性来存储日期。 json 看起来像这样(部分):
{"id":2,"timestamp_start":"Jan 13, 2015 10:44:45 AM GMT",...}
在转换中我使用了以下 TypeAdapter
:
public class DateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
private final DateFormat dateFormat;
public DateTypeAdapter() {
dateFormat = new SimpleDateFormat("MMM d, yyyy HH:mm:ss a", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
}
@Override public synchronized JsonElement serialize(Date date, Type type,
JsonSerializationContext jsonSerializationContext) {
return new JsonPrimitive(dateFormat.format(date));
}
@Override public synchronized Date deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext jsonDeserializationContext) {
try {
return dateFormat.parse(jsonElement.getAsString());
} catch (ParseException e) {
throw new JsonParseException(e);
}
}
}
然后,例如显示日期Tableviews,我只是用它来从 UTC 转换:
public static String dateToLocalTimeString(Date date) {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy 'om' HH:mm");
formatter.setTimeZone(TimeZone.getTimeZone("Europe/Amsterdam"));
return formatter.format(date);
}
问题是:它一直显示与数据库中存储的日期和时间相同的日期和时间,即 UTC。即使我去掉了 TypeAdapter
,它也会。
我在这里错过了什么?
转换后,我通过调用toString()
测试Date
,它显示相同的日期和时间,但现在附加了"CEST",我不明白。我应该是+2,但它只是相同的日期和时间...
更新 2: 我现在尝试这样转换(基于 Java 8 日期 API)
public static String dateToLocalTimeString(Date date) {
LocalDateTime ldt = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy 'om' HH:mm");
String formattedDateTime = ldt.format(formatter);
return formattedDateTime;
}
剧照显示时间提前2小时。我现在已经打印了纪元时间戳,它只是转换了 GMT -> CEST 而没有转换时间。所以我假设上面的 TypeAdapter
不起作用,所以我认为它与 Gson
..
有关
尝试将 SimpleDateFormat 设置为 MMM d, yyyy HH:mm:ss a z
{"id":2,"timestamp_start":"Jan 13, 2015 10:44:45 AM GMT",...}
在转换中,我使用了以下 TypeAdapter:
public class DateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
private final DateFormat dateFormat;
public DateTypeAdapter() {
dateFormat = new SimpleDateFormat("MMM d, yyyy HH:mm:ss a z", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
}
@Override public synchronized JsonElement serialize(Date date, Type type,
JsonSerializationContext jsonSerializationContext) {
return new JsonPrimitive(dateFormat.format(date));
}
@Override public synchronized Date deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext jsonDeserializationContext) {
try {
return dateFormat.parse(jsonElement.getAsString());
} catch (ParseException e) {
throw new JsonParseException(e);
}
}
}
使用此函数将 UTC (sourceS) 转换为另一个时区
public static String converDateTZ(String dateFormat, String dateString , String sourceTZ, String destiTZ) {
DateFormat sourceFormat = new SimpleDateFormat("MMM d, yyyy HH:mm:ss a z");
sourceFormat.setTimeZone(TimeZone.getTimeZone(sourceTZ));
Date date = null;
String parsDate = null;
if (dateString != null) {
try {
date = sourceFormat.parse(dateString);
DateFormat dFormat = new SimpleDateFormat(dateFormat);
if (destiTZ != null) {
dFormat.setTimeZone(TimeZone.getTimeZone(destiTZ));
}
parsDate = dFormat.format(date);
} catch (ParseException e) {
return "";
}
return parsDate;
} else {
return "";
}
}
我选择创建一个 DateTypeAdapter
,它不使用 SimpleDateFormat
,因为它看起来像是做了一些意想不到的事情(我不知道如何解决)。我现在在服务器上将所有日期转换为纪元,然后在客户端将它们转换回。非常简单,而且不使用任何时区。
public class DateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
public DateTypeAdapter() {
}
@Override
public synchronized JsonElement serialize(Date date, Type type, JsonSerializationContext jsonSerializationContext) {
return new JsonPrimitive(date.getTime());
}
@Override
public synchronized Date deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) {
return new Date(Long.parseLong(jsonElement.getAsString()));
}
}
当我想在客户端显示日期时,我可以用 SimpleDateFormat
来显示它。
我已将我的时间戳存储为 Timestamp
在我的 MySQL 数据库中。我在使用 UTC 的服务器上检索它们,然后将这些对象转换为 json 和 Gson
。 Gson
使用 JVM 的时区,因此它在服务器上使用 UTC,这正是我想要的。
在我的客户端,我在另一个时区 ("Europe/Amsterdam"),所以我尝试在那个时区显示日期。我正在检索 json,然后使用 Gson
将其转换为对象列表。我在客户那里检索到的日期是 UTC,所以一切顺利。这些对象有一个 Date
属性来存储日期。 json 看起来像这样(部分):
{"id":2,"timestamp_start":"Jan 13, 2015 10:44:45 AM GMT",...}
在转换中我使用了以下 TypeAdapter
:
public class DateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
private final DateFormat dateFormat;
public DateTypeAdapter() {
dateFormat = new SimpleDateFormat("MMM d, yyyy HH:mm:ss a", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
}
@Override public synchronized JsonElement serialize(Date date, Type type,
JsonSerializationContext jsonSerializationContext) {
return new JsonPrimitive(dateFormat.format(date));
}
@Override public synchronized Date deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext jsonDeserializationContext) {
try {
return dateFormat.parse(jsonElement.getAsString());
} catch (ParseException e) {
throw new JsonParseException(e);
}
}
}
然后,例如显示日期Tableviews,我只是用它来从 UTC 转换:
public static String dateToLocalTimeString(Date date) {
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy 'om' HH:mm");
formatter.setTimeZone(TimeZone.getTimeZone("Europe/Amsterdam"));
return formatter.format(date);
}
问题是:它一直显示与数据库中存储的日期和时间相同的日期和时间,即 UTC。即使我去掉了 TypeAdapter
,它也会。
我在这里错过了什么?
转换后,我通过调用toString()
测试Date
,它显示相同的日期和时间,但现在附加了"CEST",我不明白。我应该是+2,但它只是相同的日期和时间...
更新 2: 我现在尝试这样转换(基于 Java 8 日期 API)
public static String dateToLocalTimeString(Date date) {
LocalDateTime ldt = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy 'om' HH:mm");
String formattedDateTime = ldt.format(formatter);
return formattedDateTime;
}
剧照显示时间提前2小时。我现在已经打印了纪元时间戳,它只是转换了 GMT -> CEST 而没有转换时间。所以我假设上面的 TypeAdapter
不起作用,所以我认为它与 Gson
..
尝试将 SimpleDateFormat 设置为 MMM d, yyyy HH:mm:ss a z
{"id":2,"timestamp_start":"Jan 13, 2015 10:44:45 AM GMT",...}
在转换中,我使用了以下 TypeAdapter:
public class DateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
private final DateFormat dateFormat;
public DateTypeAdapter() {
dateFormat = new SimpleDateFormat("MMM d, yyyy HH:mm:ss a z", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
}
@Override public synchronized JsonElement serialize(Date date, Type type,
JsonSerializationContext jsonSerializationContext) {
return new JsonPrimitive(dateFormat.format(date));
}
@Override public synchronized Date deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext jsonDeserializationContext) {
try {
return dateFormat.parse(jsonElement.getAsString());
} catch (ParseException e) {
throw new JsonParseException(e);
}
}
}
使用此函数将 UTC (sourceS) 转换为另一个时区
public static String converDateTZ(String dateFormat, String dateString , String sourceTZ, String destiTZ) {
DateFormat sourceFormat = new SimpleDateFormat("MMM d, yyyy HH:mm:ss a z");
sourceFormat.setTimeZone(TimeZone.getTimeZone(sourceTZ));
Date date = null;
String parsDate = null;
if (dateString != null) {
try {
date = sourceFormat.parse(dateString);
DateFormat dFormat = new SimpleDateFormat(dateFormat);
if (destiTZ != null) {
dFormat.setTimeZone(TimeZone.getTimeZone(destiTZ));
}
parsDate = dFormat.format(date);
} catch (ParseException e) {
return "";
}
return parsDate;
} else {
return "";
}
}
我选择创建一个 DateTypeAdapter
,它不使用 SimpleDateFormat
,因为它看起来像是做了一些意想不到的事情(我不知道如何解决)。我现在在服务器上将所有日期转换为纪元,然后在客户端将它们转换回。非常简单,而且不使用任何时区。
public class DateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
public DateTypeAdapter() {
}
@Override
public synchronized JsonElement serialize(Date date, Type type, JsonSerializationContext jsonSerializationContext) {
return new JsonPrimitive(date.getTime());
}
@Override
public synchronized Date deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) {
return new Date(Long.parseLong(jsonElement.getAsString()));
}
}
当我想在客户端显示日期时,我可以用 SimpleDateFormat
来显示它。