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

And*_*dez 12 java timezone simpledateformat

是否可以使用SimpleDateFormat类格式化Java中的日期时间,以使日期的时区部分在其后面没有+0000.

编辑

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

SimpleTimeZone tz = new SimpleTimeZone(0, "Out Timezone");        
TimeZone.setDefault(tz);
Run Code Online (Sandbox Code Playgroud)

不幸的是,我无法删除此代码.我会猜测整个系统停止工作.我认为最初的作者把这个用于解决某些节能问题.

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

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)有任何参考的地方.

有什么想法吗?

谢谢

Andez

Bas*_*que 6

这个问题和答案现在已经过时了.它们使用旧的日期时间类,这些类已经过了Java 8及更高版本中内置的java.time框架.旧班设计糟糕,令人困惑,麻烦; 避免他们.

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

避免使用3-4个字母代码BST.它们既不标准也不独特.它们实际上并不代表时区.而且它们对夏令时(DST)的问题更加困惑.

相反,使用适当的时区.大多数是continent/region格式,如Europe/London.

避免设置默认时区

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

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

java.time

java.time框架内置于Java 8及更高版本中.请参阅教程.由JSR 310定义.灵感来自非常成功的Joda-Time库.

Instant

An Instant是UTC时间轴上的一个时刻.

以下示例显示了java.time类如果采用标准ISO 8601格式,默认情况下如何解析/生成字符串,而无需指定解析模式.使用DateTimeFormatterclass指定其他非标准模式.

Instant instant = Instant.parse( "2011-12-27T09:00:00Z" );
Run Code Online (Sandbox Code Playgroud)

ZonedDateTime

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

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );
Run Code Online (Sandbox Code Playgroud)

生成字符串

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

DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM );
Run Code Online (Sandbox Code Playgroud)

最好指定期望/期望Locale的原因与时区相同... JVM的当前默认值可以随时由JVM中运行的任何应用程序的任何线程中的任何代码更改.该Locale决定(一)用于日和月的名称的人类语言,和(b)的文化规范,如逗号与周期和部件,如一个月或一天或一年即将到来第一的顺序.

formatter = formatter.withLocale( Locale.CANADA_FRENCH );
String output = zdt.format( formatter );
Run Code Online (Sandbox Code Playgroud)

关于java.time

java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.

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

要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.

您可以直接与数据库交换java.time对象.使用符合JDBC 4.2或更高版本的JDBC驱动程序.不需要字符串,不需要课程.java.sql.*

从哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval,YearWeek,YearQuarter,和更多.


And*_*dez 3

根本不是一个优雅的解决方案,但它对我们有用。我必须为 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; 
    }
Run Code Online (Sandbox Code Playgroud)