我在创建Date对象时遇到了一个奇怪的问题。我有以下代码将日期的时区设置为UTC。在解析语句之前我看到sdfDate的时区为UTC但是在解析语句之后我看到punchDate有值:Sat Mar 30 01:00:00 CET 2013,我相信这是来自我的系统。但是,我如何确保即使在解析后时区也保持不变。
Date punchDate = null;
Date punchTime = null;
SimpleDateFormat sdfDate = new SimpleDateFormat("dd.MM.yyyy");
SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm:ss");
try
{
sdfDate.setTimeZone(TimeZone.getTimeZone("UTC"));
sdfTime.setTimeZone(TimeZone.getTimeZone("UTC"));
punchDate = sdfDate.parse(arg1);
punchTime = sdfTime.parse(arg2);
}
catch (ParseException pe)
{
System.out.println("Parse exception " +pe.getMessage());
}
我的要求基本上是我需要从字符串输入中创建一个Date对象,但时区应保持UTC。
答案 0 :(得分:3)
我需要从字符串输入中创建一个Date对象,但时区应保持UTC。
LocalDate.parse(
"23.01.2017" ,
DateTimeFormatter.ofPattern( "dd.MM.uuuu" )
)
...和...
LocalTime.parse( "12:34:56" )
...结合...
OffsetDateTime.of( datePart , timePart , ZoneOffset.UTC )
您正在使用麻烦的令人困惑的旧日期时间类,现在已被java.time类取代。
OffsetDateTime
你说你确定你的输入是用于UTC的,尽管没有这样的指标。因此,我们将解析日期部分,解析时间部分,然后在为offset-from-UTC分配UTC零时进行组合。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd.MM.uuuu" ) ;
LocalDate ld = LocalDate.parse( "23.01.2017" , f ) ;
时间输入恰好符合java.time类中默认使用的标准ISO 8601格式。因此无需指定格式化模式。
LocalTime lt = LocalTime.parse( "12:34:56" ) ;
联合
OffsetDateTime odt = OffsetDateTime.of( ld , lt , ZoneOffset.UTC ) ;
如果您希望看到特定区域的挂钟时间中显示的相同时刻,请应用ZoneId
获取ZonedDateTime
。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "Europe/Paris" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ; // Same simultaneous moment, same point on the timeline.
提示:要将此类数据作为文本进行交换,请仅使用标准ISO 8601格式。这些格式设计合理,非常明确,易于通过机器处理,并且易于人们阅读多种文化。
在解析和生成字符串时,java.time类默认使用标准格式。
String output = Instant.now().toString() ;
2017-01-23T12:34:56.123456789Z
避免遗留java.util.Date
课程。但如果你必须,你可以转换。查看添加到旧类的新方法。
Instant
类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。
通过致电Instant
,从OffsetDateTime
中提取toString
个对象。
Instant instant = odt.toInstant() ;
java.util.Date date = Date.fromInstant( instant ) ;
......走另一条路......
Instant instant = myJavaUtilDate.toInstant() ;
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 1 :(得分:0)
您的日期对象与本地系统时间相同。 您已使用本地时区创建本地日期对象,并将转换后的(UTC)时区分配给本地。
Date punchDate = null;
Date punchTime = null;
所以您的日期值保持不变,但它显示在不同的时区值。