如果手机时区已更改,SimpleDateFormat setTimeZone无效

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果手机时区已更改,SimpleDateFormat setTimeZone无效相关的知识,希望对你有一定的参考价值。

我在使用SimpleDateFormat和时区时遇到了一个奇怪的问题。

基本上,我有这段代码:

    String input              = "2017-12-21 16:15:00";
    String inputTZ            = "America/Los_Angeles";
    String phoneTZ            = TimeZone.getDefault().getID();
    SimpleDateFormat fmtInput = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
    fmtInput.setTimeZone(TimeZone.getTimeZone(inputTZ));

    SimpleDateFormat fmtOutputEventTZ = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
    fmtOutputEventTZ.setTimeZone(TimeZone.getTimeZone(inputTZ));

    SimpleDateFormat fmtOutputPhoneTZ = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
    fmtOutputPhoneTZ.setTimeZone(TimeZone.getTimeZone(phoneTZ));


    try {
        LocalDateTime dt = new LocalDateTime(fmtInput.parse(input));

        Log.d("DEBUG>>>>", "INPUT=" + input);
        Log.d("DEBUG>>>>", "TZ_EVENT=" + inputTZ);
        Log.d("DEBUG>>>>", "TZ_PHONE=" + phoneTZ);
        Log.d("DEBUG>>>>", "DT=" + dt);
        Log.d("DEBUG>>>>", "OUTPUT_EVENT=" + fmtOutputEventTZ.format(dt.toDate()));
        Log.d("DEBUG>>>>", "OUTPUT_PHONE=" + fmtOutputPhoneTZ.format(dt.toDate()));
    }
    catch (Exception e) {
        e.printStackTrace();
    }

代码逻辑如下:

  • 我有洛杉矶时区的输入日期(GMT-8)
  • 我解析这个日期指定时区(LA)
  • 然后我使用原始时区(LA)和当前手机时区格式化日期

我将手机时区设置为芝加哥(GMT-6)运行代码并得到以下输出。

D/DEBUG>>>>: INPUT=2017-12-21 16:15:00
D/DEBUG>>>>: TZ_EVENT=America/Los_Angeles
D/DEBUG>>>>: TZ_PHONE=America/Chicago
D/DEBUG>>>>: DT=2017-12-21T18:15:00.000
D/DEBUG>>>>: OUTPUT_EVENT=2017-12-21 16:15:00
D/DEBUG>>>>: OUTPUT_PHONE=2017-12-21 18:15:00

基本上,结果是预期的结果。

但是,如果我在没有重新启动应用程序的情况下将手机时区更改为纽约(GMT-5),我得到以下输出

D/DEBUG>>>>: INPUT=2017-12-21 16:15:00
D/DEBUG>>>>: TZ_EVENT=America/Los_Angeles
D/DEBUG>>>>: TZ_PHONE=America/New_York
D/DEBUG>>>>: DT=2017-12-21T18:15:00.000
D/DEBUG>>>>: OUTPUT_EVENT=2017-12-21 15:15:00
D/DEBUG>>>>: OUTPUT_PHONE=2017-12-21 18:15:00

请注意,TimeZone.getDefault().getID()返回的时区是正确的,但是当它被解析时,SimpleDateFormat将其转换为电话时区仍然是芝加哥,从而返回错误的时间!

但是,如果我杀了应用程序并重新启动它,相同的代码工作正常:

D/DEBUG>>>>: INPUT=2017-12-21 16:15:00
D/DEBUG>>>>: TZ_EVENT=America/Los_Angeles
D/DEBUG>>>>: TZ_PHONE=America/New_York
D/DEBUG>>>>: DT=2017-12-21T19:15:00.000
D/DEBUG>>>>: OUTPUT_EVENT=2017-12-21 16:15:00
D/DEBUG>>>>: OUTPUT_PHONE=2017-12-21 19:15:00

根据我的理解,SimpleDateFormat.parse解析日期并将其存储为自1970年以来的秒数。使用setTimeZone应使用时区来适当地改变时间。

然而,似乎手机时区的变化并未反映出SimpleDateFormat,而TimeZone.getDefault().getID()则清楚地反映了这一变化。

有什么方法可以解决这个问题吗?

答案

找到了解决方案!

我一开始就打电话给DateTimeZone.setDefault(DateTimeZone.forID(TimeZone.getDefault().getID()))

我想DateTimeZone.setDefault在应用程序启动时被调用,但之后joda-time本身从未重置,即使用户的时区可能已经改变。

以上是关于如果手机时区已更改,SimpleDateFormat setTimeZone无效的主要内容,如果未能解决你的问题,请参考以下文章

手机时间怎么修改?

android获取手机真实时间与时区,IP地址

iphone 上的时区变成GMT时区 怎么改?!

JAVA06_Date概述及方法SimpleDateForma时间转字符字符转时间详解

Linux之CentOS 6 时区更改

更改时区phpmyadmin?