【问题标题】:java print date different than the systemjava打印日期与系统不同
【发布时间】:2016-05-20 17:19:47
【问题描述】:

我需要在Centos 6.6中设置系统date所以我做了什么

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

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

[root@sandbox ~]#日期

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

[root@sandbox ~]# java t

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

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

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

【问题讨论】:

  • 看起来像不同的时区?
  • 只是一个基本的日期打印`Date date = new Date();`System.out.println(date.toString());
  • @Orin2005 我知道但我不知道如何解决它
  • @omar stackoverflow.com/questions/12275811/… 读一读。您可以尝试使用 SimpleDateFormat 编辑时区,看起来像
  • @Orin2005 我不想更改 java 代码我有一个庞大的程序这是不可能的

标签: java linux date centos timezone


【解决方案1】:

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

跟踪日期时间

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

日期时间!= 字符串

另一个概念:日期时间对象不是字符串。您可以生成一个字符串来表示您的日期时间对象中的日期时间值,但该字符串与日期时间不同。请记住,在内部,日期时间实际上是自 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 应用程序正确显示为 17:13:3x UTC 时区。这些值是有意义的。这两个日期时间字符串是时间轴上同一时刻的两种不同表示。

如果您想要在您的 Java 应用程序中使用巴黎时间,请询问巴黎时间(如下所示)。如果您需要 UTC,请在您的 Java 应用程序中请求 UTC(也显示在下方)。

在您向我们展示您的源代码之前,为什么您的 Java 应用程序以 UTC 显示时间仍然是个谜。

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

java.time

您使用的是旧的日期时间类,这些类已被证明是麻烦、混乱和有缺陷的。避开他们。这些旧类已被 Java 8 及更高版本中内置的 java.time 框架所取代。大部分 java.time 功能已在 ThreeTen-Backport 中向后移植到 Java 6 和 7,并在 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、巴黎和蒙特利尔)生成了三种不同的文本表示。

时区

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

【讨论】:

    【解决方案2】:

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

    ls /usr/share/zoneinfo
    

    结果

    看到我们有日期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 替换为您希望使用的时区 的目录(如果您的区域有一个)和filename,例如

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

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

    查看庞大的时区列表请点击here

    【讨论】:

    • 我在我的问题中确实说过我确实将 /zoneinfo 中的文件链接到 /etc/localtime。
    • 我在我的linux 系统中测试并更改timezone 并进行比较!现在你这样做sudo mv /etc/localtime /etc/localtime.baksudo ln -s /usr/share/zoneinfo/UTC /etc/localtime 两步,告诉我们发生了什么?
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      好的,首先您应该考虑使用@Basil-Bourque 答案来更改您的代码。这是个好习惯

      为了改变你 Centos 时区,请尝试将 TZ 导出为 Europe/Paris,如下所示

      export TZ="Europe/Paris"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-06
        • 2016-01-12
        • 1970-01-01
        • 2010-12-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多