Java Web服务中使用了错误的时区

mr_*_*urf 3 java web-services date marshalling

我有一个JAX-B java Web服务,我用它来更新数据库.我正在更新的表中的每一行都由类似于下面的对象表示: -

public class Item {
    private String id;
    private Date startDate;
    private Date endDate;

    public Item() { }

    ...

}
Run Code Online (Sandbox Code Playgroud)

这个类在一个单独的程序中实例化,然后通过类似于下面的消息通过SOAP传递: -

...

<item>
    <id>D001IAAC030</id>
    <startDate>2009-09-17T00:00:00.000+01:00</startDate>
    <endDate>2009-10-01T00:00:00.000+01:00</endDate>
</item>

...
Run Code Online (Sandbox Code Playgroud)

如您所见,由于BST,UTC时间偏移为+01:00.但是,当对象在服务器上进行编组时(也在我的本地计算机上),它将恢复为GMT并从日期中扣除1小时.

你能告诉我怎么做: -

  1. 将我的Glassfish服务器设置为正确的区域设置,以便将日期识别为BST.
  2. 告诉我如何拦截Web服务端的编组,以便我可以在设置日期之前自己设置时区.

TIA,

URF

小智 5

您只需记住Date对象(始终)将日期/时间存储为UTC/GMT时区中自纪元以来的毫秒数.让人们兴奋的是Date.toString()方法在JVM的默认时区(通过内部Calendar对象)返回文本表示.(看看JDK源代码.)

例如在我的机器上

Date now = new Date();
System.out.println(now.toString());
System.out.println(now.getTime())
Run Code Online (Sandbox Code Playgroud)

会给

Fri Oct 02 06:56:24 EST 2009
1254430584531
Run Code Online (Sandbox Code Playgroud)

毫秒数是GMT/UTC时区中自纪元以来的实际毫秒数.

在操作/使用Date对象时,应始终使用Date格式化程序或Calendar实例.例如:

Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:MM:ss zzz yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(now.toString());
System.out.println(sdf.format(now));
Run Code Online (Sandbox Code Playgroud)

Fri Oct 02 06:56:24 EST 2009
Thu Oct 01 20:56:24 UTC 2009
Run Code Online (Sandbox Code Playgroud)

总结:始终将Date对象视为仅数据,自纪元以来的毫秒数.(不要使用任何的过时方法,除非你了解了它的显示不使用的toString().)要显示,格式转换(加减时间等)的日期/时间始终使用日历实例或日期格式实施,很难出错.

正如Javadoc所说的日期:

'在JDK 1.1之前,Date类有两个附加功能.它允许将日期解释为年,月,日,小时,分钟和秒值.它还允许格式化和解析日期字符串.不幸的是,这些功能的API不适合国际化.从JDK 1.1开始,Calendar类应该用于在日期和时间字段之间进行转换,而DateFormat类应该用于格式化和解析日期字符串.不推荐使用Date中的相应方法.

使用Date,Calendars和Formatters对自己进行实验并阅读Javadoc,它将变得更加清晰.

对于问题的第一部分,您不需要设置Glassfish服务器的时区来容纳您的数据.如果要使用数据/时间值存储时区数据,请在对象中使用日历而不是日期.或者像我通常那样,所有内容都存储为UTC时间(在对象中的db和Date实例中),时区仅在显示/输出或解析数据时使用.因此,当收到您的数据时,使用DateFormat或等效的时间区域设置为+01:00解析它(如果它附加了时区,它可以自动从时间字符串中选择,如示例所示).

我不清楚你的问题的第二部分,但如果你的web服务端的实现正确处理Dates并正确解析它,它应该在没有你干预的情况下处理它.