有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

从UTC到其他时区的java时间转换因Gson失败

我已经在MySQL数据库中将时间戳存储为Timestamp。我在使用UTC的服务器上检索它们,然后使用Gson将这些对象转换为jsonGson使用JVM的时区,因此它在服务器上使用UTC,这正是我想要的

在我的客户方面,我在另一个时区(“欧洲/阿姆斯特丹”),所以我尝试在该时区显示日期。我正在检索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);
      }
    }
}

然后,为了在例如TableView中显示日期,我只需使用它从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 Date 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小时。我现在已经打印了epoch时间戳,它刚刚转换了GMT->;不转换时间的CEST。所以我假设上面的TypeAdapter不起作用,所以我认为它与Gson有关


共 (3) 个答案

  1. # 1 楼答案

    我选择创建一个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来显示它

  2. # 2 楼答案

    尝试将简化格式设置为mmmd,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);
          }
        }
    }
    
  3. # 3 楼答案

    使用此功能将UTC(sourceTZ)转换为其他时区

    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 "";
        }
    

    }