Java SimpleDataFormat将解析字符串解释为UTC
我的时区是GMT+1 因此,带有“22.09.1985 00:00UTC”的“日期”对象在tostring函数上打印“Sun Sep 22 01:00:00 CEST 1985” 现在我正试图通过使用SimpleDataFormat解析“22/09/1985”来创建这个日期Java SimpleDataFormat将解析字符串解释为UTC,java,date,Java,Date,我的时区是GMT+1 因此,带有“22.09.1985 00:00UTC”的“日期”对象在tostring函数上打印“Sun Sep 22 01:00:00 CEST 1985” 现在我正试图通过使用SimpleDataFormat解析“22/09/1985”来创建这个日期 SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); sdf.setTimeZone(TimeZone.getDefault()); Date d = sdf.
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
如何配置SimpleDataFormat,使其创建一个打印“Sun Sep 22 01:00:00 CEST 1985”的日期,并使用输入字符串“22/09/1985”?使用特定时区解析日期字符串的事实不会使打印的
日期对象使用该时区。您仍然在使用相同的Date#toString()
实现,它使用默认时区格式化Date
对象
您需要的是使用该SimpleDateFormat
对象设置日期对象的格式。如果您有该特定字符串,则需要另一个SimpleDateFormat
对象来解析该字符串:
String dateString = "22/09/1985";
SimpleDateFormat parser = new SimpleDateFormat("dd/MM/yyyy");
Date parsedDate = parser.parse(dateString);
SimpleDateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(formatter.format(parsedDate));
JavaDate
没有与之关联的时区概念。只能使用指定的时区格式化日期
对象,并获取字符串。或者,切换到。Date
是一个相对“哑”的类,因为它只表示UTC 1970-01-01 00:00:00以来的毫秒数
如果你想打印出一个日期,就像它是一个不同的时区一样,你需要为这个时区构造一个日期格式
/简化格式
,并以这种方式将它转换成一个字符串。我的假设是错误的
22.09.1985 00:00UTC is actually 22.09.1985 02:00CET
所以
这正是我想要的,我比较它的日期是错误的。避免java.util.date和Calendar
您已经找到了避免使用java.util.Date&.Calendar的众多原因之一。他们是出了名的麻烦。要么使用,要么在Java8中使用新的,其灵感来源于Joda Time,定义为
在StackOverflow中搜索“joda date”可以找到许多示例
时区
你说:
我的时区是GMT+1
不正确,您与UTC/GMT的本地偏移量为+01。那不是你的时区。时区是一个偏移量加上有关夏令时(DST)和其他异常的规则
根据标准,偏移量应该有两位数:+01
(或+01:00
),而不是+1
避免使用三个或四个字母的代码,如CET。它们既不是标准化的,也不是独特的。使用
一般来说,您应该在所有日期时间工作中指定时区,而不是依赖于当前JVM的默认值
在Joda Time和java.Time中,日期时间对象确实知道其指定的时区。java.util.Date没有时区,但似乎是因为它的toString
在创建字符串表示时应用了默认时区,这是您很遗憾地了解到的
示例代码
一些代码使用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.
转储到控制台
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTimeUtcGmt: " + dateTimeUtcGmt );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "outputMontreal: " + outputMontreal );
当运行时
日期时间:1985-09-22T00:00:00.000+02:00
日期时间UTCGMT:1985-09-21T22:00:00.000Z
印度时间:1985-09-22T03:30:00.000+05:30
输出蒙特利尔:samedi 1985年9月21日18小时00分
使用简化格式(“EEE-MMM-d-HH:mm:ss-z-dd/mm/YYYY”)
因此,如果不在字符串中定义时区,sdf就不可能将字符串解释为UTC??严格来说,所有日期
对象都基于UTC,因为自1970-01-01 00:00 UTC以来,它在内部存储为毫秒数。使用第二个DateFormat
在正确的时区显示日期的实际文本。您没有理解我:我知道“date”没有时区。。。但是,我如何在不考虑任何时区的情况下解析日期呢?date对象仍然具有值“Sun Sep 22 00:00:00 CEST 1985”,这不是我想要的want@wutzebaerDate对象没有时区的概念。您只能将其格式化为特定时区的日期字符串wrt。我建议您查看JodaTime库,它在处理日期时更好。@RohitJain库存JDK库没有任何Calendar
格式类,这一直困扰着我,因为Calendar
是在时区重要时使用的。@Powerlord,对于一个特定的日期,获取一个日历
实例是一件令人头疼的事情。这是Java API中最糟糕的部分。@Powerlord,正在等待另一个Maven编译,嗯?;)
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTimeUtcGmt: " + dateTimeUtcGmt );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "outputMontreal: " + outputMontreal );