answer by Matt Johnson 是正确的。省略时区时,将应用 JVM 的默认时区。我建议总是指定一个时区而不是依赖隐式默认值,即使是通过显式调用getDefault() 来完成。
纯乔达时间
仅供参考,这里有一些示例代码可以更好地完成这项工作。这种方式只使用Joda-Time。正如您的问题所示,将 Joda-Time 和 java.util.Date/Calendar 混合会导致混乱和痛苦。此外,java.util.Date、.Calendar 和 SimpleDateFormat 类是出了名的麻烦,应该避免使用。
顺便说一句,不需要调用 getTimeZone 并传递 TimeZone 对象。 Joda-Time 有一个内置的 UTC 常量:DateTimeZone.UTC。
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd/MM/yyyy" ); // Usually I specify a Locale as well. But in this case, no need (no names of days or months).
DateTimeZone customerTimeZone = DateTimeZone.UTC;
String input = "25/05/2014";
DateTime customerDateTime = formatter.withZone( customerTimeZone ).parseDateTime( input );
DateTime customerDateTimeAtFive = customerDateTime.withHourOfDay( 5 ); // Using customerTimeZone.
不知道您为什么通过转换为 LocalDateTime 故意丢失时区信息。如果目标是在服务器上处理 UTC 格式的日期时间值,则无需丢失时区。服务器端代码应该使用明确分配给 UTC 时区的 DateTime 对象。您可以这样调整时区:
DateTime serverDateTime = customerDateTimeAtFive.withZone( DateTimeZone.UTC );
但无论如何,如果你坚持(与问题中的代码相同)......
DateTimeZone serverTimeZone = DateTimeZone.UTC;
LocalDateTime localDateTime = new LocalDateTime( customerDateTimeAtFive, serverTimeZone ); // I don't see the point of using LocalDateTime, but here goes anyways.
转储到控制台。
System.out.println( "customerTimeZone: " + customerTimeZone );
System.out.println( "input: " + input );
System.out.println( "customerDateTime: " + customerDateTime );
System.out.println( "customerDateTimeAtFive: " + customerDateTimeAtFive );
System.out.println( "serverDateTime: " + serverDateTime );
System.out.println( "serverTimeZone: " + serverTimeZone );
System.out.println( "localDateTime: " + localDateTime );
运行时。
customerTimeZone: UTC
input: 25/05/2014
customerDateTime: 2014-05-25T00:00:00.000Z
customerDateTimeAtFive: 2014-05-25T05:00:00.000Z
serverDateTime: 2014-05-25T05:00:00.000Z
serverTimeZone: UTC
localDateTime: 2014-05-25T05:00:00.000