我一直很困惑,为什么下面的代码会导致我的日期从25日更改为24日
SimpleDateFormat sd = new SimpleDateFormat("dd/MM/yyyy");
DateTimeZone customerZone = DateTimeZone.forTimeZone(TimeZone.getTimeZone("UTC"));
DateTimeZone serverZone = DateTimeZone.UTC;
Date date = sd.parse("25/05/2014");
DateTime source = new DateTime(date).withZone(customerZone).withHourOfDay(5);
LocalDateTime ldate = new LocalDateTime(source, serverZone);
System.out.println(ldate.toDate()); //expected to be Sat May 25 05:00:00
结果
您没有为SimpleDateFormat
设置时区,因此它默认为您的环境的时区,我猜是"Africa/Johannesburg"
,因为您的结果中有SAST。
所以当你做这部分时:
SimpleDateFormat sd = new SimpleDateFormat("dd/MM/yyyy");
Date date = sd.parse("25/05/2014");
date
天体将在SAST的午夜,即UTC的前一天晚上10点。其余部分从这里开始,因为您从那时起就在使用UTC。
同样,在最后,您调用toDate
,这将产生一个Date
对象。当您输出该结果时,本地时区也会影响结果。
可以考虑在SimpleDateFormat
对象上调用setTimeZone
。这样至少可以使开头部分正确。但是,您还应该使用format
方法来输出最终字符串。
然而,更好的解决方案是使用JodaTime的DateTimeFormatter
。那么你就不需要使用SimpleDateFormat
或Date
了。
我认为南非的25/05/2014 00:00:00被看作是UTC客户时区的24/5,晚上10点。最后将时间设置为上午5点
Matt Johnson的答案是正确的。当您省略一个时区时,将应用JVM的默认时区。我建议总是指定时区,而不是依赖于隐式默认值,即使通过显式调用getDefault()
完成。
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
标题>