Java 中没有时区偏移的 SimpleDateFormat (GMT+00:00) 用于自定义时区

发布于 2024-12-17 10:36:55 字数 628 浏览 3 评论 0 原文

是否可以使用 SimpleDateFormat 类在 Java 中格式化日期时间,以给出日期的时区部分,而无需在其后添加 +0000。

编辑

我们正在更改 Java 中的默认时区,如下所示:

SimpleTimeZone tz = new SimpleTimeZone(0, "Out Timezone");        
TimeZone.setDefault(tz);

不幸的是,我无法删除此代码。我会冒险猜测整个系统停止工作。我认为最初的作者这样做是为了解决一些夏令时问题。

考虑到这一点,我想将日期格式设置为:

2011-12-27 09:00 GMT

2011-12-27 09:00 BST

我只能得到SimpleDateFormat 输出为:

2011-12-27 09:00:00 GMT+00:00

使用格式字符串yyyy-MM-dd HH:mm:ss z

我看不到任何简单时区引用冬季时间 (GMT) id 或夏季时间 id (BST) 的地方。

Is it possible to format a date time in Java using the SimpleDateFormat class to give the timezone part of a date without having the +0000 after it.

Edit

We are changing the Default Timezone within Java as follows:

SimpleTimeZone tz = new SimpleTimeZone(0, "Out Timezone");        
TimeZone.setDefault(tz);

Unfortunately, I am in no position to remove this code. I would hazard a guess at the whole system stopping working. I think the initial author put this in to work around some day light saving issues.

With this in mind, I want to format the date as:

2011-12-27 09:00 GMT

or

2011-12-27 09:00 BST

I can only get the SimpleDateFormat to output as:

2011-12-27 09:00:00 GMT+00:00

which uses the format string yyyy-MM-dd HH:mm:ss z

I cannot see anywhere where the simple timezone has any reference to winter time (GMT) id or summer time id (BST).

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

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

发布评论

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

评论(5

冷情 2024-12-24 10:36:55

这个问题和答案现在已经过时了。它们使用 Java 8 及更高版本中内置的 java.time 框架过时的旧日期时间类。旧的类设计不佳、混乱且麻烦; 避开它们

避免使用 3-4 个字母的区域代码

避免使用 3-4 个字母的代码,例如 BST。它们既不是标准化的也不是独特的。它们实际上并不代表时区。它们给夏令时 (DST) 问题带来了更多混乱。

相反,请使用正确的时区。大多数都是大陆/地区格式,例如Europe/London< /代码>

避免设置默认时区

调用 java.util.TimeZone.setDefault 仅应在最极端的情况下执行。此调用会在运行时立即影响 JVM 内所有应用程序的所有线程中运行的所有代码。

相反,在所有日期时间代码中,指定所需/预期的时区。如果省略,Java 将隐式依赖 JVM 当前的默认时区。如上所述,此默认值可以在运行时随时更改!相反,明确指定。如果您定期将所需/预期的时区指定为传递的参数,则当前的默认时区没有实际意义,无关紧要。

java.time

java.time 框架内置于 Java 8 及更高版本中。请参阅教程。由 JSR 310 定义。受到非常成功的 Joda-Time 库的启发。

Instant

Instant 是 UTC 时间轴上的某个时刻。

以下示例显示了 java.time 类在标准 ISO 8601 格式,无需指定解析模式。使用 DateTimeFormatter 类指定其他非标准模式。

Instant instant = Instant.parse( "2011-12-27T09:00:00Z" );

ZonedDateTime

根据需要应用时区,生成 ZonedDateTime

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );

生成字符串

您可以使用 DateTimeFormatter 生成 ZonedDateTime 对象的文本表示形式。您可以指定自定义模式。或者,正如我建议的那样,让 java.time 为您进行本地化。

DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM );

最好指定所需/预期的 Locale< /code> 与时区的原因相同……JVM 中运行的任何应用程序的任何线程中的任何代码都可以随时更改 JVM 的当前默认值。 Locale 确定 (a) 用于日期和时间名称的人类语言。月,以及 (b) 文化规范,例如逗号与句号,以及各部分的顺序,例如先出现月、日或年。

formatter = formatter.withLocale( Locale.CANADA_FRENCH );
String output = zdt.format( formatter );

关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧遗留日期时间类,例如java.util.Date, 日历, & ; SimpleDateFormat

Joda-Time 项目,现已在 维护模式,建议迁移到java.time 类。

要了解更多信息,请参阅 Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范为 JSR 310

您可以直接与数据库交换java.time对象。使用符合 JDBC 驱动程序 /jeps/170" rel="nofollow noreferrer">JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* 类。

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time 。该项目是 java.time 未来可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如 间隔YearWeekYearQuarter更多

This Question and the Answers are now outmoded. They use old date-time classes outmoded by the java.time framework built into Java 8 and later. The old classes are poorly designed, confusing, and troublesome; Avoid them.

Avoid 3-4 Letter Zone Codes

Avoid the 3-4 letter codes such as BST. They are neither standardized nor unique. They do not actually represent time zones. And they add even more confusion to the problem of Daylight Saving Time (DST).

Instead, use proper time zones. Most are continent/region format such as Europe/London.

Avoid setting default time zone

Calling java.util.TimeZone.setDefault should be done only in the most extreme cases. This call affects all code running in all threads of all apps within the JVM immediately during runtime.

Instead, in all your date-time code, specify the desired/expected time zone. If omitted, Java falls back by implicitly relying on the JVM’s current default time zone. As noted above this default can change at any moment during runtime! Instead, specify explicitly. If you specify your desired/expected time zone as a passed argument routinely then the current default time zone is moot, irrelevant.

java.time

The java.time framework is built into Java 8 and later. See Tutorial. Defined by JSR 310. Inspired by the highly successful Joda-Time library.

Instant

An Instant is a moment on the timeline in UTC.

The following example shows how the java.time classes can parse/generate strings by default if in standard ISO 8601 format, with no need to specify a parsing pattern. Use DateTimeFormatter class to specify other non-standard patterns.

Instant instant = Instant.parse( "2011-12-27T09:00:00Z" );

ZonedDateTime

Apply a time zone as needed, producing a ZonedDateTime.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );

Generating Strings

You can produce textual representations of the ZonedDateTime object using a DateTimeFormatter. You can specify custom patterns. Or, as I recommend, let java.time localize for you.

DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM );

Best to specify the desired/expected Locale for the same reason as time zone… the JVM’s current default can be changed at any moment by any code in any thread of any app running within the JVM. The Locale determines (a) the human language used for names of day & month, and (b) the cultural norms such as commas versus periods and the order of the parts such as month or day or year coming first.

formatter = formatter.withLocale( Locale.CANADA_FRENCH );
String output = zdt.format( formatter );

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

海风掠过北极光 2024-12-24 10:36:55

我认为您使用的模式符合您的要求,但是 JDK 不知道您的时区名称,因此它切换为使用 GMT 偏移值 代替。

当我使用您的模式格式化日期时,时区部分得到“GMT”。

TimeZone.getDefault().getDisplayName() 为您提供了什么?对我来说,我得到的是“格林威治标准时间”。

I think that you are using the correct pattern for your requirements, however the JDK doesn't know the name of your timezone, so it switches over to using a GMT offset value instead.

When I format a date using your pattern, I get "GMT" for the timezone part.

What does TimeZone.getDefault().getDisplayName() give you? For me, I get "Greenwich Mean Time".

回首观望 2024-12-24 10:36:55

根本不是一个优雅的解决方案,但它对我们有用。我必须为 DateFormat/SimpleDateFormat 创建自定义实现。这看起来如下:

static {
    // this would be initialized like something as follows when the application starts
    // which causes the headaches of SimpleDateFormat not to work...
    SimpleTimeZone tz = new SimpleTimeZone(0, "Out Timezone");             
    TimeZone.setDefault(tz);  
}

// therefore this class will workaround the issue, 

public class OurOwnCustomDateFormat
    extends SimpleDateFormat {

    /** The pattern to use as the format string. */
    protected String pattern;

    public OurOwnCustomDateFormat(String pattern) {
         super(pattern);
         // store the pattern
         this.pattern = pattern;
    }

    @Override
    public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos) {

         // custom implementation to format the date and time based on our TimeZone            
         toAppendTo.insert(pos.getBeginIndex(), "the date with our custom format calculated here");
         return toAppendTo; 
    }

Not an elegant solution at all but it works for us. I had to create a custom implementation for DateFormat/SimpleDateFormat. This looks like something as follows:

static {
    // this would be initialized like something as follows when the application starts
    // which causes the headaches of SimpleDateFormat not to work...
    SimpleTimeZone tz = new SimpleTimeZone(0, "Out Timezone");             
    TimeZone.setDefault(tz);  
}

// therefore this class will workaround the issue, 

public class OurOwnCustomDateFormat
    extends SimpleDateFormat {

    /** The pattern to use as the format string. */
    protected String pattern;

    public OurOwnCustomDateFormat(String pattern) {
         super(pattern);
         // store the pattern
         this.pattern = pattern;
    }

    @Override
    public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos) {

         // custom implementation to format the date and time based on our TimeZone            
         toAppendTo.insert(pos.getBeginIndex(), "the date with our custom format calculated here");
         return toAppendTo; 
    }
合久必婚 2024-12-24 10:36:55

因为我无法在我的计算机上重现这个问题。我想这与本地化有关。试试这个

System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z",Locale.US).format(new Date()));

希望这有帮助。

Since I cannot reproduce this problem on my computer. I guess this would relate about localization. Try this

System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z",Locale.US).format(new Date()));

Hope this helps.

孤者何惧 2024-12-24 10:36:55

System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z").format(new Date())); 对我来说只是返回 2011-11 -22 13:42:16 GMT - 所以似乎可以按您的意愿工作。看起来这可能是其他地方的问题,但您不需要创建自己的格式化程序类。

System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z").format(new Date())); for me just returns 2011-11-22 13:42:16 GMT - so appears to work as you wish. Looks like it might be a problem elsewhere, you shouldn't need to create your own formatter class though.

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