有人能解释一下,当我把过去的日期转换成莫斯科时区时,为什么会增加一个小时?
我使用的是JDK 1.60_12版本。
2011-04-02T11:39:46+0300 --> Sat Apr 02 12:39:46 MSK 2011 // 11:39 --> 12:39
我目前的系统时区是“欧洲/莫斯科”UTC 3。
此外,请注意,这个过去的日期是在DST(夏令时)时区期间UTC 4,早些时候在俄罗斯使用。2014年10月,俄罗斯时区定义发生了立法变化。从那以后,俄罗斯一整年都在使用UTC 3。
我已经查过这个2014年的老帖子了。
我们的开发人员希望,过去的每个日期(如“2011-04-02T11:39:46 0300”,且在DST期间)都应该包含当前时区偏移值,即0300,而不是0400。他们认为JRE错误地将其转换为UTC 4,尽管“默认时区偏移”显示为3。这种处理过去日期的时区偏移值的方法正确吗?
在JRE 1.8上给出了相同的输出,我认为这是一个更新的版本,JRE 1.8中的TZ定义不应该有任何问题。
提前感谢!
Java代码:
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import java.util.Date;
public class HelloWorld{
public static void main(String []args)
{
String dateInString = "2011-04-02T11:39:46+0300";
System.out.println(dateInString);
try {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date date = dateFormat.parse(dateInString);
System.out.println(date);
} catch (Exception e) {
System.out.println(e);
}
final TimeZone tzone = TimeZone.getDefault();
System.out.println("Default Time Zone ID - " + tzone.getID());
System.out.println("Default Time Zone Offset - (" + (tzone.getRawOffset() / 60 / 60 / 1000) + ") hour.");
}
}
输出:
2011-04-02T11:39:46+0300
Sat Apr 02 12:39:46 MSK 2011
Default Time Zone ID - Europe/Moscow
Default Time Zone Offset - (3) hour.
您需要将时区设置为SimpleDateFormat
,如下所示:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) throws ParseException {
String dateInString = "2011-04-02T11:39:46+0300";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
dateFormat.setTimeZone(TimeZone.getTimeZone("Europe/Moscow"));// Set time-zone
Date date = dateFormat.parse(dateInString);
System.out.println(dateFormat.format(date));
}
}
输出:
2011-04-02T12:39:46+0400
注意java。util。日期
没有时区信息。它只是标准Java纪元1970-01-01T00:00:00Z
的毫秒数,其中Z
代表UTC(0
hour offset),也称为Zulu
时区。在任何给定的时刻,您都会在位于世界任何部分的JVM上获得相同的毫秒数。当您试图打印java的对象时。util。Date
,JVM时区的日期时间字符串将根据该毫秒值计算出来,并显示相同的值。如果要获取特定时区中的日期时间字符串
,则需要将其显式设置为SimpleDataFormat
,并使用相同的设置来格式化java。util。日期
。
现代的java date/time api和传统的one(在jdk1.6中使用)都依赖于与JRE捆绑在一起的系统unix time和tzdata文件。看起来开发者是对的,你的java使用的是一个非常古老的tzdata版本,你的开发者是对的。
此外,tzdata保留有关法律变化的信息,如果您试图转换过去的日期/时间,它将应用当时相关的转换规则。
关于JDK 1.8:在8u101中更新了俄罗斯时区信息,因此您应该至少使用8u101进行更好的时区转换。
对于你来说,最好的决定是使用现代java,或者如果你真的需要使用旧的JREs数据,手动更新你的JREs数据。
你得到了正确的结果。在字符串2011-04-02T11:39:46 0300
中,尾随的0300
是UTC的偏移量。所以时间点与2011-04-02T08:39:46 00:00
(UTC)相同。正如你自己所说,莫斯科在2011年3月27日至2014年10月26日的世界协调时偏移04:00。因此,为了得到莫斯科的正确时间Java需要在字符串中的小时基础上增加1小时。或者4小时到世界协调时08:39:46。无论如何,此时莫斯科的时间是12:39:46。
或者回答你的问题:
…当我把过去的日期改成莫斯科时区时,为什么会增加一个小时?
因为莫斯科在那一天比时间提前了一个小时。
也就是说,我同意那些推荐java的人。时间,现代Java日期和时间API,用于该作业SimpleDataFormat
是一个臭名昭著的麻烦制造者,而Date
和TimeZone
的设计也很糟糕,令人困惑。这些都早已过时。现代的API非常好用。
例如:
ZoneId zone = ZoneId.of("Europe/Moscow");
ZonedDateTime zdt = ZonedDateTime.of(2011, 4, 2, 11, 39, 46, 0, zone);
System.out.println(zdt);
输出:
2011-04-02T11:39:46 04:00[欧洲/莫斯科]
您还可以从输出中看到,Java知道莫斯科当时的偏移量为04:00。
你的问题很好地说明了为什么java.time(与旧的TimeZone
类相反)区分时区和偏移量。时区包括UTC的所有历史、现在和所有已知的未来偏移。这是你需要正确代表莫斯科的历史时期。java.time一个时区由一个ZoneId
对象标识,并服从一个ZoneLaw
对象(通常我们不需要关心后者,只需相信Java就可以做出正确的选择转换)。UTC偏移量由ZoneOffset
对象表示。
今天是你的幸运日。java.time需要至少6Java。
org导入日期和时间类。三十。带有子包的bp
java.time
。 java.time
到Java6和7的Backport(用于JSR-310的Threeten)。 对于我们的俄罗斯租户,我们使用“欧洲/莫斯科”时区。但我们比正确的时间提前了一个小时。 欧洲/莫斯科是世界协调时3小时。但是,当我打印日期格式与欧洲/莫斯科时区得到1小时前的正确时间。 谢谢,西亚玛拉。
有些时区会切换到夏令时,有些不会。我知道俄罗斯不使用这个时间,而乌克兰使用夏令时。 正如我从这个链接中知道的.NET 时区信息来自奥尔森时区莫斯科使用俄罗斯标准时间,基辅(乌克兰)使用 FLE 标准时间。 我的测试是: > 冬季,俄罗斯,DateTimeKid. Utc 冬天,俄罗斯,日期时间。当地的 Summer,俄罗斯,DateTimeKind.Utc 夏天,俄罗斯,DateTimeKind。
Hi im使用moment js转换此字符串我尝试了: 当我存储在mongodb中时,问题就变成了 反正能解释为什么请?
问题内容: 法国说如何将时区中的当前时间(日期时间)转换为另一个时区?我在SO中环顾四周,但没有找到任何可以帮助我的帖子。我正在使用SQL Server 2008。 问题答案: 在这里检查
问题内容: 我正在尝试使用Java日期和日历来实现从一个时区到另一个时区的简单转换。我正在尝试运行以下代码 但这仍然返回相同的日期,而不是+1小时…整个问题似乎微不足道,但我找不到任何简单的答案。在此先感谢您的帮助。 问题答案: 当您使用来打印日期时, 返回的是,并且始终以本地时区打印日期。 相反,您可能要使用:
问题内容: 我从服务器获得的时间就像 。 我想将其转换为。 我还希望转换后的时间为24小时格式。任何人都可以解决这个问题。我想得到的输出就像 问题答案: 试试这个: