9

我有一个包含原始日期字段(存储为字符数据)的数据库字段,例如

东部夏令时间 2008 年 9 月 26 日星期五晚上 8:30

我可以使用 SimpleDateFormat 轻松地将其解析为日期

DateFormat dbFormatter = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm aa zzzz");
Date scheduledDate = dbFormatter.parse(rawDate);

我想做的是从这个字符串中提取一个 TimeZone 对象。此应用程序运行的 JVM 中的默认时区是 GMT,所以我不能.getTimezoneOffset()Date上面的解析中使用(因为它会返回默认时区)。

除了标记原始字符串并找到 Timezone 字符串的起始位置(因为我知道格式将始终是EEEE, MMMM dd, yyyy hh:mm aa zzzz)之外,还有一种方法可以使用 DateFormat/SimpleDateFormat/Date/Calendar API 来提取 TimeZone 对象 - 这将具有相同的 TimeZone作为我解析的字符串DateFormat.parse()

在 Java API 中让我对Datevs感到困扰的一件事是,它应该在所有地方都被替换......但后来他们决定,哦,嘿,让我们仍然在类中使用's 。CalendarCalendarDateDateDateFormat

4

7 回答 7

2

我发现以下内容:

        DateFormat dbFormatter = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm aa zzzz");
        dbFormatter.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
        Date scheduledDate = dbFormatter.parse("Friday, September 26, 2008 8:30 PM Eastern Daylight Time");
        System.out.println(scheduledDate);
        System.out.println(dbFormatter.format(scheduledDate));
        TimeZone tz = dbFormatter.getTimeZone();
        System.out.println(tz.getDisplayName());
        dbFormatter.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
        System.out.println(dbFormatter.format(scheduledDate));

产生以下内容:

Fri Sep 26 20:30:00 CDT 2008
Friday, September 26, 2008 08:30 PM Eastern Standard Time
Eastern Standard Time
Friday, September 26, 2008 08:30 PM Central Daylight Time

我实际上发现这有点令人惊讶。但是,我想这表明您的问题的答案是在解析后简单地在格式化程序上调用 getTimeZone 。

编辑:以上是使用 Sun 的 JDK 1.6 运行的。

于 2008-09-17T18:32:42.240 回答
1

我建议查看Joda Time 日期和时间 API。我最近开始相信它,因为它往往比 Java 中对日期和时间的内置支持要好得多。特别是,您应该查看DateTimeZone类。希望这可以帮助。

http://joda-time.sourceforge.net/

http://joda-time.sourceforge.net/api-release/index.html

于 2008-09-17T19:09:38.970 回答
1

@埃德托马斯:

我尝试了与您的示例非常相似的方法,但得到了截然不同的结果:

String testString = "Friday, September 26, 2008 8:30 PM Pacific Standard Time";
DateFormat df = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm aa zzzz");

System.out.println("The default TimeZone is: " + TimeZone.getDefault().getDisplayName());

System.out.println("DateFormat timezone before parse: " + df.getTimeZone().getDisplayName());

Date date = df.parse(testString);

System.out.println("Parsed [" + testString + "] to Date: " + date);

System.out.println("DateFormat timezone after parse: " + df.getTimeZone().getDisplayName());

输出:

默认时区为:东部标准时间

解析前的 DateFormat 时区:东部标准时间

已解析 [太平洋标准时间 2008 年 9 月 26 日星期五晚上 8:30] 至今:2008 年 9 月 27 日星期六 00:30:00 EDT

解析后的 DateFormat 时区:东部标准时间

似乎DateFormat.getTimeZone()在 ... 之前和之后返回相同的 TimeZone ,parse()即使我setTimeZone()在调用parse().

查看 DateFormat 和 SimpleDateFormat 的来源,似乎getTimeZone()只是返回底层日历的 TimeZone ......除非您指定要使用的某个日历,否则它将默认为默认 Locale/TimeZone 的日历。

于 2008-09-17T18:47:38.727 回答
1
于 2016-10-26T05:12:02.723 回答
0

作为部分解决方案,您可以使用 RegEx 匹配来获取时区,因为您将始终拥有相同的文本。上午或下午。

我对 Java 时区知之甚少,无法让您了解它的最后一部分。

于 2008-09-17T17:55:59.507 回答
0

Date 和 Calendar 之间的主要区别在于,Date 只是一个值对象,没有修改它的方法。所以它被设计用于在某处存储日期/时间信息。如果您使用日历对象,则可以在将其设置为使用日期/时间信息执行某些业务逻辑的持久实体后对其进行修改。这是非常危险的,因为实体无法识别这种变化。Calendar 类是为日期/时间的操作而设计的,比如添加天数或类似的东西。

玩弄你的例子,我得到以下信息:

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;

public class TimeZoneExtracter {

    public static final void main(String[] args) throws ParseException {
        DateFormat dbFormatter = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm aa zzzz");
        System.out.println(dbFormatter.getTimeZone());
        dbFormatter.parse("Fr, September 26, 2008 8:30 PM Eastern Daylight Time");
        System.out.println(dbFormatter.getTimeZone());
    }

}

输出:

sun.util.calendar.ZoneInfo[id="Europe/Berlin"... sun.util.calendar.ZoneInfo[id="Africa/Addis_Ababa"...

这是你想要的结果吗?

于 2008-09-17T18:38:38.140 回答
0

埃德说得对。您希望在解析时间后 DateFormat 对象上的 timeZone 。

 String rawDate = "Friday, September 26, 2008 8:30 PM Eastern Daylight Time";
 DateFormat dbFormatter = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm aa zzzz");
 Date scheduledDate = dbFormatter.parse(rawDate);

 System.out.println(rawDate); 
 System.out.println(scheduledDate); 
 System.out.println(dbFormatter.getTimeZone().getDisplayName());

生产

Friday, September 26, 2008 8:30 PM Eastern Daylight Time
Fri Sep 26 20:30:00 CDT 2008
Eastern Standard Time
于 2008-09-17T18:58:55.610 回答