SimpleDateFormat时区解析

发布于 2024-12-19 09:11:51 字数 608 浏览 1 评论 0 原文

我很难解析这个日期,它末尾的 +0 导致了问题,有人知道我的格式字符串有什么问题吗?如果我从日期字符串中删除 +0 并从格式字符串中删除 Z,则它可以正常工作,但不幸的是,对于我的应用程序来说,这不是一个选项。

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        SimpleDateFormat dateFormater = new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss zZ");
        try {
            Date d = dateFormater.parse("Sun, 04 Dec 2011 18:40:22 GMT+0");
            System.out.println(d.toLocaleString());
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

I'm having a tough time parsing this date its the +0 at the end that is causing a problem, does anyone know whats wrong with my format string?? If I remove the +0 from the date string and the Z from the format string it works fine, unfortunately for my application that isn't an option.

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        SimpleDateFormat dateFormater = new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss zZ");
        try {
            Date d = dateFormater.parse("Sun, 04 Dec 2011 18:40:22 GMT+0");
            System.out.println(d.toLocaleString());
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

十年不长 2024-12-26 09:11:51

一种方法是使用普通的字符串操作技术将字符串从您期望的形式转换为 SimpleDateFormat 能够理解的形式。您还没有确切地说什么范围的时区格式是可以接受的,但一种可能性是这样的:

private static Date parse(String dateString) throws ParseException
{
    final SimpleDateFormat dateFormat =
        new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss Z");
    dateString = dateString.replaceAll("(GMT[+-])(\\d)$", "$1\\0$2");
    dateString = dateString.replaceAll("(GMT[+-]\\d\\d)$", "$1:00");
    return dateFormat.parse(dateString);
}

除了仍然支持任何内容之外,还支持 GMT 加或减一位或两位数的小时偏移量SimpleDateFormat 已支持,例如 ESTGMT+1030

或者,如果您知道它始终是 GMT,那么您可以只在格式化程序上设置时区,并忽略字符串中的时区:

private static Date parse(String dateString) throws ParseException
{
    final SimpleDateFormat dateFormat =
        new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss");
    dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
    return dateFormat.parse(dateString);
}

您也可以分割差异。我注意到字符串中的时区格式与 TimeZone.getTimeZone() 的预期相匹配。这是故意的吗?如果是这样,您可以从字符串中获取该时区格式,预先将其传递给 dateFormat.setTimeZone ,然后在实际解析过程中忽略它:

private static Date parse(final String dateString) throws ParseException
{
    final SimpleDateFormat dateFormat =
        new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss");
    if(dateString.indexOf("GMT") > 0)
        dateFormat.setTimeZone
        (
            TimeZone.getTimeZone
                (dateString.substring(dateString.indexOf("GMT")))
        );
    return dateFormat.parse(dateString);
}

One approach is to use normal string-manipulation techniques to translate your string from a form that you're expecting to a form that SimpleDateFormat will understand. You haven't said exactly what range of time-zone formats are acceptable, but one possibility is something like this:

private static Date parse(String dateString) throws ParseException
{
    final SimpleDateFormat dateFormat =
        new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss Z");
    dateString = dateString.replaceAll("(GMT[+-])(\\d)$", "$1\\0$2");
    dateString = dateString.replaceAll("(GMT[+-]\\d\\d)$", "$1:00");
    return dateFormat.parse(dateString);
}

That would support GMT plus-or-minus a one-or-two-digit hour offset, in addition to still supporting anything already supported by SimpleDateFormat, such as EST or GMT+1030.

Alternatively, if you know it will always be GMT, then you can just set the time-zone on the formatter, and ignore the time-zone in the string:

private static Date parse(String dateString) throws ParseException
{
    final SimpleDateFormat dateFormat =
        new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss");
    dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
    return dateFormat.parse(dateString);
}

You can also split the difference. I notice that the time-zone format in your string matches what's expected by TimeZone.getTimeZone(). Is that intentional? If so, you can grab that time-zone format out of the string, pass it to dateFormat.setTimeZone beforehand, and then ignore it during actual parsing:

private static Date parse(final String dateString) throws ParseException
{
    final SimpleDateFormat dateFormat =
        new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss");
    if(dateString.indexOf("GMT") > 0)
        dateFormat.setTimeZone
        (
            TimeZone.getTimeZone
                (dateString.substring(dateString.indexOf("GMT")))
        );
    return dateFormat.parse(dateString);
}
执手闯天涯 2024-12-26 09:11:51

如果格式一致,您可以将 0:00 附加到日期字符串。

String dateString = "Sun, 04 Dec 2011 18:40:22 GMT+0";
SimpleDateFormat sdf = new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss z", Locale.ENGLISH);
Date date = sdf.parse(dateString + "0:00");
System.out.println(date);

(请注意,我修复了 SimpleDateFormat 构造以显式指定用于解析星期几和月份名称的区域设置,否则在不使用英语作为默认值的平台上可能会失败我还想知道您是否实际上 需要HH 而不是 kk,但除此之外)

If the format is that consistent, you could append 0:00 to the date string.

String dateString = "Sun, 04 Dec 2011 18:40:22 GMT+0";
SimpleDateFormat sdf = new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss z", Locale.ENGLISH);
Date date = sdf.parse(dateString + "0:00");
System.out.println(date);

(note that I fixed the SimpleDateFormat construction to explicitly specify the locale which would be used to parse the day of week and month names, otherwise it may fail on platforms which does not use English as default locale; I also wonder if you don't actually need HH instead of kk, but that aside)

兰花执着 2024-12-26 09:11:51

tl;dr

使用现代的 java.time 类。

OffsetDateTime
        .parse (
                "Sun, 04 Dec 2011 18:40:22 GMT+0" ,
                DateTimeFormatter
                        .ofPattern ( "EEE, dd MMM uuuu HH:mm:ss O" )
                        .withLocale ( Locale.of ( "en" , "US" ) )
        )
        .toString ( )

现代 Java 中的 java.time

避免使用存在严重缺陷的遗留类,例如 CalendarDateSimpleDateFormat。仅使用 Java 8+ 中的 java.time 类。

RFC 822 和 RFC 822 1123

您的输入字符串 "Sun, 04 Dec 2011 18:40:22 GMT+0" 似乎是 RFC 822 & RFC 1123。 Java 附带了一个预定义的格式化程序 RFC_1123_DATE_TIME 对于这些标准,但您的输入变化太大,无法正常工作。

提示:要以文本方式存储和交换日期时间值,请仅使用 ISO 8601 格式。

DateTimeFormatter

因此我们需要定义自己的模式来匹配您的输入。使用 <代码>DateTimeFormatter类。

DateTimeFormatter.ofPattern ( "EEE, dd MMM uuuu HH:mm:ss O" )

Locale

我们需要一个Locale来指定翻译月份名称和星期名称时使用的人类语言和文化规范。

Locale locale = Locale.of ( "en" , "US" );
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "EEE, dd MMM uuuu HH:mm:ss O" ).withLocale ( locale );

OffsetDateTime

解析为 OffsetDateTime,表示从 UTC 时间子午线偏移所看到的时刻。

在这种情况下,与 UTC 的偏移量为零小时-分钟-秒。如下所示为 Z,发音为“Zulu”。

String input = "Sun, 04 Dec 2011 18:40:22 GMT+0";
OffsetDateTime odt = OffsetDateTime.parse ( input , f );

结果:

odt.toString() = 2011-12-04T18:40:22Z

tl;dr

Use modern java.time classes.

OffsetDateTime
        .parse (
                "Sun, 04 Dec 2011 18:40:22 GMT+0" ,
                DateTimeFormatter
                        .ofPattern ( "EEE, dd MMM uuuu HH:mm:ss O" )
                        .withLocale ( Locale.of ( "en" , "US" ) )
        )
        .toString ( )

java.time in modern Java

Avoid the terribly-flawed legacy classes such as Calendar, Date, and SimpleDateFormat. Use only the java.time classes in Java 8+.

RFC 822 & 1123

Your input string "Sun, 04 Dec 2011 18:40:22 GMT+0" seems to be a screwy version of the outmoded standard format defined in RFC 822 & RFC 1123. Java comes with a predefined formatter RFC_1123_DATE_TIME for those standards, but your input varies a bit too much for that to work.

Tip: For storing and exchanging date-time values textually, use only ISO 8601 formats.

DateTimeFormatter

So we need to define our own pattern to match your input. Use DateTimeFormatter class.

DateTimeFormatter.ofPattern ( "EEE, dd MMM uuuu HH:mm:ss O" )

Locale

We need a Locale to specify the human language and cultural norms to be used in translating the name of the month and name of the day-of-week.

Locale locale = Locale.of ( "en" , "US" );
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "EEE, dd MMM uuuu HH:mm:ss O" ).withLocale ( locale );

OffsetDateTime

Parse as a OffsetDateTime, to represent a moment as seen with an offset from the temporal meridian of UTC.

In this case the offset is zero hours-minutes-seconds from UTC. Shown below as Z, pronounced “Zulu”.

String input = "Sun, 04 Dec 2011 18:40:22 GMT+0";
OffsetDateTime odt = OffsetDateTime.parse ( input , f );

Result:

odt.toString() = 2011-12-04T18:40:22Z

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文