如何使日期与语言环境无关?

Posted

技术标签:

【中文标题】如何使日期与语言环境无关?【英文标题】:How to make Date locale-independent? 【发布时间】:2011-02-11 10:58:28 【问题描述】:

我有一个数据库,它以OleDateTime 格式存储日期,在 GMT 时区。我已经实现了一个类,在 java 中扩展 Date 以用经典的日期格式表示它。但是我的课程取决于语言环境(我在 GMT+2)。因此,它将数据库中的日期转换为date - 2 hours。如何让它正确转换日期?我希望我的课程与语言环境无关,始终使用 GMT 时区。其实问题是:

class MyOleDateTime extends Date 

    static 
        Locale.setDefault(WhatGoesHere?)
    

    // ... some constructors
    // ... some methods

【问题讨论】:

【参考方案1】:

好吧,最好像其他答案中建议的那样使用 Calendar 对象。但是,如果您真的想要设置全球时区,您可以在应用程序代码的早期使用TimeZone.setDefault(TimeZone.getTimeZone("UTC"));。还有user.timezoneJava系统属性。

另外(很高兴知道),似乎唯一真正按照 GMT/UTC 时间(没有夏令时更改)的国家是利比里亚。

事实上,Date 对象本身总是 与语言环境和时区无关。它的getTime() 方法将始终返回自 1970 年 1 月 1 日 00:00:00(不包括闰秒)以来经过的毫秒数,UTC。但是,如果您想获得毫秒以外的信息,则必须使用Calendar,它 取决于时区。但这是正确的方法。您不会在 Date 类中使用那些已弃用的方法,是吗?

【讨论】:

@Michael 但我真的无法访问使用我的类的客户端代码。它确实使用了已弃用的 Date api。那我该怎么办? @Alexander 我实际上没有。但我很确定,我的客户会这样做。那么如何在不破坏代码的情况下让事情变得正确呢? @folone:如果您不能让他们纠正他们已经损坏的代码,那么您将不得不使用一个可能会在某些代码更改默认时区时中断的应用程序。 @Michael:那绝对不酷。我会尝试说服其他团队的人相应地更改他们的代码。谢谢。【参考方案2】:

正如 Michael Borgwardt 已经说过的,Java Date 对象对时区一无所知。自 01-01-1970 00:00:00 UTC 以来,它只是一个毫秒数的包装器。

仅当您使用DateFormatDate 对象转换为String 时才开始处理时区。您在DateFormat 上设置时区以指定您希望在哪个时区看到Date

DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("UTC"));

String text = df.format(date);  // text will contain date represented in UTC

【讨论】:

【参考方案3】:

日期 独立于区域设置,始终使用 GMT 时区。它只是 GMT(更准确地说:UTC)中毫秒时间戳的包装。

Date 中唯一依赖于时区的是已弃用的方法,例如 getDay() - 这就是它们被弃用的原因。那些使用默认时区。正确的做法是避免使用那些已弃用的方法 - not 将默认时区设置为 UTC!这可能会导致其他地方出现问题,并且您无法阻止代码的其他部分将默认时区设置为其他内容。

【讨论】:

【参考方案4】:

使用Calendar 对象:

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"),
                                    locale);

【讨论】:

我的班级在很多地方都被用作日期,我无法更改。【参考方案5】:

这是我用来计算 Calendar 实例的 GMT 偏移量并格式化它的 sn-p。我感谢我从这个网站获得的所有帮助,很高兴做出贡献。我希望这对某个地方的人有所帮助。享受吧。

Calendar calInst = Calendar.getInstance();

//calculate the offset to keep calendar instance GMT
int gmtOffsetMilli = calInst.get(Calendar.ZONE_OFFSET);
long gmtOffsetHr = TimeUnit.HOURS.convert(gmtOffsetMilli, TimeUnit.MILLISECONDS);

calInst = Calendar.getInstance(TimeZone.getTimeZone("GMT " + gmtOffsetHr));

【讨论】:

以上是关于如何使日期与语言环境无关?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据语言环境仅显示日期的日期和月份?

如何从日期选择器设置语言环境格式?

如何在不同的语言环境中对日期对象进行 strftime? [复制]

java 日期格式化

动态更改我的应用程序上下文的语言环境

如何更改格式化日期的语言环境?