java打印日期与系统不同

时间:2016-05-20 17:19:48

标签: java linux date centos timezone

我需要在date中设置系统Centos 6.6,这样我做了什么

  

cp / usr / share / zoneinfo / Europe / Paris / etc / localtime

我写了一个小的java应用程序来打印日期,然后用命令date打印日期,我得到了这个

  

[root @ sandbox~] #date

     

5月20日星期五19:13:32 CEST 2016

     

[root @ sandbox~] #java t

     

5月20日星期五17:13:35 UTC 2016

我真的需要知道为什么我有不同的时间以及如何解决它?

我不想更改我想要修复系统日期的java代码

4 个答案:

答案 0 :(得分:4)

在您发布该小Java应用程序的源代码之前,我们无法准确地为您提供帮助。

跟踪日期时间

您似乎误解的一个一般概念是计算机跟踪的日期时间没有时区。如果您使用旧的过时类java.util.Date,它会跟踪自epoch reference date中1970年第一时刻的UTC以来的毫秒数。

日期时间!=字符串

另一个概念:日期时间对象不是字符串。您可以生成一个字符串,以表示日期时间对象中的日期时间值,但该字符串与日期时间不同。请记住,在内部,日期时间实际上是自1970年UTC以来的毫秒数。

您的应用可能会在java.util.Date课程上调用toString方法。该方法容易混淆地将JVM的当前默认时区应用于存储的日期时间,从而产生java.util.Date已分配该区域的错误幻觉。

默认时区

默认时区通常在JVM启动时从主机操作系统中选取,但并非总是如此。 JVM的配置标志可以指示另一个时区作为默认值。 JVM中任何应用程序的任何线程中的任何代码都可以随时change the JVM’s default time zone在运行时!由于不可靠,我建议您避免使用默认值,而是始终指定所需/预期的时区。

通常,最佳做法是使服务器保持在UTC 。但我不希望我的应用程序容易受到某些系统管理员更改服务器时区等外部因素的影响,我总是在我的Java代码中指定所需/预期的时区(如下所示)。

没问题

所以你没有问题需要修复19:13:3x的巴黎时间(CEST)比UTC早两个小时,您的Java应用正确显示为UTC时区的17:13:3x。这些价值观有意义。这两个日期时间字符串是时间轴上同一时刻的两种不同表示形式。

如果您想在Java应用程序中使用巴黎时间,请询问巴黎时间(如下所示)。如果您想要UTC,请在Java应用程序中询问UTC(也会进一步显示)。

至于为什么你的Java应用程序显示UTC的时间仍然是个谜,直到你向我们展示你的源代码。

与此同时,我可以展示捕捉当前时间并调整到所需时区的基本知识。

java.time

您使用旧的日期时间类,这些类已被证明是麻烦,混乱和有缺陷的。避免他们。这些旧类已被Java 8及更高版本中内置的java.time框架所取代。许多java.time功能已经被反向移植到Java 6& 7在ThreeTen-Backport中,并在ThreeTenABP中进一步适应Android。

Instant是UTC时间轴上的当前时刻,分辨率为纳秒(比java.util.Date中的毫秒更精细)。

Instant instant = Instant.now();

通常最适合您的大部分业务逻辑,数据库存储,其他存储和UTC中的数据交换。因此,经常使用Instant

挂钟时间

应用时区以获取某个地区的wall-clock time。应用ZoneId获取ZonedDateTime

ZoneId zoneId = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

生成ISO 8601字符串

默认情况下,java.time中的toString方法生成标准ISO 8601格式的字符串。 ZonedDateTime类'toString方法通过在方括号中附加时区名称来扩展标准。

String output = instant.toString();
  

2016-05-21T00:52:53.375Z

String output = zdt.toString();
  

2016-05-21T02:52:53.375 + 02:00 [欧洲/巴黎]

您可以调整到另一个时区。请注意日期是巴黎之前的日期,20与5月的21相比(蒙特利尔仍为“昨天”)。

ZonedDateTime zdt_Montréal = zdt.withZoneSameInstant( ZoneId.of( "America/Montreal" ) ) ;
  

2016-05-20T20:52:53.375-04:00 [美国/蒙特利尔]

因此,我们在时间轴(UTC,巴黎和蒙特利尔)上生成了同一时刻的三种不同的文本表示。

时区

避免使用像CEST这样的3-4个字母区域缩写。这些既不是标准化的,也不是唯一的(!)。此外,它们不是真正的时区。始终以continent/region的格式使用proper time zone names

答案 1 :(得分:2)

如果您不喜欢或者您无法更改java代码,那么您必须更改服务器/系统/ centos timeZone,首先您需要查看可能的时区列表在

ls /usr/share/zoneinfo

和结果

timezone list

看到我们有日期Sat May 21 02:54:11 IRDT 2016我们现在要更改您需要更改(或设置)符号链接/etc/localtime,以便备份现有的`localtime文件

 sudo mv /etc/localtime /etc/localtime.bak

接下来,创建链接:

 sudo ln -s /usr/share/zoneinfo/America/Chicago /etc/localtime

请务必将America/Chicago替换为您希望使用的目录(如果您的区域有一个)和 timezone filename

 sudo ln -s /usr/share/zoneinfo/UTC /etc/localtime

现在您只需要测试您的更改。从命令行运行date,我完成了它,结果是

UTC time

并查看巨大的时区列表,点击here

答案 2 :(得分:0)

好的,首先你应该考虑使用@ Basil-Bourque的答案来改变你的代码。这是一个很好的做法

并且要更改TZ时区,请尝试将Europe/Paris导出到export TZ="Europe/Paris" ,如下所示

- (UIImage *)imageWithColor:(UIColor *)color
{
  CGRect rect = CGRectMake(0, 0, 1, 1);
  UIGraphicsBeginImageContext(rect.size);
  CGContextRef context = UIGraphicsGetCurrentContext();

  CGContextSetFillColorWithColor(context, [color CGColor]);
  CGContextFillRect(context, rect);

  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();

  return image;
}    

答案 3 :(得分:0)

确保您还检查了/etc/timezone文件并进行了相应调整