Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
b7be04e9
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看板
提交
b7be04e9
编写于
9月 08, 2008
作者:
P
peytoia
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
4823811: [Fmt-Da] SimpleDateFormat patterns don't allow embedding of some literal punctuation
Reviewed-by: okutsu
上级
b0ec6b8b
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
895 addition
and
9 deletion
+895
-9
src/share/classes/java/text/SimpleDateFormat.java
src/share/classes/java/text/SimpleDateFormat.java
+106
-9
test/java/text/Format/DateFormat/Bug4823811.java
test/java/text/Format/DateFormat/Bug4823811.java
+789
-0
未找到文件。
src/share/classes/java/text/SimpleDateFormat.java
浏览文件 @
b7be04e9
...
@@ -373,6 +373,24 @@ public class SimpleDateFormat extends DateFormat {
...
@@ -373,6 +373,24 @@ public class SimpleDateFormat extends DateFormat {
*/
*/
private
String
pattern
;
private
String
pattern
;
/**
* Saved numberFormat and pattern.
* @see SimpleDateFormat#checkNegativeNumberExpression
*/
transient
private
NumberFormat
originalNumberFormat
;
transient
private
String
originalNumberPattern
;
/**
* The minus sign to be used with format and parse.
*/
transient
private
char
minusSign
=
'-'
;
/**
* True when a negative sign follows a number.
* (True as default in Arabic.)
*/
transient
private
boolean
hasFollowingMinusSign
=
false
;
/**
/**
* The compiled pattern.
* The compiled pattern.
*/
*/
...
@@ -1226,6 +1244,8 @@ public class SimpleDateFormat extends DateFormat {
...
@@ -1226,6 +1244,8 @@ public class SimpleDateFormat extends DateFormat {
*/
*/
public
Date
parse
(
String
text
,
ParsePosition
pos
)
public
Date
parse
(
String
text
,
ParsePosition
pos
)
{
{
checkNegativeNumberExpression
();
int
start
=
pos
.
index
;
int
start
=
pos
.
index
;
int
oldStart
=
start
;
int
oldStart
=
start
;
int
textLength
=
text
.
length
();
int
textLength
=
text
.
length
();
...
@@ -1271,14 +1291,42 @@ public class SimpleDateFormat extends DateFormat {
...
@@ -1271,14 +1291,42 @@ public class SimpleDateFormat extends DateFormat {
// digit text (e.g., "20010704") with a pattern which
// digit text (e.g., "20010704") with a pattern which
// has no delimiters between fields, like "yyyyMMdd".
// has no delimiters between fields, like "yyyyMMdd".
boolean
obeyCount
=
false
;
boolean
obeyCount
=
false
;
// In Arabic, a minus sign for a negative number is put after
// the number. Even in another locale, a minus sign can be
// put after a number using DateFormat.setNumberFormat().
// If both the minus sign and the field-delimiter are '-',
// subParse() needs to determine whether a '-' after a number
// in the given text is a delimiter or is a minus sign for the
// preceding number. We give subParse() a clue based on the
// information in compiledPattern.
boolean
useFollowingMinusSignAsDelimiter
=
false
;
if
(
i
<
compiledPattern
.
length
)
{
if
(
i
<
compiledPattern
.
length
)
{
int
nextTag
=
compiledPattern
[
i
]
>>>
8
;
int
nextTag
=
compiledPattern
[
i
]
>>>
8
;
if
(!(
nextTag
==
TAG_QUOTE_ASCII_CHAR
||
nextTag
==
TAG_QUOTE_CHARS
))
{
if
(!(
nextTag
==
TAG_QUOTE_ASCII_CHAR
||
nextTag
==
TAG_QUOTE_CHARS
))
{
obeyCount
=
true
;
obeyCount
=
true
;
}
}
if
(
hasFollowingMinusSign
&&
(
nextTag
==
TAG_QUOTE_ASCII_CHAR
||
nextTag
==
TAG_QUOTE_CHARS
))
{
int
c
;
if
(
nextTag
==
TAG_QUOTE_ASCII_CHAR
)
{
c
=
compiledPattern
[
i
]
&
0xff
;
}
else
{
c
=
compiledPattern
[
i
+
1
];
}
if
(
c
==
minusSign
)
{
useFollowingMinusSignAsDelimiter
=
true
;
}
}
}
}
start
=
subParse
(
text
,
start
,
tag
,
count
,
obeyCount
,
start
=
subParse
(
text
,
start
,
tag
,
count
,
obeyCount
,
ambiguousYear
,
pos
);
ambiguousYear
,
pos
,
useFollowingMinusSignAsDelimiter
);
if
(
start
<
0
)
{
if
(
start
<
0
)
{
pos
.
index
=
oldStart
;
pos
.
index
=
oldStart
;
return
null
;
return
null
;
...
@@ -1514,8 +1562,8 @@ public class SimpleDateFormat extends DateFormat {
...
@@ -1514,8 +1562,8 @@ public class SimpleDateFormat extends DateFormat {
*/
*/
private
int
subParse
(
String
text
,
int
start
,
int
patternCharIndex
,
int
count
,
private
int
subParse
(
String
text
,
int
start
,
int
patternCharIndex
,
int
count
,
boolean
obeyCount
,
boolean
[]
ambiguousYear
,
boolean
obeyCount
,
boolean
[]
ambiguousYear
,
ParsePosition
origPos
)
ParsePosition
origPos
,
{
boolean
useFollowingMinusSignAsDelimiter
)
{
Number
number
=
null
;
Number
number
=
null
;
int
value
=
0
;
int
value
=
0
;
ParsePosition
pos
=
new
ParsePosition
(
0
);
ParsePosition
pos
=
new
ParsePosition
(
0
);
...
@@ -1540,10 +1588,10 @@ public class SimpleDateFormat extends DateFormat {
...
@@ -1540,10 +1588,10 @@ public class SimpleDateFormat extends DateFormat {
// a number value. We handle further, more generic cases below. We need
// a number value. We handle further, more generic cases below. We need
// to handle some of them here because some fields require extra processing on
// to handle some of them here because some fields require extra processing on
// the parsed value.
// the parsed value.
if
(
patternCharIndex
==
4
/*
HOUR_OF_DAY1_FIELD
*/
||
if
(
patternCharIndex
==
4
/*
HOUR_OF_DAY1_FIELD
*/
||
patternCharIndex
==
15
/*
HOUR1_FIELD
*/
||
patternCharIndex
==
15
/*
HOUR1_FIELD
*/
||
(
patternCharIndex
==
2
/*
MONTH_FIELD
*/
&&
count
<=
2
)
||
(
patternCharIndex
==
2
/*
MONTH_FIELD
*/
&&
count
<=
2
)
||
patternCharIndex
==
1
)
{
patternCharIndex
==
1
/* YEAR_FIELD */
)
{
// It would be good to unify this with the obeyCount logic below,
// It would be good to unify this with the obeyCount logic below,
// but that's going to be difficult.
// but that's going to be difficult.
if
(
obeyCount
)
{
if
(
obeyCount
)
{
...
@@ -1560,6 +1608,15 @@ public class SimpleDateFormat extends DateFormat {
...
@@ -1560,6 +1608,15 @@ public class SimpleDateFormat extends DateFormat {
}
}
}
else
{
}
else
{
value
=
number
.
intValue
();
value
=
number
.
intValue
();
if
(
useFollowingMinusSignAsDelimiter
&&
(
value
<
0
)
&&
(((
pos
.
index
<
text
.
length
())
&&
(
text
.
charAt
(
pos
.
index
)
!=
minusSign
))
||
((
pos
.
index
==
text
.
length
())
&&
(
text
.
charAt
(
pos
.
index
-
1
)
==
minusSign
))))
{
value
=
-
value
;
pos
.
index
--;
}
}
}
}
}
...
@@ -1891,7 +1948,18 @@ public class SimpleDateFormat extends DateFormat {
...
@@ -1891,7 +1948,18 @@ public class SimpleDateFormat extends DateFormat {
number
=
numberFormat
.
parse
(
text
,
pos
);
number
=
numberFormat
.
parse
(
text
,
pos
);
}
}
if
(
number
!=
null
)
{
if
(
number
!=
null
)
{
calendar
.
set
(
field
,
number
.
intValue
());
value
=
number
.
intValue
();
if
(
useFollowingMinusSignAsDelimiter
&&
(
value
<
0
)
&&
(((
pos
.
index
<
text
.
length
())
&&
(
text
.
charAt
(
pos
.
index
)
!=
minusSign
))
||
((
pos
.
index
==
text
.
length
())
&&
(
text
.
charAt
(
pos
.
index
-
1
)
==
minusSign
))))
{
value
=
-
value
;
pos
.
index
--;
}
calendar
.
set
(
field
,
value
);
return
pos
.
index
;
return
pos
.
index
;
}
}
break
parsing
;
break
parsing
;
...
@@ -2102,4 +2170,33 @@ public class SimpleDateFormat extends DateFormat {
...
@@ -2102,4 +2170,33 @@ public class SimpleDateFormat extends DateFormat {
}
}
}
}
}
}
/**
* Analyze the negative subpattern of DecimalFormat and set/update values
* as necessary.
*/
private
void
checkNegativeNumberExpression
()
{
if
((
numberFormat
instanceof
DecimalFormat
)
&&
!
numberFormat
.
equals
(
originalNumberFormat
))
{
String
numberPattern
=
((
DecimalFormat
)
numberFormat
).
toPattern
();
if
(!
numberPattern
.
equals
(
originalNumberPattern
))
{
hasFollowingMinusSign
=
false
;
int
separatorIndex
=
numberPattern
.
indexOf
(
';'
);
// If the negative subpattern is not absent, we have to analayze
// it in order to check if it has a following minus sign.
if
(
separatorIndex
>
-
1
)
{
int
minusIndex
=
numberPattern
.
indexOf
(
'-'
,
separatorIndex
);
if
((
minusIndex
>
numberPattern
.
lastIndexOf
(
'0'
))
&&
(
minusIndex
>
numberPattern
.
lastIndexOf
(
'#'
)))
{
hasFollowingMinusSign
=
true
;
minusSign
=
((
DecimalFormat
)
numberFormat
).
getDecimalFormatSymbols
().
getMinusSign
();
}
}
originalNumberPattern
=
numberPattern
;
}
originalNumberFormat
=
numberFormat
;
}
}
}
}
test/java/text/Format/DateFormat/Bug4823811.java
0 → 100644
浏览文件 @
b7be04e9
/*
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 4823811
* @summary Confirm that text which includes numbers with a trailing minus sign is parsed correctly.
*/
import
java.text.*
;
import
java.util.*
;
public
class
Bug4823811
{
private
static
Locale
localeEG
=
new
Locale
(
"ar"
,
"EG"
);
private
static
Locale
localeUS
=
Locale
.
US
;
private
static
String
JuneInArabic
=
"\u064a\u0648\u0646\u064a\u0648"
;
private
static
String
JulyInArabic
=
"\u064a\u0648\u0644\u064a\u0648"
;
private
static
String
JuneInEnglish
=
"June"
;
private
static
String
JulyInEnglish
=
"July"
;
private
static
String
BORDER
=
"============================================================"
;
/*
* I don't use static import here intentionally so that this test program
* can be run on JDK 1.4.2.
*/
private
static
int
ERA
=
Calendar
.
ERA
;
private
static
int
BC
=
GregorianCalendar
.
BC
;
// private static int JAN = Calendar.JANUARY;
// private static int FEB = Calendar.FEBRUARY;
// private static int MAR = Calendar.MARCH;
private
static
int
APR
=
Calendar
.
APRIL
;
private
static
int
MAY
=
Calendar
.
MAY
;
private
static
int
JUN
=
Calendar
.
JUNE
;
private
static
int
JUL
=
Calendar
.
JULY
;
// private static int AUG = Calendar.AUGUST;
// private static int SEP = Calendar.SEPTEMBER;
// private static int OCT = Calendar.OCTOBER;
// private static int NOV = Calendar.NOVEMBER;
// private static int DEC = Calendar.DECEMBER;
private
static
String
[]
patterns
=
{
"yyyy MMMM d H m s"
,
"yyyy MM dd hh mm ss"
,
/*
* Because 1-based HOUR_OF_DAY, 1-based HOUR, MONTH, and YEAR fields
* are parsed using different code from the code for other numeric
* fields, I prepared YEAR-preceding patterns and SECOND-preceding
* patterns.
*/
"yyyy M d h m s"
,
" yyyy M d h m s"
,
"yyyy M d h m s "
,
"s m h d M yyyy"
,
" s m h d M yyyy"
,
"s m h d M yyyy "
,
};
private
static
char
originalMinusSign1
=
':'
;
private
static
char
originalMinusSign2
=
'\uff0d'
;
// fullwidth minus
private
static
String
[]
delimiters
=
{
"-"
,
"/"
,
":"
,
"/"
,
"\uff0d"
,
"/"
};
private
static
String
[][]
specialDelimiters
=
{
// for Arabic formatter and modified English formatter
{
"--"
,
"-/"
,
"::"
,
":/"
,
"\uff0d\uff0d"
,
"\uff0d/"
},
// for English formatter and modified Arabic formatter
{
"--"
,
"/-"
,
"::"
,
"/:"
,
"\uff0d\uff0d"
,
"/\uff0d"
},
};
/*
* Format:
* +-------------------------------------------------------------------+
* | Input | Output |
* +---------------------+---------------------------------------------|
* | datesEG & datesUS | formattedDatesEG & formattedDatesUS |
* +-------------------------------------------------------------------+
*
* Parse:
* +-------------------------------------------------------------------+
* | Input | Output |
* |---------------------+---------------------------------------------|
* | datesToParse | datesEG & datesUS |
* +-------------------------------------------------------------------+
*/
private
static
String
[][]
datesToParse
=
{
// "JUNE" and "JULY" are replaced with a localized month name later.
{
"2008 JULY 20 3 12 83"
,
"2008 JULY 20 3 12 83"
,
"2008 JULY 20 3 12 83"
},
{
"2008 07 20 03 12 83"
,
"2008 07 20 03 12 83"
,
"2008 07 20 03 12 83"
},
{
"2008 7 20 3 12 83"
,
"2008 7 20 3 12 83"
,
"2008 7 20 3 12 83"
},
{
" 2008 7 20 3 12 83"
,
" 2008 7 20 3 12 83"
,
" 2008 7 20 3 12 83"
,
"2008 7 20 3 12 83"
},
{
"2008 7 20 3 12 83 "
,
"2008 7 20 3 12 83 "
,
"2008 7 20 3 12 83"
},
{
"83 12 3 20 7 2008"
,
"83 12 3 20 7 2008"
,
"83 12 3 20 7 2008"
},
{
" 83 12 3 20 7 2008"
,
" 83 12 3 20 7 2008"
,
" 83 12 3 20 7 2008"
,
"83 12 3 20 7 2008"
},
{
"83 12 3 20 7 2008 "
,
"83 12 3 20 7 2008 "
,
"83 12 3 20 7 2008"
},
};
// For formatting
private
static
String
[][]
formattedDatesEG
=
{
{
"2008 JULY 20 3 13 23"
,
"2009 JULY 20 3 13 23"
,
null
},
{
"2008 07 20 03 13 23"
,
"2009 07 20 03 13 23"
,
"2007 05 20 03 13 23"
},
{
"2008 7 20 3 13 23"
,
"2009 6 10 3 13 23"
,
"2007 4 10 3 13 23"
},
{
" 2008 7 20 3 13 23"
,
null
,
" 2009 7 20 3 13 23"
,
null
},
{
"2008 7 20 3 13 23 "
,
"2008 7 20 3 10 37 "
,
null
},
{
"23 13 3 20 7 2008"
,
"37 10 9 19 7 2008"
,
"23 49 8 19 7 2008"
},
{
" 23 13 3 20 7 2008"
,
null
,
" 37 10 3 20 7 2008"
,
null
},
{
"23 13 3 20 7 2008 "
,
"23 13 3 20 7 2009 "
,
null
},
};
private
static
String
[][]
formattedDatesUS
=
{
{
"2008 JULY 20 3 13 23"
,
null
,
"2008 JUNE 10 3 13 23"
},
{
"2008 07 20 03 13 23"
,
"2007 05 20 03 13 23"
,
"2008 06 10 03 13 23"
},
{
"2008 7 20 3 13 23"
,
"2007 5 19 9 13 23"
,
"2008 6 9 9 13 23"
},
{
" 2008 7 20 3 13 23"
,
" 2009 7 20 3 13 23"
,
" 2007 5 20 3 13 23"
,
null
},
{
"2008 7 20 3 13 23 "
,
"2008 7 20 3 13 23 "
,
null
},
{
"23 13 3 20 7 2008"
,
"23 49 2 10 6 2008"
,
"23 13 9 9 6 2008"
},
{
" 23 13 3 20 7 2008"
,
" 37 10 3 20 7 2008"
,
" 23 49 2 20 7 2008"
,
null
},
{
"23 13 3 20 7 2008 "
,
"23 13 3 20 7 2008 "
,
null
},
};
private
static
GregorianCalendar
[][]
datesEG
=
{
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(-
2008
,
JUL
,
20
,
3
,
12
,
83
),
null
},
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(-
2008
,
JUL
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(
2007
,
MAY
,
20
,
3
,
12
,
83
)},
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(-
2008
,
JUL
,
-
20
,
3
,
12
,
83
),
new
GregorianCalendar
(
2007
,
APR
,
10
,
3
,
12
,
83
)},
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
null
,
new
GregorianCalendar
(-
2008
,
JUL
,
20
,
3
,
12
,
83
),
null
},
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
-
83
),
null
},
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(
2008
,
JUL
,
20
,
-
3
,
12
,
-
83
),
new
GregorianCalendar
(
2008
,
JUL
,
20
,
-
3
,
-
12
,
83
)},
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
null
,
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
-
83
),
null
},
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(-
2008
,
JUL
,
20
,
3
,
12
,
83
),
null
},
};
private
static
GregorianCalendar
[][]
datesUS
=
{
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
null
,
new
GregorianCalendar
(
2008
,
JUN
,
10
,
3
,
12
,
83
)},
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(
2007
,
MAY
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(
2008
,
JUN
,
10
,
3
,
12
,
83
)},
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(
2007
,
MAY
,
20
,
-
3
,
12
,
83
),
new
GregorianCalendar
(
2008
,
JUL
,
-
20
,
-
3
,
12
,
83
)},
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(-
2008
,
JUL
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(
2007
,
MAY
,
20
,
3
,
12
,
83
),
null
},
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
null
},
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(
2008
,
JUL
,
-
20
,
3
,
-
12
,
83
),
new
GregorianCalendar
(
2008
,
JUL
,
-
20
,
-
3
,
12
,
83
)},
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
-
83
),
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
-
12
,
83
),
null
},
{
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
new
GregorianCalendar
(
2008
,
JUL
,
20
,
3
,
12
,
83
),
null
},
};
/* flags */
private
static
boolean
err
=
false
;
private
static
boolean
verbose
=
false
;
public
static
void
main
(
String
[]
args
)
{
if
(
args
.
length
==
1
&&
args
[
0
].
equals
(
"-v"
))
{
verbose
=
true
;
}
Locale
defaultLocale
=
Locale
.
getDefault
();
TimeZone
defaultTimeZone
=
TimeZone
.
getDefault
();
TimeZone
.
setDefault
(
TimeZone
.
getTimeZone
(
"Asia/Tokyo"
));
try
{
/*
* Test SimpleDateFormat.parse() and format() for original
* SimpleDateFormat instances
*/
testDateFormat1
();
/*
* Test SimpleDateFormat.parse() and format() for modified
* SimpleDateFormat instances using an original minus sign,
* pattern, and diffenrent month names in DecimalFormat
*/
testDateFormat2
();
/*
* Test SimpleDateFormat.parse() and format() for modified
* SimpleDateFormat instances using a fullwidth minus sign
*/
testDateFormat3
();
/*
* Just to confirm that regressions aren't introduced in
* DecimalFormat. This cannot happen, though. Because I didn't
* change DecimalFormat at all.
*/
testNumberFormat
();
}
catch
(
Exception
e
)
{
err
=
true
;
System
.
err
.
println
(
"Unexpected exception: "
+
e
);
}
finally
{
Locale
.
setDefault
(
defaultLocale
);
TimeZone
.
setDefault
(
defaultTimeZone
);
if
(
err
)
{
System
.
err
.
println
(
BORDER
+
" Test failed."
);
throw
new
RuntimeException
(
"Date/Number formatting/parsing error."
);
}
else
{
System
.
out
.
println
(
BORDER
+
" Test passed."
);
}
}
}
//
// DateFormat test
//
private
static
void
testDateFormat1
()
{
for
(
int
i
=
0
;
i
<
patterns
.
length
;
i
++)
{
System
.
out
.
println
(
BORDER
);
for
(
int
j
=
0
;
j
<=
1
;
j
++)
{
// Generate a pattern
String
pattern
=
patterns
[
i
].
replaceAll
(
" "
,
delimiters
[
j
]);
System
.
out
.
println
(
"Pattern=\""
+
pattern
+
"\""
);
System
.
out
.
println
(
"*** DateFormat.format test in ar_EG"
);
testDateFormatFormattingInRTL
(
pattern
,
i
,
j
,
null
,
localeEG
,
false
);
System
.
out
.
println
(
"*** DateFormat.parse test in ar_EG"
);
testDateFormatParsingInRTL
(
pattern
,
i
,
j
,
null
,
localeEG
,
false
);
System
.
out
.
println
(
"*** DateFormat.format test in en_US"
);
testDateFormatFormattingInLTR
(
pattern
,
i
,
j
,
null
,
localeUS
,
true
);
System
.
out
.
println
(
"*** DateFormat.parse test in en_US"
);
testDateFormatParsingInLTR
(
pattern
,
i
,
j
,
null
,
localeUS
,
true
);
}
}
}
private
static
void
testDateFormat2
()
{
/*
* modified ar_EG Date&Time formatter :
* minus sign: ':'
* pattern: "#,##0.###"
* month names: In Arabic
*
* modified en_US Date&Time formatter :
* minus sign: ':'
* pattern: "#,##0.###;#,##0.###-"
* month names: In English
*/
DecimalFormat
dfEG
=
(
DecimalFormat
)
NumberFormat
.
getInstance
(
localeEG
);
DecimalFormat
dfUS
=
(
DecimalFormat
)
NumberFormat
.
getInstance
(
localeUS
);
DecimalFormatSymbols
dfsEG
=
dfEG
.
getDecimalFormatSymbols
();
DecimalFormatSymbols
dfsUS
=
dfUS
.
getDecimalFormatSymbols
();
dfsEG
.
setMinusSign
(
originalMinusSign1
);
dfsUS
.
setMinusSign
(
originalMinusSign1
);
dfEG
.
setDecimalFormatSymbols
(
dfsUS
);
dfUS
.
setDecimalFormatSymbols
(
dfsEG
);
String
patternEG
=
dfEG
.
toPattern
();
String
patternUS
=
dfUS
.
toPattern
();
dfEG
.
applyPattern
(
patternUS
);
dfUS
.
applyPattern
(
patternEG
);
for
(
int
i
=
0
;
i
<
patterns
.
length
;
i
++)
{
System
.
out
.
println
(
BORDER
);
for
(
int
j
=
2
;
j
<=
3
;
j
++)
{
// Generate a pattern
String
pattern
=
patterns
[
i
].
replaceAll
(
" "
,
delimiters
[
j
]);
System
.
out
.
println
(
"Pattern=\""
+
pattern
+
"\""
);
System
.
out
.
println
(
"*** DateFormat.format test in modified en_US"
);
testDateFormatFormattingInRTL
(
pattern
,
i
,
j
,
dfUS
,
localeUS
,
true
);
System
.
out
.
println
(
"*** DateFormat.parse test in modified en_US"
);
testDateFormatParsingInRTL
(
pattern
,
i
,
j
,
dfUS
,
localeUS
,
true
);
System
.
out
.
println
(
"*** DateFormat.format test in modified ar_EG"
);
testDateFormatFormattingInLTR
(
pattern
,
i
,
j
,
dfEG
,
localeEG
,
false
);
System
.
out
.
println
(
"*** DateFormat.parse test in modified ar_EG"
);
testDateFormatParsingInLTR
(
pattern
,
i
,
j
,
dfEG
,
localeEG
,
false
);
}
}
}
private
static
void
testDateFormat3
()
{
/*
* modified ar_EG Date&Time formatter :
* minus sign: '\uff0d' // fullwidth minus
* pattern: "#,##0.###;#,##0.###-"
* month names: In Arabic
*
* modified en_US Date&Time formatter :
* minus sign: '\uff0d' // fullwidth minus
* pattern: "#,##0.###"
* month names: In English
*/
DecimalFormat
dfEG
=
(
DecimalFormat
)
NumberFormat
.
getInstance
(
localeEG
);
DecimalFormat
dfUS
=
(
DecimalFormat
)
NumberFormat
.
getInstance
(
localeUS
);
DecimalFormatSymbols
dfsEG
=
dfEG
.
getDecimalFormatSymbols
();
DecimalFormatSymbols
dfsUS
=
dfUS
.
getDecimalFormatSymbols
();
dfsEG
.
setMinusSign
(
originalMinusSign2
);
dfsUS
.
setMinusSign
(
originalMinusSign2
);
dfEG
.
setDecimalFormatSymbols
(
dfsEG
);
dfUS
.
setDecimalFormatSymbols
(
dfsUS
);
for
(
int
i
=
0
;
i
<
patterns
.
length
;
i
++)
{
System
.
out
.
println
(
BORDER
);
for
(
int
j
=
4
;
j
<=
5
;
j
++)
{
// Generate a pattern
String
pattern
=
patterns
[
i
].
replaceAll
(
" "
,
delimiters
[
j
]);
System
.
out
.
println
(
"Pattern=\""
+
pattern
+
"\""
);
System
.
out
.
println
(
"*** DateFormat.format test in modified ar_EG"
);
testDateFormatFormattingInRTL
(
pattern
,
i
,
j
,
dfEG
,
localeEG
,
false
);
System
.
out
.
println
(
"*** DateFormat.parse test in modified ar_EG"
);
testDateFormatParsingInRTL
(
pattern
,
i
,
j
,
dfEG
,
localeEG
,
false
);
System
.
out
.
println
(
"*** DateFormat.format test in modified en_US"
);
testDateFormatFormattingInLTR
(
pattern
,
i
,
j
,
dfUS
,
localeUS
,
true
);
System
.
out
.
println
(
"*** DateFormat.parse test in modified en_US"
);
testDateFormatParsingInLTR
(
pattern
,
i
,
j
,
dfUS
,
localeUS
,
true
);
}
}
}
private
static
void
testDateFormatFormattingInRTL
(
String
pattern
,
int
basePattern
,
int
delimiter
,
NumberFormat
nf
,
Locale
locale
,
boolean
useEnglishMonthName
)
{
Locale
.
setDefault
(
locale
);
SimpleDateFormat
sdf
=
new
SimpleDateFormat
(
pattern
);
if
(
nf
!=
null
)
{
sdf
.
setNumberFormat
(
nf
);
}
for
(
int
i
=
0
;
i
<
datesToParse
[
basePattern
].
length
;
i
++)
{
if
(
datesEG
[
basePattern
][
i
]
==
null
)
{
continue
;
}
String
expected
=
formattedDatesEG
[
basePattern
][
i
]
.
replaceAll
(
"JUNE"
,
(
useEnglishMonthName
?
JuneInEnglish
:
JuneInArabic
))
.
replaceAll
(
"JULY"
,
(
useEnglishMonthName
?
JulyInEnglish
:
JulyInArabic
))
.
replaceAll
(
" "
,
delimiters
[
delimiter
]);
testDateFormatFormatting
(
sdf
,
pattern
,
datesEG
[
basePattern
][
i
],
expected
,
locale
.
toString
());
}
}
private
static
void
testDateFormatFormattingInLTR
(
String
pattern
,
int
basePattern
,
int
delimiter
,
NumberFormat
nf
,
Locale
locale
,
boolean
useEnglishMonthName
)
{
Locale
.
setDefault
(
locale
);
SimpleDateFormat
sdf
=
new
SimpleDateFormat
(
pattern
);
if
(
nf
!=
null
)
{
sdf
.
setNumberFormat
(
nf
);
}
for
(
int
i
=
0
;
i
<
datesToParse
[
basePattern
].
length
;
i
++)
{
if
(
datesUS
[
basePattern
][
i
]
==
null
)
{
continue
;
}
String
expected
=
formattedDatesUS
[
basePattern
][
i
]
.
replaceAll
(
"JUNE"
,
(
useEnglishMonthName
?
JuneInEnglish
:
JuneInArabic
))
.
replaceAll
(
"JULY"
,
(
useEnglishMonthName
?
JulyInEnglish
:
JulyInArabic
))
.
replaceAll
(
" "
,
delimiters
[
delimiter
]);
testDateFormatFormatting
(
sdf
,
pattern
,
datesUS
[
basePattern
][
i
],
expected
,
locale
.
toString
());
}
}
private
static
void
testDateFormatFormatting
(
SimpleDateFormat
sdf
,
String
pattern
,
GregorianCalendar
givenGC
,
String
expected
,
String
locale
)
{
Date
given
=
givenGC
.
getTime
();
String
str
=
sdf
.
format
(
given
);
if
(
expected
.
equals
(
str
))
{
if
(
verbose
)
{
System
.
out
.
print
(
" Passed: SimpleDateFormat("
);
System
.
out
.
print
(
locale
+
", \""
+
pattern
+
"\").format("
);
System
.
out
.
println
(
given
+
")"
);
System
.
out
.
print
(
" ---> \""
+
str
+
"\" "
);
System
.
out
.
println
((
givenGC
.
get
(
ERA
)
==
BC
)
?
"(BC)"
:
"(AD)"
);
}
}
else
{
err
=
true
;
System
.
err
.
print
(
" Failed: Unexpected SimpleDateFormat("
);
System
.
out
.
print
(
locale
+
", \""
+
pattern
+
"\").format("
);
System
.
out
.
println
(
given
+
") result."
);
System
.
out
.
println
(
" Expected: \""
+
expected
+
"\""
);
System
.
out
.
print
(
" Got: \""
+
str
+
"\" "
);
System
.
out
.
println
((
givenGC
.
get
(
ERA
)
==
BC
)
?
"(BC)"
:
"(AD)"
);
}
}
private
static
void
testDateFormatParsingInRTL
(
String
pattern
,
int
basePattern
,
int
delimiter
,
NumberFormat
nf
,
Locale
locale
,
boolean
useEnglishMonthName
)
{
Locale
.
setDefault
(
locale
);
SimpleDateFormat
sdf
=
new
SimpleDateFormat
(
pattern
);
if
(
nf
!=
null
)
{
sdf
.
setNumberFormat
(
nf
);
}
for
(
int
i
=
0
;
i
<
datesToParse
[
basePattern
].
length
;
i
++)
{
String
given
=
datesToParse
[
basePattern
][
i
]
.
replaceAll
(
" "
,
specialDelimiters
[
0
][
delimiter
])
.
replaceAll
(
" "
,
delimiters
[
delimiter
]);
testDateFormatParsing
(
sdf
,
pattern
,
given
.
replaceAll
(
"JULY"
,
(
useEnglishMonthName
?
JulyInEnglish
:
JulyInArabic
)),
datesEG
[
basePattern
][
i
],
locale
.
toString
());
}
}
private
static
void
testDateFormatParsingInLTR
(
String
pattern
,
int
basePattern
,
int
delimiter
,
NumberFormat
nf
,
Locale
locale
,
boolean
useEnglishMonthName
)
{
Locale
.
setDefault
(
locale
);
SimpleDateFormat
sdf
=
new
SimpleDateFormat
(
pattern
);
if
(
nf
!=
null
)
{
sdf
.
setNumberFormat
(
nf
);
}
for
(
int
i
=
0
;
i
<
datesToParse
[
basePattern
].
length
;
i
++)
{
String
given
=
datesToParse
[
basePattern
][
i
]
.
replaceAll
(
" "
,
specialDelimiters
[
1
][
delimiter
])
.
replaceAll
(
" "
,
delimiters
[
delimiter
]);
testDateFormatParsing
(
sdf
,
pattern
,
given
.
replaceAll
(
"JULY"
,
(
useEnglishMonthName
?
JulyInEnglish
:
JulyInArabic
)),
datesUS
[
basePattern
][
i
],
locale
.
toString
());
}
}
private
static
void
testDateFormatParsing
(
SimpleDateFormat
sdf
,
String
pattern
,
String
given
,
GregorianCalendar
expectedGC
,
String
locale
)
{
try
{
Date
d
=
sdf
.
parse
(
given
);
if
(
expectedGC
==
null
)
{
err
=
true
;
System
.
err
.
print
(
" Failed: SimpleDateFormat("
+
locale
);
System
.
err
.
print
(
", \""
+
pattern
+
"\").parse(\""
+
given
);
System
.
err
.
println
(
"\") should have thrown ParseException"
);
}
else
if
(
expectedGC
.
getTime
().
equals
(
d
))
{
if
(
verbose
)
{
System
.
out
.
print
(
" Passed: SimpleDateFormat("
+
locale
);
System
.
out
.
print
(
", \""
+
pattern
+
"\").parse(\""
+
given
);
System
.
out
.
println
(
"\")"
);
System
.
out
.
print
(
" ---> "
+
d
+
" ("
+
d
.
getTime
());
System
.
out
.
println
(
")"
);
}
}
else
{
err
=
true
;
System
.
err
.
print
(
" Failed: SimpleDateFormat("
+
locale
);
System
.
err
.
print
(
", \""
+
pattern
+
"\").parse(\""
+
given
);
System
.
err
.
println
(
"\")"
);
System
.
err
.
print
(
" Expected: "
+
expectedGC
.
getTime
());
System
.
err
.
println
(
" ("
+
d
.
getTime
()
+
")"
);
System
.
err
.
print
(
" Got: "
+
d
+
" ("
+
d
.
getTime
());
System
.
err
.
println
(
")"
);
System
.
err
.
print
(
" Pattern: \""
);
System
.
err
.
print
(((
DecimalFormat
)
sdf
.
getNumberFormat
()).
toPattern
());
System
.
err
.
println
(
"\""
);
}
}
catch
(
ParseException
pe
)
{
if
(
expectedGC
==
null
)
{
if
(
verbose
)
{
System
.
out
.
print
(
" Passed: SimpleDateFormat("
+
locale
);
System
.
out
.
print
(
", \""
+
pattern
+
"\").parse(\""
+
given
);
System
.
out
.
println
(
"\")"
);
System
.
out
.
println
(
" threw ParseException as expected"
);
}
}
else
{
err
=
true
;
System
.
err
.
println
(
" Failed: Unexpected exception with"
);
System
.
err
.
print
(
" SimpleDateFormat("
+
locale
);
System
.
err
.
print
(
", \""
+
pattern
+
"\").parse(\""
);
System
.
err
.
println
(
given
+
"\"):"
);
System
.
err
.
println
(
" "
+
pe
);
System
.
err
.
print
(
" Pattern: \""
);
System
.
err
.
print
(((
DecimalFormat
)
sdf
.
getNumberFormat
()).
toPattern
());
System
.
err
.
println
(
"\""
);
System
.
err
.
print
(
" Month 0: "
);
System
.
err
.
println
(
sdf
.
getDateFormatSymbols
().
getMonths
()[
0
]);
}
}
}
//
// NumberFormat test
//
private
static
void
testNumberFormat
()
{
NumberFormat
nfEG
=
NumberFormat
.
getInstance
(
localeEG
);
NumberFormat
nfUS
=
NumberFormat
.
getInstance
(
localeUS
);
System
.
out
.
println
(
"*** DecimalFormat.format test in ar_EG"
);
testNumberFormatFormatting
(
nfEG
,
-
123456789
,
"123,456,789-"
,
"ar_EG"
);
testNumberFormatFormatting
(
nfEG
,
-
456
,
"456-"
,
"ar_EG"
);
System
.
out
.
println
(
"*** DecimalFormat.parse test in ar_EG"
);
testNumberFormatParsing
(
nfEG
,
"123-"
,
new
Long
(-
123
),
"ar_EG"
);
testNumberFormatParsing
(
nfEG
,
"123--"
,
new
Long
(-
123
),
"ar_EG"
);
testNumberFormatParsingCheckException
(
nfEG
,
"-123"
,
0
,
"ar_EG"
);
System
.
out
.
println
(
"*** DecimalFormat.format test in en_US"
);
testNumberFormatFormatting
(
nfUS
,
-
123456789
,
"-123,456,789"
,
"en_US"
);
testNumberFormatFormatting
(
nfUS
,
-
456
,
"-456"
,
"en_US"
);
System
.
out
.
println
(
"*** DecimalFormat.parse test in en_US"
);
testNumberFormatParsing
(
nfUS
,
"123-"
,
new
Long
(
123
),
"en_US"
);
testNumberFormatParsing
(
nfUS
,
"-123"
,
new
Long
(-
123
),
"en_US"
);
testNumberFormatParsingCheckException
(
nfUS
,
"--123"
,
0
,
"en_US"
);
}
private
static
void
testNumberFormatFormatting
(
NumberFormat
nf
,
int
given
,
String
expected
,
String
locale
)
{
String
str
=
nf
.
format
(
given
);
if
(
expected
.
equals
(
str
))
{
if
(
verbose
)
{
System
.
out
.
print
(
" Passed: NumberFormat("
+
locale
);
System
.
out
.
println
(
").format("
+
given
+
")"
);
System
.
out
.
println
(
" ---> \""
+
str
+
"\""
);
}
}
else
{
err
=
true
;
System
.
err
.
print
(
" Failed: Unexpected NumberFormat("
+
locale
);
System
.
err
.
println
(
").format("
+
given
+
") result."
);
System
.
err
.
println
(
" Expected: \""
+
expected
+
"\""
);
System
.
err
.
println
(
" Got: \""
+
str
+
"\""
);
}
}
private
static
void
testNumberFormatParsing
(
NumberFormat
nf
,
String
given
,
Number
expected
,
String
locale
)
{
try
{
Number
n
=
nf
.
parse
(
given
);
if
(
n
.
equals
(
expected
))
{
if
(
verbose
)
{
System
.
out
.
print
(
" Passed: NumberFormat("
+
locale
);
System
.
out
.
println
(
").parse(\""
+
given
+
"\")"
);
System
.
out
.
println
(
" ---> "
+
n
);
}
}
else
{
err
=
true
;
System
.
err
.
print
(
" Failed: Unexpected NumberFormat("
+
locale
);
System
.
err
.
println
(
").parse(\""
+
given
+
"\") result."
);
System
.
err
.
println
(
" Expected: "
+
expected
);
System
.
err
.
println
(
" Got: "
+
n
);
}
}
catch
(
ParseException
pe
)
{
err
=
true
;
System
.
err
.
print
(
" Failed: Unexpected exception with NumberFormat("
);
System
.
err
.
println
(
locale
+
").parse(\""
+
given
+
"\") :"
);
System
.
err
.
println
(
" "
+
pe
);
}
}
private
static
void
testNumberFormatParsingCheckException
(
NumberFormat
nf
,
String
given
,
int
expected
,
String
locale
)
{
try
{
Number
n
=
nf
.
parse
(
given
);
err
=
true
;
System
.
err
.
print
(
" Failed: NumberFormat("
+
locale
);
System
.
err
.
println
(
").parse(\""
+
given
+
"\")"
);
System
.
err
.
println
(
" should have thrown ParseException"
);
}
catch
(
ParseException
pe
)
{
int
errorOffset
=
pe
.
getErrorOffset
();
if
(
errorOffset
==
expected
)
{
if
(
verbose
)
{
System
.
out
.
print
(
" Passed: NumberFormat("
+
locale
);
System
.
out
.
println
(
").parse(\""
+
given
+
"\")"
);
System
.
out
.
print
(
" threw ParseException as expected, and its errorOffset was correct: "
);
System
.
out
.
println
(
errorOffset
);
}
}
else
{
err
=
true
;
System
.
err
.
print
(
" Failed: NumberFormat("
+
locale
);
System
.
err
.
println
(
").parse(\""
+
given
+
"\")"
);
System
.
err
.
print
(
" threw ParseException as expected, but its errorOffset was incorrect: "
);
System
.
err
.
println
(
errorOffset
);
}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录