对于自定义时区,不带Java(GMT+;00:00)时区偏移量的SimpleDataFormat

对于自定义时区,不带Java(GMT+;00:00)时区偏移量的SimpleDataFormat,java,timezone,simpledateformat,Java,Timezone,Simpledateformat,是否可以使用SimpleDataFormat类在Java中格式化日期时间,以给出日期的时区部分,而不在其后面加上+0000 编辑 我们正在更改Java中的默认时区,如下所示: SimpleTimeZone tz = new SimpleTimeZone(0, "Out Timezone"); TimeZone.setDefault(tz); static { // this would be initialized like something as follows w

是否可以使用SimpleDataFormat类在Java中格式化日期时间,以给出日期的时区部分,而不在其后面加上+0000

编辑

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

SimpleTimeZone tz = new SimpleTimeZone(0, "Out Timezone");        
TimeZone.setDefault(tz);
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; 
    }
不幸的是,我无法删除此代码。我会冒险猜测整个系统停止工作。我认为最初的作者把这个放进去是为了解决一些白天的节能问题

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

2011-12-27 09:00GMT

2011-12-27英国夏令时09:00

我只能将SimpleDataFormat输出为:

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

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


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

我认为您使用的模式符合您的要求,但是JDK不知道您的时区名称,因此它转而使用了

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


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

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

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

希望这能有所帮助。

System.out.println(新的SimpleDataFormat(“yyy-MM-dd-HH:MM:ss z”).format(new-Date())
对于我来说,只需返回
2011-11-22 13:42:16 GMT
——这样看起来就可以按照您的意愿工作了。看起来这在其他地方可能是个问题,不过您不需要创建自己的格式化程序类。

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

SimpleTimeZone tz = new SimpleTimeZone(0, "Out Timezone");        
TimeZone.setDefault(tz);
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; 
    }

这个问题和答案现在已经过时了。他们使用旧的日期时间类,这些类被java 8及更高版本中内置的java.time框架所淘汰。旧的类设计拙劣、混乱且麻烦避开它们

避免使用3-4个字母的区号 避免使用3-4个字母的代码,例如
BST
。它们既不是标准化的,也不是独特的。它们实际上并不代表时区。而且,他们给夏令时(DST)问题增添了更多的困惑

相反,使用。大多数是
大陆/地区
格式,例如

避免设置默认时区 只有在最极端的情况下才能调用。此调用会在运行时立即影响JVM中所有应用程序的所有线程中运行的所有代码

相反,在所有日期时间代码中,指定所需/预期时区。如果省略,Java会通过隐式依赖JVM的当前默认时区而后退。如上所述,此默认值可以在运行时的任何时刻更改!而是显式地指定。如果将所需/预期时区指定为已通过的参数,则当前默认时区是无意义的,不相关的

java.time java.time框架内置于Java8及更高版本中。看见由JSR310定义。灵感来源于非常成功的Joda Time library

Instant
即时
是UTC时间线上的一个时刻

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

Instant instant = Instant.parse( "2011-12-27T09:00:00Z" );
ZoneDateTime
根据需要应用时区,生成一个新的时区

生成字符串 您可以使用
DateTimeFormatter
生成ZoneDateTime对象的文本表示。您可以指定自定义模式。或者,正如我所建议的,让java.time为您本地化

DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM );
最好指定所需/预期的值,原因与时区相同……JVM中运行的任何应用程序的任何线程中的任何代码都可以随时更改JVM的当前默认值。
Locale
确定了(a)用于日期和月份名称的人类语言,以及(b)文化规范,如逗号与句点,以及部分顺序,如月、日或年的先后顺序

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

关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

该项目现已启动,建议迁移到类

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*

从哪里获得java.time类

  • 、和更高版本-标准Java API的一部分,带有捆绑实现。
    • Java9添加了一些次要功能和修复
    • 大多数java.time功能都在中向后移植到Java6和Java7
    • 更高版本的Android捆绑包实现了java.time类

    • 对于早期的Android(
      System.out.println(新的SimpleDataFormat(“yyyy-MM-dd HH:MM:ss z”).format(新的日期())
      对于我来说只返回
      2011-11-22 13:42:16 GMT
      。这行是否也为您显示偏移量?@berry120-是的,可以。从外观上看,这可能是我使用SimpleDateFormat的JIDE组件的问题。将进一步调查。将此作为答案,我将接受它。谢谢Andez。这是p在Windows 7 x64上的Eclipse Indigo SR1中的JDK 1.7.0和1.6.0_23上,我也可以打印GMT+偏移量。我不知道为什么其他人不能获得+偏移量以及如何消除它。@BalusC我想如果JDK不知道您所在时区的名称,就会发生这种情况