Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
b44cf83b
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
b44cf83b
编写于
6月 11, 2014
作者:
S
scolebourne
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8046416: Unable to parse an Instant from fields
Summary: Fix Instant parsing Reviewed-by: rriggs
上级
ea2f8b1f
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
374 addition
and
2 deletion
+374
-2
src/share/classes/java/time/Instant.java
src/share/classes/java/time/Instant.java
+1
-1
src/share/classes/java/time/format/DateTimeFormatterBuilder.java
...re/classes/java/time/format/DateTimeFormatterBuilder.java
+1
-1
src/share/classes/java/time/format/Parsed.java
src/share/classes/java/time/format/Parsed.java
+67
-0
test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java
...a/time/tck/java/time/format/TCKDateTimeParseResolver.java
+101
-0
test/java/time/test/java/time/format/TestDateTimeParsing.java
.../java/time/test/java/time/format/TestDateTimeParsing.java
+204
-0
未找到文件。
src/share/classes/java/time/Instant.java
浏览文件 @
b44cf83b
...
@@ -375,7 +375,7 @@ public final class Instant
...
@@ -375,7 +375,7 @@ public final class Instant
return
Instant
.
ofEpochSecond
(
instantSecs
,
nanoOfSecond
);
return
Instant
.
ofEpochSecond
(
instantSecs
,
nanoOfSecond
);
}
catch
(
DateTimeException
ex
)
{
}
catch
(
DateTimeException
ex
)
{
throw
new
DateTimeException
(
"Unable to obtain Instant from TemporalAccessor: "
+
throw
new
DateTimeException
(
"Unable to obtain Instant from TemporalAccessor: "
+
temporal
+
" of type "
+
temporal
.
getClass
().
getName
());
temporal
+
" of type "
+
temporal
.
getClass
().
getName
()
,
ex
);
}
}
}
}
...
...
src/share/classes/java/time/format/DateTimeFormatterBuilder.java
浏览文件 @
b44cf83b
...
@@ -3286,7 +3286,7 @@ public final class DateTimeFormatterBuilder {
...
@@ -3286,7 +3286,7 @@ public final class DateTimeFormatterBuilder {
}
catch
(
RuntimeException
ex
)
{
}
catch
(
RuntimeException
ex
)
{
return
~
position
;
return
~
position
;
}
}
int
successPos
=
text
.
length
()
;
int
successPos
=
pos
;
successPos
=
context
.
setParsedField
(
INSTANT_SECONDS
,
instantSecs
,
position
,
successPos
);
successPos
=
context
.
setParsedField
(
INSTANT_SECONDS
,
instantSecs
,
position
,
successPos
);
return
context
.
setParsedField
(
NANO_OF_SECOND
,
nano
,
position
,
successPos
);
return
context
.
setParsedField
(
NANO_OF_SECOND
,
nano
,
position
,
successPos
);
}
}
...
...
src/share/classes/java/time/format/Parsed.java
浏览文件 @
b44cf83b
...
@@ -66,6 +66,7 @@ import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_AMPM;
...
@@ -66,6 +66,7 @@ import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_AMPM;
import
static
java
.
time
.
temporal
.
ChronoField
.
CLOCK_HOUR_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
CLOCK_HOUR_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
HOUR_OF_AMPM
;
import
static
java
.
time
.
temporal
.
ChronoField
.
HOUR_OF_AMPM
;
import
static
java
.
time
.
temporal
.
ChronoField
.
HOUR_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
HOUR_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
INSTANT_SECONDS
;
import
static
java
.
time
.
temporal
.
ChronoField
.
MICRO_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
MICRO_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
MICRO_OF_SECOND
;
import
static
java
.
time
.
temporal
.
ChronoField
.
MICRO_OF_SECOND
;
import
static
java
.
time
.
temporal
.
ChronoField
.
MILLI_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
MILLI_OF_DAY
;
...
@@ -74,14 +75,17 @@ import static java.time.temporal.ChronoField.MINUTE_OF_DAY;
...
@@ -74,14 +75,17 @@ import static java.time.temporal.ChronoField.MINUTE_OF_DAY;
import
static
java
.
time
.
temporal
.
ChronoField
.
MINUTE_OF_HOUR
;
import
static
java
.
time
.
temporal
.
ChronoField
.
MINUTE_OF_HOUR
;
import
static
java
.
time
.
temporal
.
ChronoField
.
NANO_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
NANO_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
NANO_OF_SECOND
;
import
static
java
.
time
.
temporal
.
ChronoField
.
NANO_OF_SECOND
;
import
static
java
.
time
.
temporal
.
ChronoField
.
OFFSET_SECONDS
;
import
static
java
.
time
.
temporal
.
ChronoField
.
SECOND_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
SECOND_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
SECOND_OF_MINUTE
;
import
static
java
.
time
.
temporal
.
ChronoField
.
SECOND_OF_MINUTE
;
import
java.time.DateTimeException
;
import
java.time.DateTimeException
;
import
java.time.Instant
;
import
java.time.LocalDate
;
import
java.time.LocalDate
;
import
java.time.LocalTime
;
import
java.time.LocalTime
;
import
java.time.Period
;
import
java.time.Period
;
import
java.time.ZoneId
;
import
java.time.ZoneId
;
import
java.time.ZoneOffset
;
import
java.time.chrono.ChronoLocalDate
;
import
java.time.chrono.ChronoLocalDate
;
import
java.time.chrono.ChronoLocalDateTime
;
import
java.time.chrono.ChronoLocalDateTime
;
import
java.time.chrono.ChronoZonedDateTime
;
import
java.time.chrono.ChronoZonedDateTime
;
...
@@ -241,12 +245,15 @@ final class Parsed implements TemporalAccessor {
...
@@ -241,12 +245,15 @@ final class Parsed implements TemporalAccessor {
resolveTimeLenient
();
resolveTimeLenient
();
crossCheck
();
crossCheck
();
resolvePeriod
();
resolvePeriod
();
resolveFractional
();
resolveInstant
();
return
this
;
return
this
;
}
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
private
void
resolveFields
()
{
private
void
resolveFields
()
{
// resolve ChronoField
// resolve ChronoField
resolveInstantFields
();
resolveDateFields
();
resolveDateFields
();
resolveTimeFields
();
resolveTimeFields
();
...
@@ -300,6 +307,7 @@ final class Parsed implements TemporalAccessor {
...
@@ -300,6 +307,7 @@ final class Parsed implements TemporalAccessor {
}
}
// if something changed then have to redo ChronoField resolve
// if something changed then have to redo ChronoField resolve
if
(
changedCount
>
0
)
{
if
(
changedCount
>
0
)
{
resolveInstantFields
();
resolveDateFields
();
resolveDateFields
();
resolveTimeFields
();
resolveTimeFields
();
}
}
...
@@ -315,6 +323,29 @@ final class Parsed implements TemporalAccessor {
...
@@ -315,6 +323,29 @@ final class Parsed implements TemporalAccessor {
}
}
}
}
//-----------------------------------------------------------------------
private
void
resolveInstantFields
()
{
// resolve parsed instant seconds to date and time if zone available
if
(
fieldValues
.
containsKey
(
INSTANT_SECONDS
))
{
if
(
zone
!=
null
)
{
resolveInstantFields0
(
zone
);
}
else
{
Long
offsetSecs
=
fieldValues
.
get
(
OFFSET_SECONDS
);
if
(
offsetSecs
!=
null
)
{
ZoneOffset
offset
=
ZoneOffset
.
ofTotalSeconds
(
offsetSecs
.
intValue
());
resolveInstantFields0
(
offset
);
}
}
}
}
private
void
resolveInstantFields0
(
ZoneId
selectedZone
)
{
Instant
instant
=
Instant
.
ofEpochSecond
(
fieldValues
.
remove
(
INSTANT_SECONDS
));
ChronoZonedDateTime
<?>
zdt
=
chrono
.
zonedDateTime
(
instant
,
selectedZone
);
updateCheckConflict
(
zdt
.
toLocalDate
());
updateCheckConflict
(
INSTANT_SECONDS
,
SECOND_OF_DAY
,
(
long
)
zdt
.
toLocalTime
().
toSecondOfDay
());
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
private
void
resolveDateFields
()
{
private
void
resolveDateFields
()
{
updateCheckConflict
(
chrono
.
resolveDate
(
fieldValues
,
resolverStyle
));
updateCheckConflict
(
chrono
.
resolveDate
(
fieldValues
,
resolverStyle
));
...
@@ -533,6 +564,42 @@ final class Parsed implements TemporalAccessor {
...
@@ -533,6 +564,42 @@ final class Parsed implements TemporalAccessor {
}
}
}
}
private
void
resolveFractional
()
{
// ensure fractional seconds available as ChronoField requires
// resolveTimeLenient() will have merged MICRO_OF_SECOND/MILLI_OF_SECOND to NANO_OF_SECOND
if
(
time
==
null
&&
(
fieldValues
.
containsKey
(
INSTANT_SECONDS
)
||
fieldValues
.
containsKey
(
SECOND_OF_DAY
)
||
fieldValues
.
containsKey
(
SECOND_OF_MINUTE
)))
{
if
(
fieldValues
.
containsKey
(
NANO_OF_SECOND
))
{
long
nos
=
fieldValues
.
get
(
NANO_OF_SECOND
);
fieldValues
.
put
(
MICRO_OF_SECOND
,
nos
/
1000
);
fieldValues
.
put
(
MILLI_OF_SECOND
,
nos
/
1000000
);
}
else
{
fieldValues
.
put
(
NANO_OF_SECOND
,
0L
);
fieldValues
.
put
(
MICRO_OF_SECOND
,
0L
);
fieldValues
.
put
(
MILLI_OF_SECOND
,
0L
);
}
}
}
private
void
resolveInstant
()
{
// add instant seconds if we have date, time and zone
if
(
date
!=
null
&&
time
!=
null
)
{
if
(
zone
!=
null
)
{
long
instant
=
date
.
atTime
(
time
).
atZone
(
zone
).
getLong
(
ChronoField
.
INSTANT_SECONDS
);
fieldValues
.
put
(
INSTANT_SECONDS
,
instant
);
}
else
{
Long
offsetSecs
=
fieldValues
.
get
(
OFFSET_SECONDS
);
if
(
offsetSecs
!=
null
)
{
ZoneOffset
offset
=
ZoneOffset
.
ofTotalSeconds
(
offsetSecs
.
intValue
());
long
instant
=
date
.
atTime
(
time
).
atZone
(
offset
).
getLong
(
ChronoField
.
INSTANT_SECONDS
);
fieldValues
.
put
(
INSTANT_SECONDS
,
instant
);
}
}
}
}
private
void
updateCheckConflict
(
LocalTime
timeToSet
,
Period
periodToSet
)
{
private
void
updateCheckConflict
(
LocalTime
timeToSet
,
Period
periodToSet
)
{
if
(
time
!=
null
)
{
if
(
time
!=
null
)
{
if
(
time
.
equals
(
timeToSet
)
==
false
)
{
if
(
time
.
equals
(
timeToSet
)
==
false
)
{
...
...
test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java
浏览文件 @
b44cf83b
...
@@ -76,6 +76,7 @@ import static java.time.temporal.ChronoField.EPOCH_DAY;
...
@@ -76,6 +76,7 @@ import static java.time.temporal.ChronoField.EPOCH_DAY;
import
static
java
.
time
.
temporal
.
ChronoField
.
ERA
;
import
static
java
.
time
.
temporal
.
ChronoField
.
ERA
;
import
static
java
.
time
.
temporal
.
ChronoField
.
HOUR_OF_AMPM
;
import
static
java
.
time
.
temporal
.
ChronoField
.
HOUR_OF_AMPM
;
import
static
java
.
time
.
temporal
.
ChronoField
.
HOUR_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
HOUR_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
INSTANT_SECONDS
;
import
static
java
.
time
.
temporal
.
ChronoField
.
MICRO_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
MICRO_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
MICRO_OF_SECOND
;
import
static
java
.
time
.
temporal
.
ChronoField
.
MICRO_OF_SECOND
;
import
static
java
.
time
.
temporal
.
ChronoField
.
MILLI_OF_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
MILLI_OF_DAY
;
...
@@ -93,11 +94,13 @@ import static java.time.temporal.ChronoField.YEAR_OF_ERA;
...
@@ -93,11 +94,13 @@ import static java.time.temporal.ChronoField.YEAR_OF_ERA;
import
static
org
.
testng
.
Assert
.
assertEquals
;
import
static
org
.
testng
.
Assert
.
assertEquals
;
import
static
org
.
testng
.
Assert
.
fail
;
import
static
org
.
testng
.
Assert
.
fail
;
import
java.time.Instant
;
import
java.time.LocalDate
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.time.LocalDateTime
;
import
java.time.LocalTime
;
import
java.time.LocalTime
;
import
java.time.Period
;
import
java.time.Period
;
import
java.time.ZoneId
;
import
java.time.ZoneId
;
import
java.time.ZoneOffset
;
import
java.time.ZonedDateTime
;
import
java.time.ZonedDateTime
;
import
java.time.chrono.ChronoLocalDate
;
import
java.time.chrono.ChronoLocalDate
;
import
java.time.chrono.ChronoLocalDateTime
;
import
java.time.chrono.ChronoLocalDateTime
;
...
@@ -1159,4 +1162,102 @@ public class TCKDateTimeParseResolver {
...
@@ -1159,4 +1162,102 @@ public class TCKDateTimeParseResolver {
}
}
};
};
//-------------------------------------------------------------------------
// SPEC: ChronoField.INSTANT_SECONDS
@Test
public
void
test_parse_fromField_InstantSeconds
()
{
DateTimeFormatter
fmt
=
new
DateTimeFormatterBuilder
()
.
appendValue
(
INSTANT_SECONDS
).
toFormatter
();
TemporalAccessor
acc
=
fmt
.
parse
(
"86402"
);
Instant
expected
=
Instant
.
ofEpochSecond
(
86402
);
assertEquals
(
acc
.
isSupported
(
INSTANT_SECONDS
),
true
);
assertEquals
(
acc
.
isSupported
(
NANO_OF_SECOND
),
true
);
assertEquals
(
acc
.
isSupported
(
MICRO_OF_SECOND
),
true
);
assertEquals
(
acc
.
isSupported
(
MILLI_OF_SECOND
),
true
);
assertEquals
(
acc
.
getLong
(
INSTANT_SECONDS
),
86402L
);
assertEquals
(
acc
.
getLong
(
NANO_OF_SECOND
),
0L
);
assertEquals
(
acc
.
getLong
(
MICRO_OF_SECOND
),
0L
);
assertEquals
(
acc
.
getLong
(
MILLI_OF_SECOND
),
0L
);
assertEquals
(
Instant
.
from
(
acc
),
expected
);
}
@Test
public
void
test_parse_fromField_InstantSeconds_NanoOfSecond
()
{
DateTimeFormatter
fmt
=
new
DateTimeFormatterBuilder
()
.
appendValue
(
INSTANT_SECONDS
).
appendLiteral
(
'.'
).
appendValue
(
NANO_OF_SECOND
).
toFormatter
();
TemporalAccessor
acc
=
fmt
.
parse
(
"86402.123456789"
);
Instant
expected
=
Instant
.
ofEpochSecond
(
86402
,
123456789
);
assertEquals
(
acc
.
isSupported
(
INSTANT_SECONDS
),
true
);
assertEquals
(
acc
.
isSupported
(
NANO_OF_SECOND
),
true
);
assertEquals
(
acc
.
isSupported
(
MICRO_OF_SECOND
),
true
);
assertEquals
(
acc
.
isSupported
(
MILLI_OF_SECOND
),
true
);
assertEquals
(
acc
.
getLong
(
INSTANT_SECONDS
),
86402L
);
assertEquals
(
acc
.
getLong
(
NANO_OF_SECOND
),
123456789L
);
assertEquals
(
acc
.
getLong
(
MICRO_OF_SECOND
),
123456L
);
assertEquals
(
acc
.
getLong
(
MILLI_OF_SECOND
),
123L
);
assertEquals
(
Instant
.
from
(
acc
),
expected
);
}
// SPEC: ChronoField.SECOND_OF_DAY
@Test
public
void
test_parse_fromField_SecondOfDay
()
{
DateTimeFormatter
fmt
=
new
DateTimeFormatterBuilder
()
.
appendValue
(
SECOND_OF_DAY
).
toFormatter
();
TemporalAccessor
acc
=
fmt
.
parse
(
"864"
);
assertEquals
(
acc
.
isSupported
(
SECOND_OF_DAY
),
true
);
assertEquals
(
acc
.
isSupported
(
NANO_OF_SECOND
),
true
);
assertEquals
(
acc
.
isSupported
(
MICRO_OF_SECOND
),
true
);
assertEquals
(
acc
.
isSupported
(
MILLI_OF_SECOND
),
true
);
assertEquals
(
acc
.
getLong
(
SECOND_OF_DAY
),
864L
);
assertEquals
(
acc
.
getLong
(
NANO_OF_SECOND
),
0L
);
assertEquals
(
acc
.
getLong
(
MICRO_OF_SECOND
),
0L
);
assertEquals
(
acc
.
getLong
(
MILLI_OF_SECOND
),
0L
);
}
@Test
public
void
test_parse_fromField_SecondOfDay_NanoOfSecond
()
{
DateTimeFormatter
fmt
=
new
DateTimeFormatterBuilder
()
.
appendValue
(
SECOND_OF_DAY
).
appendLiteral
(
'.'
).
appendValue
(
NANO_OF_SECOND
).
toFormatter
();
TemporalAccessor
acc
=
fmt
.
parse
(
"864.123456789"
);
assertEquals
(
acc
.
isSupported
(
SECOND_OF_DAY
),
true
);
assertEquals
(
acc
.
isSupported
(
NANO_OF_SECOND
),
true
);
assertEquals
(
acc
.
isSupported
(
MICRO_OF_SECOND
),
true
);
assertEquals
(
acc
.
isSupported
(
MILLI_OF_SECOND
),
true
);
assertEquals
(
acc
.
getLong
(
SECOND_OF_DAY
),
864L
);
assertEquals
(
acc
.
getLong
(
NANO_OF_SECOND
),
123456789L
);
assertEquals
(
acc
.
getLong
(
MICRO_OF_SECOND
),
123456L
);
assertEquals
(
acc
.
getLong
(
MILLI_OF_SECOND
),
123L
);
}
// SPEC: ChronoField.SECOND_OF_MINUTE
@Test
public
void
test_parse_fromField_SecondOfMinute
()
{
DateTimeFormatter
fmt
=
new
DateTimeFormatterBuilder
()
.
appendValue
(
SECOND_OF_MINUTE
).
toFormatter
();
TemporalAccessor
acc
=
fmt
.
parse
(
"32"
);
assertEquals
(
acc
.
isSupported
(
SECOND_OF_MINUTE
),
true
);
assertEquals
(
acc
.
isSupported
(
NANO_OF_SECOND
),
true
);
assertEquals
(
acc
.
isSupported
(
MICRO_OF_SECOND
),
true
);
assertEquals
(
acc
.
isSupported
(
MILLI_OF_SECOND
),
true
);
assertEquals
(
acc
.
getLong
(
SECOND_OF_MINUTE
),
32L
);
assertEquals
(
acc
.
getLong
(
NANO_OF_SECOND
),
0L
);
assertEquals
(
acc
.
getLong
(
MICRO_OF_SECOND
),
0L
);
assertEquals
(
acc
.
getLong
(
MILLI_OF_SECOND
),
0L
);
}
@Test
public
void
test_parse_fromField_SecondOfMinute_NanoOfSecond
()
{
DateTimeFormatter
fmt
=
new
DateTimeFormatterBuilder
()
.
appendValue
(
SECOND_OF_MINUTE
).
appendLiteral
(
'.'
).
appendValue
(
NANO_OF_SECOND
).
toFormatter
();
TemporalAccessor
acc
=
fmt
.
parse
(
"32.123456789"
);
assertEquals
(
acc
.
isSupported
(
SECOND_OF_MINUTE
),
true
);
assertEquals
(
acc
.
isSupported
(
NANO_OF_SECOND
),
true
);
assertEquals
(
acc
.
isSupported
(
MICRO_OF_SECOND
),
true
);
assertEquals
(
acc
.
isSupported
(
MILLI_OF_SECOND
),
true
);
assertEquals
(
acc
.
getLong
(
SECOND_OF_MINUTE
),
32L
);
assertEquals
(
acc
.
getLong
(
NANO_OF_SECOND
),
123456789L
);
assertEquals
(
acc
.
getLong
(
MICRO_OF_SECOND
),
123456L
);
assertEquals
(
acc
.
getLong
(
MILLI_OF_SECOND
),
123L
);
}
}
}
test/java/time/test/java/time/format/TestDateTimeParsing.java
0 → 100644
浏览文件 @
b44cf83b
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* Copyright (c) 2014, Stephen Colebourne & Michael Nascimento Santos
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of JSR-310 nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package
test.java.time.format
;
import
static
java
.
time
.
temporal
.
ChronoField
.
EPOCH_DAY
;
import
static
java
.
time
.
temporal
.
ChronoField
.
INSTANT_SECONDS
;
import
static
java
.
time
.
temporal
.
ChronoField
.
MICRO_OF_SECOND
;
import
static
java
.
time
.
temporal
.
ChronoField
.
MILLI_OF_SECOND
;
import
static
java
.
time
.
temporal
.
ChronoField
.
NANO_OF_SECOND
;
import
static
java
.
time
.
temporal
.
ChronoField
.
OFFSET_SECONDS
;
import
static
java
.
time
.
temporal
.
ChronoField
.
SECOND_OF_DAY
;
import
static
org
.
testng
.
Assert
.
assertEquals
;
import
java.time.DateTimeException
;
import
java.time.Instant
;
import
java.time.LocalDateTime
;
import
java.time.ZoneId
;
import
java.time.ZoneOffset
;
import
java.time.ZonedDateTime
;
import
java.time.format.DateTimeFormatter
;
import
java.time.format.DateTimeFormatterBuilder
;
import
java.time.temporal.TemporalAccessor
;
import
org.testng.annotations.DataProvider
;
import
org.testng.annotations.Test
;
/**
* Test parsing of edge cases.
*/
@Test
public
class
TestDateTimeParsing
{
private
static
final
ZoneId
PARIS
=
ZoneId
.
of
(
"Europe/Paris"
);
private
static
final
ZoneOffset
OFFSET_0230
=
ZoneOffset
.
ofHoursMinutes
(
2
,
30
);
private
static
final
DateTimeFormatter
LOCALFIELDS
=
new
DateTimeFormatterBuilder
()
.
appendPattern
(
"yyyy-MM-dd HH:mm:ss"
).
toFormatter
();
private
static
final
DateTimeFormatter
LOCALFIELDS_ZONEID
=
new
DateTimeFormatterBuilder
()
.
appendPattern
(
"yyyy-MM-dd HH:mm:ss "
).
appendZoneId
().
toFormatter
();
private
static
final
DateTimeFormatter
LOCALFIELDS_OFFSETID
=
new
DateTimeFormatterBuilder
()
.
appendPattern
(
"yyyy-MM-dd HH:mm:ss "
).
appendOffsetId
().
toFormatter
();
private
static
final
DateTimeFormatter
LOCALFIELDS_WITH_PARIS
=
LOCALFIELDS
.
withZone
(
PARIS
);
private
static
final
DateTimeFormatter
LOCALFIELDS_WITH_0230
=
LOCALFIELDS
.
withZone
(
OFFSET_0230
);
private
static
final
DateTimeFormatter
INSTANT
=
new
DateTimeFormatterBuilder
()
.
appendInstant
().
toFormatter
();
private
static
final
DateTimeFormatter
INSTANT_WITH_PARIS
=
INSTANT
.
withZone
(
PARIS
);
private
static
final
DateTimeFormatter
INSTANT_WITH_0230
=
INSTANT
.
withZone
(
OFFSET_0230
);
private
static
final
DateTimeFormatter
INSTANT_OFFSETID
=
new
DateTimeFormatterBuilder
()
.
appendInstant
().
appendLiteral
(
' '
).
appendOffsetId
().
toFormatter
();
private
static
final
DateTimeFormatter
INSTANT_OFFSETSECONDS
=
new
DateTimeFormatterBuilder
()
.
appendInstant
().
appendLiteral
(
' '
).
appendValue
(
OFFSET_SECONDS
).
toFormatter
();
private
static
final
DateTimeFormatter
INSTANTSECONDS
=
new
DateTimeFormatterBuilder
()
.
appendValue
(
INSTANT_SECONDS
).
toFormatter
();
private
static
final
DateTimeFormatter
INSTANTSECONDS_WITH_PARIS
=
INSTANTSECONDS
.
withZone
(
PARIS
);
private
static
final
DateTimeFormatter
INSTANTSECONDS_NOS
=
new
DateTimeFormatterBuilder
()
.
appendValue
(
INSTANT_SECONDS
).
appendLiteral
(
'.'
).
appendValue
(
NANO_OF_SECOND
).
toFormatter
();
private
static
final
DateTimeFormatter
INSTANTSECONDS_NOS_WITH_PARIS
=
INSTANTSECONDS_NOS
.
withZone
(
PARIS
);
private
static
final
DateTimeFormatter
INSTANTSECONDS_OFFSETSECONDS
=
new
DateTimeFormatterBuilder
()
.
appendValue
(
INSTANT_SECONDS
).
appendLiteral
(
' '
).
appendValue
(
OFFSET_SECONDS
).
toFormatter
();
@DataProvider
(
name
=
"instantZones"
)
Object
[][]
data_instantZones
()
{
return
new
Object
[][]
{
{
LOCALFIELDS_ZONEID
,
"2014-06-30 01:02:03 Europe/Paris"
,
ZonedDateTime
.
of
(
2014
,
6
,
30
,
1
,
2
,
3
,
0
,
PARIS
)},
{
LOCALFIELDS_ZONEID
,
"2014-06-30 01:02:03 +02:30"
,
ZonedDateTime
.
of
(
2014
,
6
,
30
,
1
,
2
,
3
,
0
,
OFFSET_0230
)},
{
LOCALFIELDS_OFFSETID
,
"2014-06-30 01:02:03 +02:30"
,
ZonedDateTime
.
of
(
2014
,
6
,
30
,
1
,
2
,
3
,
0
,
OFFSET_0230
)},
{
LOCALFIELDS_WITH_PARIS
,
"2014-06-30 01:02:03"
,
ZonedDateTime
.
of
(
2014
,
6
,
30
,
1
,
2
,
3
,
0
,
PARIS
)},
{
LOCALFIELDS_WITH_0230
,
"2014-06-30 01:02:03"
,
ZonedDateTime
.
of
(
2014
,
6
,
30
,
1
,
2
,
3
,
0
,
OFFSET_0230
)},
{
INSTANT_WITH_PARIS
,
"2014-06-30T01:02:03Z"
,
ZonedDateTime
.
of
(
2014
,
6
,
30
,
1
,
2
,
3
,
0
,
ZoneOffset
.
UTC
).
withZoneSameInstant
(
PARIS
)},
{
INSTANT_WITH_0230
,
"2014-06-30T01:02:03Z"
,
ZonedDateTime
.
of
(
2014
,
6
,
30
,
1
,
2
,
3
,
0
,
ZoneOffset
.
UTC
).
withZoneSameInstant
(
OFFSET_0230
)},
{
INSTANT_OFFSETID
,
"2014-06-30T01:02:03Z +02:30"
,
ZonedDateTime
.
of
(
2014
,
6
,
30
,
1
,
2
,
3
,
0
,
ZoneOffset
.
UTC
).
withZoneSameInstant
(
OFFSET_0230
)},
{
INSTANT_OFFSETSECONDS
,
"2014-06-30T01:02:03Z 9000"
,
ZonedDateTime
.
of
(
2014
,
6
,
30
,
1
,
2
,
3
,
0
,
ZoneOffset
.
UTC
).
withZoneSameInstant
(
OFFSET_0230
)},
{
INSTANTSECONDS_WITH_PARIS
,
"86402"
,
Instant
.
ofEpochSecond
(
86402
).
atZone
(
PARIS
)},
{
INSTANTSECONDS_NOS_WITH_PARIS
,
"86402.123456789"
,
Instant
.
ofEpochSecond
(
86402
,
123456789
).
atZone
(
PARIS
)},
{
INSTANTSECONDS_OFFSETSECONDS
,
"86402 9000"
,
Instant
.
ofEpochSecond
(
86402
).
atZone
(
OFFSET_0230
)},
};
}
@Test
(
dataProvider
=
"instantZones"
)
public
void
test_parse_instantZones_ZDT
(
DateTimeFormatter
formatter
,
String
text
,
ZonedDateTime
expected
)
{
TemporalAccessor
actual
=
formatter
.
parse
(
text
);
assertEquals
(
ZonedDateTime
.
from
(
actual
),
expected
);
}
@Test
(
dataProvider
=
"instantZones"
)
public
void
test_parse_instantZones_LDT
(
DateTimeFormatter
formatter
,
String
text
,
ZonedDateTime
expected
)
{
TemporalAccessor
actual
=
formatter
.
parse
(
text
);
assertEquals
(
LocalDateTime
.
from
(
actual
),
expected
.
toLocalDateTime
());
}
@Test
(
dataProvider
=
"instantZones"
)
public
void
test_parse_instantZones_Instant
(
DateTimeFormatter
formatter
,
String
text
,
ZonedDateTime
expected
)
{
TemporalAccessor
actual
=
formatter
.
parse
(
text
);
assertEquals
(
Instant
.
from
(
actual
),
expected
.
toInstant
());
}
@Test
(
dataProvider
=
"instantZones"
)
public
void
test_parse_instantZones_supported
(
DateTimeFormatter
formatter
,
String
text
,
ZonedDateTime
expected
)
{
TemporalAccessor
actual
=
formatter
.
parse
(
text
);
assertEquals
(
actual
.
isSupported
(
INSTANT_SECONDS
),
true
);
assertEquals
(
actual
.
isSupported
(
EPOCH_DAY
),
true
);
assertEquals
(
actual
.
isSupported
(
SECOND_OF_DAY
),
true
);
assertEquals
(
actual
.
isSupported
(
NANO_OF_SECOND
),
true
);
assertEquals
(
actual
.
isSupported
(
MICRO_OF_SECOND
),
true
);
assertEquals
(
actual
.
isSupported
(
MILLI_OF_SECOND
),
true
);
}
//-----------------------------------------------------------------------
@DataProvider
(
name
=
"instantNoZone"
)
Object
[][]
data_instantNoZone
()
{
return
new
Object
[][]
{
{
INSTANT
,
"2014-06-30T01:02:03Z"
,
ZonedDateTime
.
of
(
2014
,
6
,
30
,
1
,
2
,
3
,
0
,
ZoneOffset
.
UTC
).
toInstant
()},
{
INSTANTSECONDS
,
"86402"
,
Instant
.
ofEpochSecond
(
86402
)},
{
INSTANTSECONDS_NOS
,
"86402.123456789"
,
Instant
.
ofEpochSecond
(
86402
,
123456789
)},
};
}
@Test
(
dataProvider
=
"instantNoZone"
,
expectedExceptions
=
DateTimeException
.
class
)
public
void
test_parse_instantNoZone_ZDT
(
DateTimeFormatter
formatter
,
String
text
,
Instant
expected
)
{
TemporalAccessor
actual
=
formatter
.
parse
(
text
);
ZonedDateTime
.
from
(
actual
);
}
@Test
(
dataProvider
=
"instantNoZone"
,
expectedExceptions
=
DateTimeException
.
class
)
public
void
test_parse_instantNoZone_LDT
(
DateTimeFormatter
formatter
,
String
text
,
Instant
expected
)
{
TemporalAccessor
actual
=
formatter
.
parse
(
text
);
LocalDateTime
.
from
(
actual
);
}
@Test
(
dataProvider
=
"instantNoZone"
)
public
void
test_parse_instantNoZone_Instant
(
DateTimeFormatter
formatter
,
String
text
,
Instant
expected
)
{
TemporalAccessor
actual
=
formatter
.
parse
(
text
);
assertEquals
(
Instant
.
from
(
actual
),
expected
);
}
@Test
(
dataProvider
=
"instantNoZone"
)
public
void
test_parse_instantNoZone_supported
(
DateTimeFormatter
formatter
,
String
text
,
Instant
expected
)
{
TemporalAccessor
actual
=
formatter
.
parse
(
text
);
assertEquals
(
actual
.
isSupported
(
INSTANT_SECONDS
),
true
);
assertEquals
(
actual
.
isSupported
(
EPOCH_DAY
),
false
);
assertEquals
(
actual
.
isSupported
(
SECOND_OF_DAY
),
false
);
assertEquals
(
actual
.
isSupported
(
NANO_OF_SECOND
),
true
);
assertEquals
(
actual
.
isSupported
(
MICRO_OF_SECOND
),
true
);
assertEquals
(
actual
.
isSupported
(
MILLI_OF_SECOND
),
true
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录