【问题标题】:Local date & time to UTC and then UTC to local date & time本地日期和时间到 UTC,然后 UTC 到本地日期和时间
【发布时间】:2012-10-29 18:03:20
【问题描述】:

我正在尝试将语言环境时间转换为 UTC,然后将 UTC 转换为语言环境时间。但我没有得到结果。

public class DateDemo
{

public static void main(String args[])
{
    DateFormat dateFormatter = 
               DateFormat.getDateTimeInstance
                 (DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault());

    TimeZone.setDefault(TimeZone.getDefault());

    SimpleDateFormat simpleDateFormatter = new SimpleDateFormat("dd/MM/yyyy");
    SimpleDateFormat simpleTimeFormatter = new SimpleDateFormat("hh:mm:ss a");

    Date today = new Date();
    String localeFormattedInTime = dateFormatter.format(today);

    try
    {
        Date parsedDate = dateFormatter.parse(localeFormattedInTime);
        System.out.println("Locale:" + localeFormattedInTime);
        System.out.println("After parsing a date: " + parsedDate);

        simpleDateFormatter.setTimeZone(TimeZone.getDefault());
        simpleTimeFormatter.setTimeZone(TimeZone.getDefault());

        String date = simpleDateFormatter.format(today);
        String time = simpleTimeFormatter.format(today);
        System.out.println("Today's only date: " + date);
        System.out.println("Today's only time: " + time);

        //// Locale to UTC converting

        simpleDateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
        simpleTimeFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));

        String utcDate = simpleDateFormatter.format(today);
        String utcTime = simpleTimeFormatter.format(today);
        System.out.println("Convert into UTC's date: " + utcDate);
        System.out.println("Convert into UTC's only time: " + utcTime);

         //// UTC to locale converting

        simpleDateFormatter.setTimeZone(TimeZone.getDefault());
        simpleTimeFormatter.setTimeZone(TimeZone.getDefault());

        Date getDate = simpleDateFormatter.parse(utcDate);
        Date getTime = simpleTimeFormatter.parse(utcTime);

        String getLocalDate = simpleDateFormatter.format(getDate);
        String getLocalTime = simpleTimeFormatter.format(getTime);
        System.out.println("Get local date: " + getLocalDate);
        System.out.println("Get local time: " + getLocalTime);

    } catch (ParseException e) {
        e.printStackTrace();
    }
  }
 }

我正在向网络服务发送本地日期和时间,然后在需要时我需要检索 UTC 日期和时间,然后转换为区域设置日期和时间(即用户的本地设置)。

样本输出:

Locale:11/9/12 8:15 PM
After parsing a date: Fri Nov 09 20:15:00 SGT 2012
Today's only date: 09/11/2012
Today's only time: 08:15:30 PM
Convert into UTC's date: 09/11/2012
Convert into UTC's only time: 12:15:30 PM
Get local date: 09/11/2012
Get local time: 12:15:30 PM

Saksak 和 ADTC 回答后:

对于代码片段,UTC 日期和时间(实际上是 GMT-5 因为数据库可能在美国)是输入,我想获取本地日期和时间作为输出.但是下面这段仍然给 GMT-5 时间。

SimpleDateFormat simpleDateTimeFormatter = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss a");

....

Date inDateTime = simpleDateTimeFormatter.parse(intent.getExtras().getString("inTime")); Date outDateTime = simpleDateTimeFormatter.parse(intent.getExtras().getString("outTime"));

simpleDateTimeFormatter.setTimeZone(TimeZone.getDefault()); simpleDateTimeFormatter.setTimeZone(simpleDateTimeFormatter.getTimeZone());

//TimeZone tzTimeZone = TimeZone.getDefault();

//System.out.println("Current time zone: " + tzTimeZone.getDisplayName());

String getLocalInTimeString = simpleDateTimeFormatter.format(inDateTime); 

String getLocalOutTimeString = simpleDateTimeFormatter.format(outDateTime);

我的问题:getLocalInTimeString & getLocalOutTimeString 仍然显示 GMT-5 时间。这里有什么问题?我还需要设置什么其他的东西吗?

【问题讨论】:

  • 究竟是什么不起作用?例外?堆栈跟踪?运行程序的输出?
  • 分享你的代码,这将有助于我们的有效对话..
  • @Dibyendu 请注意,对日期和时间使用两个单独的解析器可能会导致转换问题。为避免它们,请使用一个解析器同时解析日期和时间。详情请看我的回答。

标签: java android


【解决方案1】:

你需要做的是解决你的问题,你有你的代码按这个顺序转换回本地时间:

simpleDateFormatter.setTimeZone(TimeZone.getDefault());
simpleTimeFormatter.setTimeZone(TimeZone.getDefault());

Date getDate = simpleDateFormatter.parse(utcDate);
Date getTime = simpleTimeFormatter.parse(utcTime);

你需要做的就是等到你把 utcDate, utcTime Strings 解析回 Date Object 然后将日期格式化程序时区设置为本地区域,如下所示:

Date getDate = simpleDateFormatter.parse(utcDate);
Date getTime = simpleTimeFormatter.parse(utcTime);

simpleDateFormatter.setTimeZone(TimeZone.getDefault());
simpleTimeFormatter.setTimeZone(TimeZone.getDefault());

这应该在本地打印正确的日期/时间。

编辑: 这是完整的主要方法:

public static void main(String[] args) {
    DateFormat dateFormatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault());
    TimeZone.setDefault(TimeZone.getDefault());
    SimpleDateFormat simpleDateFormatter = new SimpleDateFormat("dd/MM/yyyy");
    SimpleDateFormat simpleTimeFormatter = new SimpleDateFormat("hh:mm:ss a");
    Date today = new Date();
    String localeFormattedInTime = dateFormatter.format(today);
    try {
        Date parsedDate = dateFormatter.parse(localeFormattedInTime);
        System.out.println("Locale:" + localeFormattedInTime);
        System.out.println("After parsing a date: " + parsedDate);

        simpleDateFormatter.setTimeZone(TimeZone.getDefault());
        simpleTimeFormatter.setTimeZone(TimeZone.getDefault());

        String date = simpleDateFormatter.format(today);
        String time = simpleTimeFormatter.format(today);
        System.out.println("Today's only date: " + date);
        System.out.println("Today's only time: " + time);

        //// Locale to UTC converting

        System.out.println("TimeZone.getDefault() >>> " + TimeZone.getDefault());

        simpleDateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
        simpleTimeFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));

        String utcDate = simpleDateFormatter.format(today);
        String utcTime = simpleTimeFormatter.format(today);
        System.out.println("Convert into UTC's date: " + utcDate);
        System.out.println("Convert into UTC's only time: " + utcTime);

        //// UTC to locale converting
        /**
         ** //////EDIT
        */
        // at this point your utcDate,utcTime are strings that are formated in UTC
        // so first you need to parse them back to Dates using UTC format not Locale
        Date getDate = simpleDateFormatter.parse(utcDate);
        Date getTime = simpleTimeFormatter.parse(utcTime);

        // NOW after having the Dates you can change the formatters timezone to your
        // local to format them into strings
        simpleDateFormatter.setTimeZone(TimeZone.getDefault());
        simpleTimeFormatter.setTimeZone(TimeZone.getDefault());

        String getLocalDate = simpleDateFormatter.format(getDate);
        String getLocalTime = simpleTimeFormatter.format(getTime);
        System.out.println("Get local date: " + getLocalDate);
        System.out.println("Get local time: " + getLocalTime);

    } catch (ParseException e) {
        e.printStackTrace();
    }

}

【讨论】:

  • 你把代码泄露了 ;) ...但这并不可靠。我得到一个半小时的差异。看我的回答。
  • @ADTC 抱歉,我正在写答案,然后离开笔记本电脑重新打开,所以我没有看到你的答案,我测试了代码,它对我来说运行得很好。
  • 对不起,我弄错了。方法是可靠的,但原发帖人的使用方法是错误的。他对日期和时间使用了单独的解析器,这导致了我得到的半小时差异。如果您使用一个解析器将日期和时间组合为一个字符串,您将获得正确的时间(没有我遇到的不稳定差异)。检查我的答案的最新更新。
  • @ADTC 即使您使用 2 个解析器,它也应该可以工作,我运行代码,它给出了确切的日期/时间而无需更改任何内容。我将编辑我的答案并发布完整的主要方法,看看我们是否遗漏了什么
  • @Dibyendu 请检查我在上面代码中添加的cmets,希望它会说清楚
【解决方案2】:

您的问题在第 54 和 55 行:

    Date getDate = simpleDateFormatter.parse(utcDate);
    Date getTime = simpleTimeFormatter.parse(utcTime);

这些行只是解析包含日期和时间的字符串,但这些字符串没有任何时区信息:

    utcDate = "09/11/2012"
    utcTime = "12:15:30 PM"

因此,解析器假定字符串已经在您在第 51 行和第 52 行中设置的时区的语言环境中。

现在考虑如何解决它;)提示:确保解析器假定字符串表示的时间的正确时区。

PS:[已解决!] 我解决了这个问题,但我发现时区转换是不稳定的,至少在我所在的地方。时间是8:30 pm local .转换为 UTC,12:30 pm(正确,8 小时差异)。转换回来,它是8:00 pm(错误,即使设置的时区是正确的 - 我得到了原来的时区并将其传回 - 我只有 7.5 小时的差异)。 你应该寻找更可靠的方法,除非你能弄清楚发生了什么以及如何解决它。

[RESOLUTION:] 上面的问题实际上是因为原始代码将日期和时间拆分为两个不同的解析器。如果您只对日期和时间使用一个解析器,您将在目标语言环境中获得正确的日期和时间。所以总而言之,解析器可靠的,但是你使用它的方式有很大的不同!

    SimpleDateFormat simpleDateTimeFormatter
            = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss a");
    Date getDateTime
            = simpleDateTimeFormatter.parse(utcDate + " " + utcTime);
    //use above line if you have the date and time as separate strings
    simpleDateTimeFormatter.setTimeZone(TimeZone.getDefault());
    String getLocalDateTime = simpleDateTimeFormatter.format(getDateTime);
    System.out.println("Get local date time: " + getLocalDateTime);

为什么对日期和时间使用两个单独的解析器是不可靠的:
如上所述,对日期和时间部分使用两个单独的解析器是个坏主意。原因如下:

    Date getDate = simpleDateFormatter.parse(utcDate);
    Date getTime = simpleTimeFormatter.parse(utcTime);
    //Time zone changed to local here
    String getLocalDate2 = simpleDateTimeFormatter.format(getDate);
    String getLocalTime2 = simpleDateTimeFormatter.format(getTime);
    System.out.println("Get local date2: " + getLocalDate2);
    System.out.println("Get local time2: " + getLocalTime2);

    OUTPUT:
    Get local date2: 10/11/2012 08:00:00 AM
    Get local time2: 01/01/1970 10:35:10 AM

我得到半小时的差异,因为Date 变量存储时间(第二行)中使用了默认日期01/01/1970。将其转换为本地时区时,会发生错误,因为格式化程序将其转换基于默认日期01/01/1970 (where I live, 时差为 +7.5 小时 1970 年 - 今天,现在是 +8 小时)。这就是为什么两个单独的解析器即使您得到正确的结果也不可靠,您必须始终使用同时接受日期和时间信息的组合解析器。

【讨论】:

  • 感谢所有解释。
  • 不客气。你可以用绿色勾号奖励我;)(是的,我很无耻=P,这完全取决于你)
  • 没问题哥们...你的程序也运行良好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-18
  • 1970-01-01
  • 2012-10-07
  • 1970-01-01
  • 1970-01-01
  • 2016-07-29
  • 2021-06-29
相关资源
最近更新 更多