【问题标题】:Parsing formatted Date String in another TimeZone to date object not working在另一个 TimeZone 中解析格式化的日期字符串到日期对象不起作用
【发布时间】:2012-06-27 18:11:09
【问题描述】:

我正在尝试将格式化的日期字符串转换为日期对象。日期字符串被格式化为其他时区。

当我执行sdf.parse(String) 时,它会返回我的系统日期对象。

代码如下,

static Date convertGMTTime(String timeZone, long longDate){
    Date convertedTime = null;
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    try{
        Date date = new Date(longDate);
        System.out.println("timezone: "+timeZone +", timestamp: "+date);
        Locale locale = Locale.ENGLISH;
        TimeZone destTimeZone = TimeZone.getTimeZone(timeZone);// TimeZone.getDefault();
        System.out.println("Source timezone: "+destTimeZone);
/*          DateFormat formatter = DateFormat.getDateTimeInstance(
                    DateFormat.DEFAULT,
                    DateFormat.DEFAULT,
                    locale);
        formatter.setTimeZone(destTimeZone);*/
        sdf.setTimeZone(destTimeZone);
        String convertedDateStr = sdf.format(date);
        System.out.println("convertedDateStr: "+convertedDateStr);
        convertedTime = sdf.parse(convertedDateStr);
        System.out.println("convertedTime: "+convertedTime + "sdf: "+sdf.getTimeZone());
    }catch(Exception e){
        e.printStackTrace();
    }
    return convertedTime;
}

如果有人能提供帮助并指出我哪里出错了,我将不胜感激。 提前致谢。

输出:

时区:大西洋/佛得角,时间戳:2012 年 6 月 26 日星期二 17:38:11 IST
源时区:sun.util.calendar.ZoneInfo[id="Atlantic/Cape_Verde",offset=-3600000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null]

convertedDateStr: 2012-06-26 11:08:11

转换时间:2012 年 6 月 26 日星期二 17:38:11 IST
sdf:sun.util.calendar.ZoneInfo[id="Atlantic/Cape_Verde",offset=-3600000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null]


更多细节要分享,当我使用另一个 sdf 对象(没有为其设置时区)时,它确实返回了正确的时间和日期,但时区仍然是从系统时钟中选择的

代码

static Date convertGMTTime(String timeZone, long longDate){
    Date convertedTime = null;
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    SimpleDateFormat sdfParse = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    try{
        Date date = new Date(longDate);
        TimeZone destTimeZone = TimeZone.getTimeZone(timeZone);// TimeZone.getDefault();
        System.out.println("Source timezone: "+destTimeZone);
        sdf.setTimeZone(destTimeZone);
        String convertedDateStr = sdf.format(date);
        System.out.println("convertedDateStr: "+convertedDateStr );
        convertedTime = sdfParse.parse(convertedDateStr,new ParsePosition(0));
        System.out.println("convertedTime: "+convertedTime + "sdf: "+sdf.getTimeZone());
    }catch(Exception e){
        e.printStackTrace();
    }
    return convertedTime;
}

输出

Source timezone: sun.util.calendar.ZoneInfo[id="Atlantic/Cape_Verde",offset=-3600000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null]

convertedDateStr: 2012-06-26 12:24:56

convertedTime: Tue Jun 26 12:24:56 IST 2012 

sdf: sun.util.calendar.ZoneInfo[id="Atlantic/Cape_Verde",offset=-3600000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null]

我知道当我不将时区分配给 sdf 时,它需要系统时区,但为什么它不显示系统时区的时间?我在时区中显示它,就像在字符串中一样,但时区不同。

Ans 当我设置时区时,它会根据我的系统时间返回日期对象,而不管 sdf 是否设置了其他时区。

谁能解释一下 sdf.parse 和 sdf.format 的功能行为。

对我来说,sdf.setTimeZone() 在我们使用 format 时确实会产生影响,而在我们使用 sdf.parse() 时它会失效。我觉得很奇怪。

感谢您在这方面的帮助。

【问题讨论】:

    标签: java timezone


    【解决方案1】:

    您已经有一个日期(或日期的毫秒数),所以没有什么要转换的。日期没有任何时区。这是一个普遍的瞬间。仅当您显示此日期时,时区才相关,因为日期 65647678000 在某些时区可能是 12:38,但在某些其他时区可能是 10:38。当您解析日期的字符串表示时,它也很重要,因为 10:38 在某些时区是 65647678000,但在其他时区是 65657678000。

    虽然您不显示日期对象或将字符串解析为日期,但您不需要关心时区。并选择显示/解析时使用的时区,设置DateFormat的时区,然后使用DateFormat.format()/DateFormat.parse()格式化/解析日期。

    当您使用Date.toString() 显示日期时,它将始终使用您当前的时区。

    我发现不将日期视为一天、一个月、一年、一个小时等,而是将其视为一个时刻,这样更容易理解我的意思:“当肯尼迪被枪杀时”。 “当肯尼迪被枪杀时”对每个人来说都是同一个时刻。但是,如果您在达拉斯时区代表“肯尼迪被枪杀”的时刻,则与您在巴黎时区代表同一时刻时得到的结果不同。

    【讨论】:

    • 感谢您回复和分享宝贵的信息。我需要我的方法来返回 Date 对象,因为它将在给定的时区中。在使用 parse(String) 方法时,我在当前时区中获得了 Date 对象。我的应用程序要求用户在他的个人资料中设置他的时区,我想要一个通用方法,我可以在其中返回一个 Date 对象,因为它将在该时区中。
    • 我确实理解这样一个事实,即日期是所有时区的时间瞬间,以及我们如何显示/查看该时间瞬间根据时区而变化。现在,我担心的是,我可以在特定时区保留 Date 对象吗?我有一个为特定时区保留时间的字符串。我想解析它并根据给定的时区获取具有时间即时详细信息的 Date 对象。不确定是否可能,对我来说,它总是在我的系统时区给我日期对象。非常感谢任何帮助/解决方法。
    • 正如我所说:Date 对象没有时区。您认为它有一个,因为 toString() 方法返回一个包含您的时区的字符串。但是这个时区是JVM的默认时区。它不在 Date 对象中。您可以使用具有 TimeZone 的 Calendar 实例。或者,您可以在每次需要为该用户解析/显示 Date 对象时在用户的首选项中获取 TimeZone。
    • 解析字符串以获取 Date 对象对我不起作用,因为它在 JVM 时区返回我的对象​​(如上所述)。我需要一个带有时区时间的 Date 对象(我知道你的观点是日期没有时区)来比较不同时区的一个时间实例(例如 IST 中的 10:30 和 CST 中的 10:30)。我最初想用 Date 对象来做这件事。请告诉我这是否可能。
    • 您可以使用具有时区的日历实例。或者,您可以在每次需要为该用户解析/显示 Date 对象时在用户的首选项中获取 TimeZone。
    猜你喜欢
    • 2012-10-20
    • 2016-02-24
    • 1970-01-01
    • 2011-03-16
    • 2019-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    相关资源
    最近更新 更多