文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

深入了解Java.Util.Date详情

2024-04-02 19:55

关注

前言:

很少有类能像java.util.Date那样在堆栈溢出方面引起如此多的类似问题,有四个原因:

了解java.util.Date最重要的事情为:

现在,关于细节…

Java.Util.Date有什么问题?

java.util.Date(从现在开始就是Date)是一种糟糕的类型,这解释了为什么Java 1.1中有这么多的Date被弃用(但不幸的是,它仍然在使用)。

设计缺陷包括:

我可以发现更多的问题,但他们会越来越挑剔。这是一个非常丰富的列表。好的一面是:

不幸的是,开发人员对这一“好方面”的理解也很差。让我们把它打开…

什么是“瞬间”

注意:在这篇文章的其余部分,我忽略了相对论和闰秒。它们对一些人来说非常重要,但对大多数读者来说,它们只会带来更多的困惑。

当我谈论“瞬间”时,我指的是可以用来识别什么时候发生了什么的概念。(这可能发生在将来,但最容易从过去的事情来考虑。)它独立于时区和日历系统,因此多个使用“本地”时间表示的人可以用不同的方式谈论它。

让我们用一个非常具体的例子来说明发生在不使用我们熟悉的时区的地方的事情:尼尔·阿姆斯特朗在月球上行走。月球行走开始于一个特定的时刻——如果来自世界各地的多个人同时观看,他们会(几乎)同时说“我现在可以看到它正在发生”。

如果你在休斯顿的任务控制中心观看,你可能会想到那一刻是“1969年7月20日,CDT晚上9:56:20”。如果你在伦敦观看,你可能会想到那一刻是“1969年7月21日,英国夏令时凌晨3:26:20”。如果你在利雅得观看,你可能会认为那一刻是“1389年7月7日上午5:56:20(+03)”(使用《古拉经》日历)。尽管不同的观察者会在他们的时钟上看到不同的时间,甚至不同的年份,但他们仍然会考虑同一时刻。他们只是在应用不同的时区和日历系统,将即时转换为更人性化的概念。

那么,计算机如何表示实例呢?它们通常在一个特定的瞬间之前或之后存储一定量的时间,而这个瞬间实际上是一个原点。许多系统使用Unix纪元,这是格里高历中以UTC表示的1970年1月1日开始的午夜。这并不意味着纪元本质上是“在”UTC中的——Unix纪元同样可以定义为“1969年12月31日纽约下午7点的那一刻”。

Date类使用“自Unix纪元以来的毫秒数”——这是getTime()返回的值,由Date(long)构造函数或setTime()方法设置。由于月球行走发生在Unix纪元之前,因此该值为负值:实际上是-14159020000

为了演示日期如何与系统时区交互,让我们展示前面提到的三个时区–休斯顿(美国/芝加哥)、伦敦(欧洲/伦敦)和利雅得(亚洲/利雅得)。当我们从历元毫秒值构建日期时,系统时区是什么并不重要,这根本不取决于本地时区。但如果我们使用Date.toString(),它转换为当前默认时区以显示结果。更改默认时区根本不会更改日期值。对象的内部状态完全相同。它仍然表示相同的瞬间,但toString()getMonth()getDate()等方法将受到影响。

下面的示例代码显示:

import java.util.Date;
import java.util.TimeZone;

public class Test {

    public static void main(String[] args) {
        // The default time zone makes no difference when constructing
        // a Date from a milliseconds-since-Unix-epoch value
        Date date = new Date(-14159020000L);

        // Display the instant in three different time zones
        TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago"));
        System.out.println(date);

        TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));
        System.out.println(date);

        TimeZone.setDefault(TimeZone.getTimeZone("Asia/Riyadh"));
        System.out.println(date);

        // Prove that the instant hasn't changed...
        System.out.println(date.getTime());
    }
}

输出如下:

Sun Jul 20 21:56:20 CDT 1969
Mon Jul 21 03:56:20 GMT 1969
Mon Jul 21 05:56:20 AST 1969
-14159020000

这里的输出中的“GMT”和“AST”缩写非常不幸——java.util.TimeZone并非在所有情况下都具有1970年之前值的正确名称。不过时机已经成熟。

常见问题

如何将Date日期转换为其他时区?

你没有——因为约会没有时区。这是一个瞬间。不要被toString()的输出所愚弄。这会显示默认时区中的瞬间。这不是值的一部分。

如果代码以日期作为输入,则已经发生了从“本地时区”到即时的任何转换。(希望操作正确……)

如果您开始编写一个带有这样签名的方法,那么您并没有帮助自己:

// A method like this is always wrong
Date convertTimeZone(Date input, TimeZone fromZone, TimeZone toZone)

如何将Date日期转换为其他格式?

你没有——因为日期没有格式。不要被toString()的输出所愚弄。始终使用相同的格式,如文档所述。要以特定方式格式化日期,请使用合适的日期格式(可能是SimpleDataFormat)——记住将时区设置为适合您使用的适当区域。

到此这篇关于深入了解Java.Util.Date详情的文章就介绍到这了,更多相关Java.Util.Date 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯