Java SimpleDateFormat将解析字符串解释为UTC

wut*_*aer 8 java date

我的时区是GMT + 1.

所以"日期"对象与"22.09.1985 00:00UTC"在tostring函数上打印"Sun Sep 22 01:00:00 CEST 1985".

现在我试图通过使用simpleDateFormat解析"22/09/1985"来创建这个日期

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getDefault());
Date d = sdf.parse("22/09/1985");
    => Sun Sep 22 00:00:00 CEST 1985

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date d = sdf.parse("22/09/1985");
    => Sun Sep 22 02:00:00 CEST 1985
Run Code Online (Sandbox Code Playgroud)

我如何配置simpledateformat它创建一个日期打印输出字符串"22/09/1985"的"Sun Sep 22 01:00:00 CEST 1985"?

wut*_*aer 11

我的假设错了,

22.09.1985 00:00UTC is actually 22.09.1985 02:00CET
Run Code Online (Sandbox Code Playgroud)

所以

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date d = sdf.parse("22/09/1985");
Run Code Online (Sandbox Code Playgroud)

正是我想要的,我比较它的日期是错误的.


Bas*_*que 5

避免使用 java.util.Date 和 Calendar

您已经找到了避免使用 java.util.Date 和 .Calendar 的众多原因之一。他们是出了名的麻烦。要么使用Joda-Time,要么在 Java 8 中使用受 Joda-Time 启发并由JSR 310定义的新java.time 包

在 StackOverflow 中搜索“joda date”以找到许多示例。

时区

你说:

我的时区是 GMT+1。

不正确,您本地与 UTC/GMT 的偏移量为 +01。那不是您的时区。时区是偏移量加上有关夏令时 (DST) 和其他异常的规则。

根据ISO 8601标准,该偏移量应该有两个数字:+01(或+01:00) 而不是。+1

避免使用 3 或 4 个字母的代码,例如 CET。它们既不标准化也不独特。使用正确的时区名称

一般来说,您应该在所有日期时间工作中指定一个时区,而不是依赖当前 JVM 的默认值。

在 Joda-Time 和 java.time 中,日期时间对象真正知道其分配的时区。java.util.Date 没有时区,但似乎是因为它toString在创建 String 表示时应用了默认时区,正如您遗憾地学到的那样。

示例代码

一些使用 Joda-Time 2.3 的代码。

String input = "22/09/1985";

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Amsterdam" );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd/MM/yyyy" );
DateTime dateTime = formatter.withZone( timeZone ).parseDateTime( input );
DateTime dateTimeUtcGmt = dateTime.withZone( DateTimeZone.UTC );
DateTime dateTimeIndia = dateTime.withZone( DateTimeZone.forID( "Asia/Kolkata" ) );
String outputMontreal = DateTimeFormat.forStyle( "FF" ).withZone( DateTimeZone.forID( "America/Montreal" ) ).withLocale( Locale.CANADA_FRENCH ).print( dateTime );
// All of the above date-time represent the very same moment in the timeline of the Universe.
Run Code Online (Sandbox Code Playgroud)

转储到控制台...

System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTimeUtcGmt: " + dateTimeUtcGmt );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "outputMontreal: " + outputMontreal );
Run Code Online (Sandbox Code Playgroud)

运行时…

String input = "22/09/1985";

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Amsterdam" );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd/MM/yyyy" );
DateTime dateTime = formatter.withZone( timeZone ).parseDateTime( input );
DateTime dateTimeUtcGmt = dateTime.withZone( DateTimeZone.UTC );
DateTime dateTimeIndia = dateTime.withZone( DateTimeZone.forID( "Asia/Kolkata" ) );
String outputMontreal = DateTimeFormat.forStyle( "FF" ).withZone( DateTimeZone.forID( "America/Montreal" ) ).withLocale( Locale.CANADA_FRENCH ).print( dateTime );
// All of the above date-time represent the very same moment in the timeline of the Universe.
Run Code Online (Sandbox Code Playgroud)