Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
778748d1
提交
778748d1
authored
7 年前
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Reimplement TO_DATE without a Calendar and fix a lot of bugs an incompatibilities
上级
aac17564
master
version-1.4.198
version-1.4.197
无相关合并请求
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
360 行增加
和
210 行删除
+360
-210
Function.java
h2/src/main/org/h2/expression/Function.java
+11
-5
ToChar.java
h2/src/main/org/h2/util/ToChar.java
+3
-3
ToDateParser.java
h2/src/main/org/h2/util/ToDateParser.java
+202
-40
ToDateTokenizer.java
h2/src/main/org/h2/util/ToDateTokenizer.java
+77
-103
TestFunctions.java
h2/src/test/org/h2/test/db/TestFunctions.java
+67
-59
没有找到文件。
h2/src/main/org/h2/expression/Function.java
浏览文件 @
778748d1
...
@@ -98,7 +98,7 @@ public class Function extends Expression implements FunctionCall {
...
@@ -98,7 +98,7 @@ public class Function extends Expression implements FunctionCall {
XMLATTR
=
83
,
XMLNODE
=
84
,
XMLCOMMENT
=
85
,
XMLCDATA
=
86
,
XMLATTR
=
83
,
XMLNODE
=
84
,
XMLCOMMENT
=
85
,
XMLCDATA
=
86
,
XMLSTARTDOC
=
87
,
XMLTEXT
=
88
,
REGEXP_REPLACE
=
89
,
RPAD
=
90
,
XMLSTARTDOC
=
87
,
XMLTEXT
=
88
,
REGEXP_REPLACE
=
89
,
RPAD
=
90
,
LPAD
=
91
,
CONCAT_WS
=
92
,
TO_CHAR
=
93
,
TRANSLATE
=
94
,
ORA_HASH
=
95
,
LPAD
=
91
,
CONCAT_WS
=
92
,
TO_CHAR
=
93
,
TRANSLATE
=
94
,
ORA_HASH
=
95
,
TO_DATE
=
96
,
TO_TIMESTAMP
=
97
,
ADD_MONTHS
=
98
;
TO_DATE
=
96
,
TO_TIMESTAMP
=
97
,
ADD_MONTHS
=
98
,
TO_TIMESTAMP_TZ
=
99
;
public
static
final
int
CURDATE
=
100
,
CURTIME
=
101
,
DATE_ADD
=
102
,
public
static
final
int
CURDATE
=
100
,
CURTIME
=
101
,
DATE_ADD
=
102
,
DATE_DIFF
=
103
,
DAY_NAME
=
104
,
DAY_OF_MONTH
=
105
,
DATE_DIFF
=
103
,
DAY_NAME
=
104
,
DAY_OF_MONTH
=
105
,
...
@@ -335,6 +335,7 @@ public class Function extends Expression implements FunctionCall {
...
@@ -335,6 +335,7 @@ public class Function extends Expression implements FunctionCall {
addFunction
(
"TO_DATE"
,
TO_DATE
,
VAR_ARGS
,
Value
.
TIMESTAMP
);
addFunction
(
"TO_DATE"
,
TO_DATE
,
VAR_ARGS
,
Value
.
TIMESTAMP
);
addFunction
(
"TO_TIMESTAMP"
,
TO_TIMESTAMP
,
VAR_ARGS
,
Value
.
TIMESTAMP
);
addFunction
(
"TO_TIMESTAMP"
,
TO_TIMESTAMP
,
VAR_ARGS
,
Value
.
TIMESTAMP
);
addFunction
(
"ADD_MONTHS"
,
ADD_MONTHS
,
2
,
Value
.
TIMESTAMP
);
addFunction
(
"ADD_MONTHS"
,
ADD_MONTHS
,
2
,
Value
.
TIMESTAMP
);
addFunction
(
"TO_TIMESTAMP_TZ"
,
TO_TIMESTAMP_TZ
,
VAR_ARGS
,
Value
.
TIMESTAMP_TZ
);
// alias for MSSQLServer
// alias for MSSQLServer
addFunctionNotDeterministic
(
"GETDATE"
,
CURDATE
,
addFunctionNotDeterministic
(
"GETDATE"
,
CURDATE
,
0
,
Value
.
DATE
);
0
,
Value
.
DATE
);
...
@@ -1455,16 +1456,20 @@ public class Function extends Expression implements FunctionCall {
...
@@ -1455,16 +1456,20 @@ public class Function extends Expression implements FunctionCall {
}
}
break
;
break
;
case
TO_DATE:
case
TO_DATE:
result
=
ValueTimestamp
.
get
(
ToDateParser
.
toDate
(
v0
.
getString
(),
result
=
ToDateParser
.
toDate
(
v0
.
getString
(),
v1
==
null
?
null
:
v1
.
getString
())
)
;
v1
==
null
?
null
:
v1
.
getString
());
break
;
break
;
case
TO_TIMESTAMP:
case
TO_TIMESTAMP:
result
=
ValueTimestamp
.
get
(
ToDateParser
.
toTimestamp
(
v0
.
getString
(),
result
=
ToDateParser
.
toTimestamp
(
v0
.
getString
(),
v1
==
null
?
null
:
v1
.
getString
())
)
;
v1
==
null
?
null
:
v1
.
getString
());
break
;
break
;
case
ADD_MONTHS:
case
ADD_MONTHS:
result
=
dateadd
(
"MONTH"
,
v1
.
getInt
(),
v0
);
result
=
dateadd
(
"MONTH"
,
v1
.
getInt
(),
v0
);
break
;
break
;
case
TO_TIMESTAMP_TZ:
result
=
ToDateParser
.
toTimestampTz
(
v0
.
getString
(),
v1
==
null
?
null
:
v1
.
getString
());
break
;
case
TRANSLATE:
{
case
TRANSLATE:
{
String
matching
=
v1
.
getString
();
String
matching
=
v1
.
getString
();
String
replacement
=
v2
.
getString
();
String
replacement
=
v2
.
getString
();
...
@@ -2307,6 +2312,7 @@ public class Function extends Expression implements FunctionCall {
...
@@ -2307,6 +2312,7 @@ public class Function extends Expression implements FunctionCall {
case
XMLTEXT:
case
XMLTEXT:
case
TRUNCATE:
case
TRUNCATE:
case
TO_TIMESTAMP:
case
TO_TIMESTAMP:
case
TO_TIMESTAMP_TZ:
min
=
1
;
min
=
1
;
max
=
2
;
max
=
2
;
break
;
break
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/util/ToChar.java
浏览文件 @
778748d1
...
@@ -28,7 +28,7 @@ public class ToChar {
...
@@ -28,7 +28,7 @@ public class ToChar {
/**
/**
* The beginning of the Julian calendar.
* The beginning of the Julian calendar.
*/
*/
private
static
final
int
JULIAN_EPOCH
=
-
2_440_588
;
static
final
int
JULIAN_EPOCH
=
-
2_440_588
;
private
static
final
int
[]
ROMAN_VALUES
=
{
1000
,
900
,
500
,
400
,
100
,
90
,
50
,
40
,
10
,
9
,
private
static
final
int
[]
ROMAN_VALUES
=
{
1000
,
900
,
500
,
400
,
100
,
90
,
50
,
40
,
10
,
9
,
5
,
4
,
1
};
5
,
4
,
1
};
...
@@ -36,7 +36,7 @@ public class ToChar {
...
@@ -36,7 +36,7 @@ public class ToChar {
private
static
final
String
[]
ROMAN_NUMERALS
=
{
"M"
,
"CM"
,
"D"
,
"CD"
,
"C"
,
"XC"
,
private
static
final
String
[]
ROMAN_NUMERALS
=
{
"M"
,
"CM"
,
"D"
,
"CD"
,
"C"
,
"XC"
,
"L"
,
"XL"
,
"X"
,
"IX"
,
"V"
,
"IV"
,
"I"
};
"L"
,
"XL"
,
"X"
,
"IX"
,
"V"
,
"IV"
,
"I"
};
private
static
final
int
MONTHS
=
0
,
SHORT_MONTHS
=
1
,
WEEKDAYS
=
2
,
SHORT_WEEKDAYS
=
3
,
AM_PM
=
4
;
static
final
int
MONTHS
=
0
,
SHORT_MONTHS
=
1
,
WEEKDAYS
=
2
,
SHORT_WEEKDAYS
=
3
,
AM_PM
=
4
;
private
static
volatile
String
[][]
NAMES
;
private
static
volatile
String
[][]
NAMES
;
...
@@ -454,7 +454,7 @@ public class ToChar {
...
@@ -454,7 +454,7 @@ public class ToChar {
return
hex
;
return
hex
;
}
}
private
static
String
[]
getNames
(
int
names
)
{
static
String
[]
getNames
(
int
names
)
{
String
[][]
result
=
NAMES
;
String
[][]
result
=
NAMES
;
if
(
result
==
null
)
{
if
(
result
==
null
)
{
result
=
new
String
[
5
][];
result
=
new
String
[
5
][];
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/util/ToDateParser.java
浏览文件 @
778748d1
...
@@ -7,9 +7,13 @@ package org.h2.util;
...
@@ -7,9 +7,13 @@ package org.h2.util;
import
static
java
.
lang
.
String
.
format
;
import
static
java
.
lang
.
String
.
format
;
import
java.sql.Timestamp
;
import
java.util.Calendar
;
import
java.util.Calendar
;
import
java.util.GregorianCalendar
;
import
java.util.List
;
import
java.util.List
;
import
java.util.TimeZone
;
import
org.h2.value.ValueTimestamp
;
import
org.h2.value.ValueTimestampTimeZone
;
/**
/**
* Emulates Oracle's TO_DATE function.<br>
* Emulates Oracle's TO_DATE function.<br>
...
@@ -21,8 +25,29 @@ public class ToDateParser {
...
@@ -21,8 +25,29 @@ public class ToDateParser {
private
final
ConfigParam
functionName
;
private
final
ConfigParam
functionName
;
private
String
inputStr
;
private
String
inputStr
;
private
String
formatStr
;
private
String
formatStr
;
private
final
Calendar
resultCalendar
=
DateTimeUtils
.
createGregorianCalendar
();
private
Integer
nanos
;
private
boolean
doyValid
=
false
,
absoluteDayValid
=
false
,
hour12Valid
=
false
,
timeZoneHMValid
=
false
;
private
boolean
bc
;
private
long
absoluteDay
;
private
int
year
,
month
,
day
=
1
;
private
int
dayOfYear
;
private
int
hour
,
minute
,
second
,
nanos
;
private
int
hour12
;
boolean
isAM
=
true
;
private
TimeZone
timeZone
;
private
int
timeZoneHour
,
timeZoneMinute
;
private
int
currentYear
,
currentMonth
;
/**
/**
* @param input the input date with the date-time info
* @param input the input date with the date-time info
...
@@ -32,18 +57,6 @@ public class ToDateParser {
...
@@ -32,18 +57,6 @@ public class ToDateParser {
*/
*/
private
ToDateParser
(
ConfigParam
functionName
,
String
input
,
String
format
)
{
private
ToDateParser
(
ConfigParam
functionName
,
String
input
,
String
format
)
{
// reset calendar - default oracle behaviour
// reset calendar - default oracle behaviour
resultCalendar
.
set
(
Calendar
.
YEAR
,
1970
);
resultCalendar
.
set
(
Calendar
.
MONTH
,
DateTimeUtils
.
createGregorianCalendar
().
get
(
Calendar
.
MONTH
));
resultCalendar
.
clear
(
Calendar
.
DAY_OF_YEAR
);
resultCalendar
.
clear
(
Calendar
.
DAY_OF_WEEK
);
resultCalendar
.
clear
(
Calendar
.
DAY_OF_WEEK_IN_MONTH
);
resultCalendar
.
set
(
Calendar
.
DAY_OF_MONTH
,
1
);
resultCalendar
.
set
(
Calendar
.
HOUR
,
0
);
resultCalendar
.
set
(
Calendar
.
HOUR_OF_DAY
,
0
);
resultCalendar
.
set
(
Calendar
.
MINUTE
,
0
);
resultCalendar
.
set
(
Calendar
.
SECOND
,
0
);
resultCalendar
.
set
(
Calendar
.
MILLISECOND
,
0
);
resultCalendar
.
set
(
Calendar
.
AM_PM
,
Calendar
.
AM
);
this
.
functionName
=
functionName
;
this
.
functionName
=
functionName
;
inputStr
=
input
.
trim
();
inputStr
=
input
.
trim
();
...
@@ -59,30 +72,65 @@ public class ToDateParser {
...
@@ -59,30 +72,65 @@ public class ToDateParser {
unmodifiedFormatStr
=
formatStr
;
unmodifiedFormatStr
=
formatStr
;
}
}
private
static
ToDateParser
getDateParser
(
String
input
,
String
format
)
{
private
static
ToDateParser
getTimestampParser
(
ConfigParam
param
,
String
input
,
String
format
)
{
ToDateParser
result
=
new
ToDateParser
(
ConfigParam
.
TO_DATE
,
input
,
format
);
ToDateParser
result
=
new
ToDateParser
(
param
,
input
,
format
);
parse
(
result
);
return
result
;
}
private
static
ToDateParser
getTimestampParser
(
String
input
,
String
format
)
{
ToDateParser
result
=
new
ToDateParser
(
ConfigParam
.
TO_TIMESTAMP
,
input
,
format
);
parse
(
result
);
parse
(
result
);
return
result
;
return
result
;
}
}
private
Timestamp
getResultingTimestamp
()
{
private
ValueTimestamp
getResultingValue
()
{
Calendar
cal
=
(
Calendar
)
getResultCalendar
().
clone
();
long
dateValue
;
int
nanosToSet
=
nanos
==
null
?
if
(
absoluteDayValid
)
{
cal
.
get
(
Calendar
.
MILLISECOND
)
*
1000000
:
nanos
.
intValue
();
dateValue
=
DateTimeUtils
.
dateValueFromAbsoluteDay
(
absoluteDay
);
cal
.
set
(
Calendar
.
MILLISECOND
,
0
);
}
else
{
Timestamp
ts
=
new
Timestamp
(
cal
.
getTimeInMillis
());
int
year
=
this
.
year
;
ts
.
setNanos
(
nanosToSet
);
if
(
year
==
0
)
{
return
ts
;
year
=
getCurrentYear
();
}
if
(
bc
)
{
year
=
1
-
year
;
}
if
(
doyValid
)
{
dateValue
=
DateTimeUtils
.
dateValueFromAbsoluteDay
(
DateTimeUtils
.
absoluteDayFromDateValue
(
DateTimeUtils
.
dateValue
(
year
,
1
,
1
))
+
dayOfYear
-
1
);
}
else
{
int
month
=
this
.
month
;
if
(
month
==
0
)
{
// Oracle uses current month as default
month
=
getCurrentMonth
();
}
dateValue
=
DateTimeUtils
.
dateValue
(
year
,
month
,
day
);
}
}
int
hour
;
if
(
hour12Valid
)
{
hour
=
hour12
%
12
;
if
(!
isAM
)
{
hour
+=
12
;
}
}
else
{
hour
=
this
.
hour
;
}
long
timeNanos
=
((((
hour
*
60
)
+
minute
)
*
60
)
+
second
)
*
1_000_000_000L
+
nanos
;
return
ValueTimestamp
.
fromDateValueAndNanos
(
dateValue
,
timeNanos
);
}
}
Calendar
getResultCalendar
()
{
private
ValueTimestampTimeZone
getResultingValueWithTimeZone
()
{
return
resultCalendar
;
ValueTimestamp
ts
=
getResultingValue
();
long
dateValue
=
ts
.
getDateValue
();
short
offset
;
if
(
timeZoneHMValid
)
{
offset
=
(
short
)
(
timeZoneHour
*
60
+
((
timeZoneHour
>=
0
)
?
timeZoneMinute
:
-
timeZoneMinute
));
}
else
{
TimeZone
timeZone
=
this
.
timeZone
;
if
(
timeZone
==
null
)
{
timeZone
=
TimeZone
.
getDefault
();
}
long
millis
=
DateTimeUtils
.
convertDateTimeValueToMillis
(
timeZone
,
dateValue
,
nanos
/
1000000
);
offset
=
(
short
)
(
timeZone
.
getOffset
(
millis
)
/
1000
/
60
);
}
return
ValueTimestampTimeZone
.
fromDateValueAndNanos
(
dateValue
,
ts
.
getTimeNanos
(),
offset
);
}
}
String
getInputStr
()
{
String
getInputStr
()
{
...
@@ -97,10 +145,111 @@ public class ToDateParser {
...
@@ -97,10 +145,111 @@ public class ToDateParser {
return
functionName
.
name
();
return
functionName
.
name
();
}
}
private
void
queryCurrentYearAndMonth
()
{
GregorianCalendar
gc
=
DateTimeUtils
.
getCalendar
();
gc
.
setTimeInMillis
(
System
.
currentTimeMillis
());
currentYear
=
gc
.
get
(
Calendar
.
YEAR
);
currentMonth
=
gc
.
get
(
Calendar
.
MONTH
)
+
1
;
}
int
getCurrentYear
()
{
if
(
currentYear
==
0
)
{
queryCurrentYearAndMonth
();
}
return
currentYear
;
}
int
getCurrentMonth
()
{
if
(
currentMonth
==
0
)
{
queryCurrentYearAndMonth
();
}
return
currentMonth
;
}
void
setAbsoluteDay
(
int
absoluteDay
)
{
doyValid
=
false
;
absoluteDayValid
=
true
;
this
.
absoluteDay
=
absoluteDay
;
}
void
setBC
(
boolean
bc
)
{
doyValid
=
false
;
absoluteDayValid
=
false
;
this
.
bc
=
bc
;
}
void
setYear
(
int
year
)
{
doyValid
=
false
;
absoluteDayValid
=
false
;
this
.
year
=
year
;
}
void
setMonth
(
int
month
)
{
doyValid
=
false
;
absoluteDayValid
=
false
;
this
.
month
=
month
;
if
(
year
==
0
)
{
year
=
1970
;
}
}
void
setDay
(
int
day
)
{
doyValid
=
false
;
absoluteDayValid
=
false
;
this
.
day
=
day
;
if
(
year
==
0
)
{
year
=
1970
;
}
}
void
setDayOfYear
(
int
dayOfYear
)
{
doyValid
=
true
;
absoluteDayValid
=
false
;
this
.
dayOfYear
=
dayOfYear
;
}
void
setHour
(
int
hour
)
{
hour12Valid
=
false
;
this
.
hour
=
hour
;
}
void
setMinute
(
int
minute
)
{
this
.
minute
=
minute
;
}
void
setSecord
(
int
second
)
{
this
.
second
=
second
;
}
void
setNanos
(
int
nanos
)
{
void
setNanos
(
int
nanos
)
{
this
.
nanos
=
nanos
;
this
.
nanos
=
nanos
;
}
}
void
setAmPm
(
boolean
isAM
)
{
hour12Valid
=
true
;
this
.
isAM
=
isAM
;
}
void
setHour12
(
int
hour12
)
{
hour12Valid
=
true
;
this
.
hour12
=
hour12
;
}
void
setTimeZone
(
TimeZone
timeZone
)
{
timeZoneHMValid
=
false
;
this
.
timeZone
=
timeZone
;
}
void
setTimeZoneHour
(
int
timeZoneHour
)
{
timeZoneHMValid
=
true
;
this
.
timeZoneHour
=
timeZoneHour
;
}
void
setTimeZoneMinute
(
int
timeZoneMinute
)
{
timeZoneHMValid
=
true
;
this
.
timeZoneMinute
=
timeZoneMinute
;
}
private
boolean
hasToParseData
()
{
private
boolean
hasToParseData
()
{
return
formatStr
.
length
()
>
0
;
return
formatStr
.
length
()
>
0
;
}
}
...
@@ -180,9 +329,21 @@ public class ToDateParser {
...
@@ -180,9 +329,21 @@ public class ToDateParser {
* @param format the format
* @param format the format
* @return the timestamp
* @return the timestamp
*/
*/
public
static
Timestamp
toTimestamp
(
String
input
,
String
format
)
{
public
static
ValueTimestamp
toTimestamp
(
String
input
,
String
format
)
{
ToDateParser
parser
=
getTimestampParser
(
input
,
format
);
ToDateParser
parser
=
getTimestampParser
(
ConfigParam
.
TO_TIMESTAMP
,
input
,
format
);
return
parser
.
getResultingTimestamp
();
return
parser
.
getResultingValue
();
}
/**
* Parse a string as a timestamp with the given format.
*
* @param input the input
* @param format the format
* @return the timestamp
*/
public
static
ValueTimestampTimeZone
toTimestampTz
(
String
input
,
String
format
)
{
ToDateParser
parser
=
getTimestampParser
(
ConfigParam
.
TO_TIMESTAMP_TZ
,
input
,
format
);
return
parser
.
getResultingValueWithTimeZone
();
}
}
/**
/**
...
@@ -192,9 +353,9 @@ public class ToDateParser {
...
@@ -192,9 +353,9 @@ public class ToDateParser {
* @param format the format
* @param format the format
* @return the date as a timestamp
* @return the date as a timestamp
*/
*/
public
static
Timestamp
toDate
(
String
input
,
String
format
)
{
public
static
Value
Timestamp
toDate
(
String
input
,
String
format
)
{
ToDateParser
parser
=
get
DateParser
(
input
,
format
);
ToDateParser
parser
=
get
TimestampParser
(
ConfigParam
.
TO_DATE
,
input
,
format
);
return
parser
.
getResulting
Timestamp
();
return
parser
.
getResulting
Value
();
}
}
/**
/**
...
@@ -202,7 +363,8 @@ public class ToDateParser {
...
@@ -202,7 +363,8 @@ public class ToDateParser {
*/
*/
private
enum
ConfigParam
{
private
enum
ConfigParam
{
TO_DATE
(
"DD MON YYYY"
),
TO_DATE
(
"DD MON YYYY"
),
TO_TIMESTAMP
(
"DD MON YYYY HH:MI:SS"
);
TO_TIMESTAMP
(
"DD MON YYYY HH:MI:SS"
),
TO_TIMESTAMP_TZ
(
"DD MON YYYY HH:MI:SS TZR"
);
private
final
String
defaultFormatStr
;
private
final
String
defaultFormatStr
;
ConfigParam
(
String
defaultFormatStr
)
{
ConfigParam
(
String
defaultFormatStr
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/util/ToDateTokenizer.java
浏览文件 @
778748d1
...
@@ -6,17 +6,12 @@
...
@@ -6,17 +6,12 @@
package
org
.
h2
.
util
;
package
org
.
h2
.
util
;
import
static
java
.
lang
.
String
.
format
;
import
static
java
.
lang
.
String
.
format
;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Calendar
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.Date
;
import
java.util.GregorianCalendar
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.TimeZone
;
import
java.util.TimeZone
;
import
java.util.regex.Matcher
;
import
java.util.regex.Matcher
;
...
@@ -144,10 +139,10 @@ class ToDateTokenizer {
...
@@ -144,10 +139,10 @@ class ToDateTokenizer {
* Parslet responsible for parsing year parameter
* Parslet responsible for parsing year parameter
*/
*/
static
class
YearParslet
implements
ToDateParslet
{
static
class
YearParslet
implements
ToDateParslet
{
@Override
@Override
public
void
parse
(
ToDateParser
params
,
FormatTokenEnum
formatTokenEnum
,
public
void
parse
(
ToDateParser
params
,
FormatTokenEnum
formatTokenEnum
,
String
formatTokenStr
)
{
String
formatTokenStr
)
{
Calendar
result
=
params
.
getResultCalendar
();
String
inputFragmentStr
=
null
;
String
inputFragmentStr
=
null
;
int
dateNr
=
0
;
int
dateNr
=
0
;
switch
(
formatTokenEnum
)
{
switch
(
formatTokenEnum
)
{
...
@@ -156,26 +151,26 @@ class ToDateTokenizer {
...
@@ -156,26 +151,26 @@ class ToDateTokenizer {
case
IYYY:
case
IYYY:
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_FOUR_DIGITS
,
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_FOUR_DIGITS
,
params
,
formatTokenEnum
);
params
,
formatTokenEnum
);
// only necessary for Java1.6
if
(
inputFragmentStr
.
startsWith
(
"+"
))
{
inputFragmentStr
=
inputFragmentStr
.
substring
(
1
);
}
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
// Gregorian calendar does not have a year 0.
// Gregorian calendar does not have a year 0.
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
if
(
dateNr
==
0
)
{
if
(
dateNr
==
0
)
{
throwException
(
params
,
"Year may not be zero"
);
throwException
(
params
,
"Year may not be zero"
);
}
}
result
.
set
(
Calendar
.
YEAR
,
dateNr
>=
0
?
dateNr
:
dateNr
+
1
);
params
.
setYear
(
dateNr
>=
0
?
dateNr
:
dateNr
+
1
);
break
;
break
;
case
YYY:
case
YYY:
case
IYY:
case
IYY:
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_THREE_DIGITS
,
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_THREE_DIGITS
,
params
,
formatTokenEnum
);
params
,
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
if
(
dateNr
>
999
)
{
throwException
(
params
,
"Year may have only three digits with specified format"
);
}
dateNr
+=
(
params
.
getCurrentYear
()
/
1_000
)
*
1_000
;
// Gregorian calendar does not have a year 0.
// Gregorian calendar does not have a year 0.
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
result
.
set
(
Calendar
.
YEAR
,
dateNr
>=
0
?
dateNr
:
dateNr
+
1
);
params
.
setYear
(
dateNr
>=
0
?
dateNr
:
dateNr
+
1
);
break
;
break
;
case
RRRR:
case
RRRR:
inputFragmentStr
=
matchStringOrThrow
(
inputFragmentStr
=
matchStringOrThrow
(
...
@@ -191,15 +186,14 @@ class ToDateTokenizer {
...
@@ -191,15 +186,14 @@ class ToDateTokenizer {
if
(
dateNr
==
0
)
{
if
(
dateNr
==
0
)
{
throwException
(
params
,
"Year may not be zero"
);
throwException
(
params
,
"Year may not be zero"
);
}
}
result
.
set
(
Calendar
.
YEAR
,
dateNr
);
params
.
setYear
(
dateNr
);
break
;
break
;
case
RR:
case
RR:
Calendar
calendar
=
DateTimeUtils
.
createGregorianCalendar
();
int
cc
=
params
.
getCurrentYear
()
/
100
;
int
cc
=
calendar
.
get
(
Calendar
.
YEAR
)
/
100
;
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_TWO_DIGITS
,
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_TWO_DIGITS
,
params
,
formatTokenEnum
);
params
,
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
)
+
cc
*
100
;
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
)
+
cc
*
100
;
result
.
set
(
Calendar
.
YEAR
,
dateNr
);
params
.
setYear
(
dateNr
);
break
;
break
;
case
EE
/* NOT supported yet */
:
case
EE
/* NOT supported yet */
:
throwException
(
params
,
format
(
"token '%s' not supported yet."
,
throwException
(
params
,
format
(
"token '%s' not supported yet."
,
...
@@ -214,34 +208,38 @@ class ToDateTokenizer {
...
@@ -214,34 +208,38 @@ class ToDateTokenizer {
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_TWO_DIGITS
,
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_TWO_DIGITS
,
params
,
formatTokenEnum
);
params
,
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
if
(
dateNr
>
99
)
{
throwException
(
params
,
"Year may have only two digits with specified format"
);
}
dateNr
+=
(
params
.
getCurrentYear
()
/
100
)
*
100
;
// Gregorian calendar does not have a year 0.
// Gregorian calendar does not have a year 0.
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
result
.
set
(
Calendar
.
YEAR
,
dateNr
>=
0
?
dateNr
:
dateNr
+
1
);
params
.
setYear
(
dateNr
>=
0
?
dateNr
:
dateNr
+
1
);
break
;
break
;
case
SCC:
case
SCC:
case
CC:
case
CC:
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_TWO_DIGITS
,
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_TWO_DIGITS
,
params
,
formatTokenEnum
);
params
,
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
)
*
100
;
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
)
*
100
;
result
.
set
(
Calendar
.
YEAR
,
dateNr
);
params
.
setYear
(
dateNr
);
break
;
break
;
case
Y:
case
Y:
case
I:
case
I:
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_ONE_DIGIT
,
params
,
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_ONE_DIGIT
,
params
,
formatTokenEnum
);
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
if
(
dateNr
>
9
)
{
throwException
(
params
,
"Year may have only two digits with specified format"
);
}
dateNr
+=
(
params
.
getCurrentYear
()
/
10
)
*
10
;
// Gregorian calendar does not have a year 0.
// Gregorian calendar does not have a year 0.
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
result
.
set
(
Calendar
.
YEAR
,
dateNr
>=
0
?
dateNr
:
dateNr
+
1
);
params
.
setYear
(
dateNr
>=
0
?
dateNr
:
dateNr
+
1
);
break
;
break
;
case
BC_AD:
case
BC_AD:
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_BC_AD
,
params
,
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_BC_AD
,
params
,
formatTokenEnum
);
formatTokenEnum
);
if
(
inputFragmentStr
.
toUpperCase
().
startsWith
(
"B"
))
{
params
.
setBC
(
inputFragmentStr
.
toUpperCase
().
startsWith
(
"B"
));
result
.
set
(
Calendar
.
ERA
,
GregorianCalendar
.
BC
);
}
else
{
result
.
set
(
Calendar
.
ERA
,
GregorianCalendar
.
AD
);
}
break
;
break
;
default
:
default
:
throw
new
IllegalArgumentException
(
format
(
throw
new
IllegalArgumentException
(
format
(
...
@@ -262,29 +260,26 @@ class ToDateTokenizer {
...
@@ -262,29 +260,26 @@ class ToDateTokenizer {
@Override
@Override
public
void
parse
(
ToDateParser
params
,
FormatTokenEnum
formatTokenEnum
,
public
void
parse
(
ToDateParser
params
,
FormatTokenEnum
formatTokenEnum
,
String
formatTokenStr
)
{
String
formatTokenStr
)
{
Calendar
result
=
params
.
getResultCalendar
();
String
s
=
params
.
getInputStr
();
String
s
=
params
.
getInputStr
();
String
inputFragmentStr
=
null
;
String
inputFragmentStr
=
null
;
int
dateNr
=
0
;
int
dateNr
=
0
;
switch
(
formatTokenEnum
)
{
switch
(
formatTokenEnum
)
{
case
MONTH:
case
MONTH:
inputFragmentStr
=
setByName
(
result
,
params
,
Calendar
.
MONTH
,
inputFragmentStr
=
setByName
(
params
,
ToChar
.
MONTHS
);
Calendar
.
LONG
);
break
;
break
;
case
Q
/* NOT supported yet */
:
case
Q
/* NOT supported yet */
:
throwException
(
params
,
format
(
"token '%s' not supported yet."
,
throwException
(
params
,
format
(
"token '%s' not supported yet."
,
formatTokenEnum
.
name
()));
formatTokenEnum
.
name
()));
break
;
break
;
case
MON:
case
MON:
inputFragmentStr
=
setByName
(
result
,
params
,
Calendar
.
MONTH
,
inputFragmentStr
=
setByName
(
params
,
ToChar
.
SHORT_MONTHS
);
Calendar
.
SHORT
);
break
;
break
;
case
MM:
case
MM:
// Note: In Calendar Month go from 0 - 11
// Note: In Calendar Month go from 0 - 11
inputFragmentStr
=
matchStringOrThrow
(
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
result
.
set
(
Calendar
.
MONTH
,
dateNr
-
1
);
params
.
setMonth
(
dateNr
);
break
;
break
;
case
RM:
case
RM:
dateNr
=
0
;
dateNr
=
0
;
...
@@ -293,7 +288,7 @@ class ToDateTokenizer {
...
@@ -293,7 +288,7 @@ class ToDateTokenizer {
int
len
=
monthName
.
length
();
int
len
=
monthName
.
length
();
if
(
s
.
length
()
>=
len
&&
monthName
if
(
s
.
length
()
>=
len
&&
monthName
.
equalsIgnoreCase
(
s
.
substring
(
0
,
len
)))
{
.
equalsIgnoreCase
(
s
.
substring
(
0
,
len
)))
{
result
.
set
(
Calendar
.
MONTH
,
dateNr
);
params
.
setMonth
(
dateNr
+
1
);
inputFragmentStr
=
monthName
;
inputFragmentStr
=
monthName
;
break
;
break
;
}
}
...
@@ -322,7 +317,6 @@ class ToDateTokenizer {
...
@@ -322,7 +317,6 @@ class ToDateTokenizer {
@Override
@Override
public
void
parse
(
ToDateParser
params
,
FormatTokenEnum
formatTokenEnum
,
public
void
parse
(
ToDateParser
params
,
FormatTokenEnum
formatTokenEnum
,
String
formatTokenStr
)
{
String
formatTokenStr
)
{
Calendar
result
=
params
.
getResultCalendar
();
String
inputFragmentStr
=
null
;
String
inputFragmentStr
=
null
;
int
dateNr
=
0
;
int
dateNr
=
0
;
switch
(
formatTokenEnum
)
{
switch
(
formatTokenEnum
)
{
...
@@ -330,40 +324,31 @@ class ToDateTokenizer {
...
@@ -330,40 +324,31 @@ class ToDateTokenizer {
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_NUMBER
,
params
,
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_NUMBER
,
params
,
formatTokenEnum
);
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
result
.
set
(
Calendar
.
DAY_OF_YEAR
,
dateNr
);
params
.
setDayOfYear
(
dateNr
);
break
;
break
;
case
DD:
case
DD:
inputFragmentStr
=
matchStringOrThrow
(
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
result
.
set
(
Calendar
.
DAY_OF_MONTH
,
dateNr
);
params
.
setDay
(
dateNr
);
break
;
break
;
case
D:
case
D:
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_ONE_DIGIT
,
params
,
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_ONE_DIGIT
,
params
,
formatTokenEnum
);
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
result
.
set
(
Calendar
.
DAY_OF_MONTH
,
dateNr
);
params
.
setDay
(
dateNr
);
break
;
break
;
case
DAY:
case
DAY:
inputFragmentStr
=
setByName
(
result
,
params
,
inputFragmentStr
=
setByName
(
params
,
ToChar
.
WEEKDAYS
);
Calendar
.
DAY_OF_WEEK
,
Calendar
.
LONG
);
break
;
break
;
case
DY:
case
DY:
inputFragmentStr
=
setByName
(
result
,
params
,
inputFragmentStr
=
setByName
(
params
,
ToChar
.
SHORT_WEEKDAYS
);
Calendar
.
DAY_OF_WEEK
,
Calendar
.
SHORT
);
break
;
break
;
case
J:
case
J:
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_NUMBER
,
params
,
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_NUMBER
,
params
,
formatTokenEnum
);
formatTokenEnum
);
try
{
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
Date
date
=
new
SimpleDateFormat
(
"Myydd"
)
params
.
setAbsoluteDay
(
dateNr
+
ToChar
.
JULIAN_EPOCH
);
.
parse
(
inputFragmentStr
);
result
.
setTime
(
date
);
}
catch
(
ParseException
e
)
{
throwException
(
params
,
format
(
"Failed to parse Julian date: %s"
,
inputFragmentStr
));
}
break
;
break
;
default
:
default
:
throw
new
IllegalArgumentException
(
format
(
throw
new
IllegalArgumentException
(
format
(
...
@@ -382,7 +367,6 @@ class ToDateTokenizer {
...
@@ -382,7 +367,6 @@ class ToDateTokenizer {
@Override
@Override
public
void
parse
(
ToDateParser
params
,
FormatTokenEnum
formatTokenEnum
,
public
void
parse
(
ToDateParser
params
,
FormatTokenEnum
formatTokenEnum
,
String
formatTokenStr
)
{
String
formatTokenStr
)
{
Calendar
result
=
params
.
getResultCalendar
();
String
inputFragmentStr
=
null
;
String
inputFragmentStr
=
null
;
int
dateNr
=
0
;
int
dateNr
=
0
;
switch
(
formatTokenEnum
)
{
switch
(
formatTokenEnum
)
{
...
@@ -390,97 +374,76 @@ class ToDateTokenizer {
...
@@ -390,97 +374,76 @@ class ToDateTokenizer {
inputFragmentStr
=
matchStringOrThrow
(
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
result
.
set
(
Calendar
.
HOUR_OF_DAY
,
dateNr
);
params
.
setHour
(
dateNr
);
break
;
break
;
case
HH12:
case
HH12:
case
HH:
case
HH:
inputFragmentStr
=
matchStringOrThrow
(
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
result
.
set
(
Calendar
.
HOUR
,
dateNr
);
params
.
setHour12
(
dateNr
);
break
;
break
;
case
MI:
case
MI:
inputFragmentStr
=
matchStringOrThrow
(
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
result
.
set
(
Calendar
.
MINUTE
,
dateNr
);
params
.
setMinute
(
dateNr
);
break
;
break
;
case
SS:
case
SS:
inputFragmentStr
=
matchStringOrThrow
(
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
result
.
set
(
Calendar
.
SECOND
,
dateNr
);
params
.
setSecord
(
dateNr
);
break
;
break
;
case
SSSSS:
case
SSSSS:
{
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_NUMBER
,
params
,
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_NUMBER
,
params
,
formatTokenEnum
);
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
result
.
set
(
Calendar
.
HOUR_OF_DAY
,
0
);
int
second
=
dateNr
%
60
;
result
.
set
(
Calendar
.
MINUTE
,
0
);
dateNr
/=
60
;
result
.
set
(
Calendar
.
SECOND
,
dateNr
);
int
minute
=
dateNr
%
60
;
dateNr
/=
60
;
int
hour
=
dateNr
%
24
;
params
.
setHour
(
hour
);
params
.
setMinute
(
minute
);
params
.
setSecord
(
second
);
break
;
break
;
}
case
FF:
case
FF:
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_NUMBER
,
params
,
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_NUMBER
,
params
,
formatTokenEnum
);
formatTokenEnum
);
String
paddedRightNrStr
=
format
(
"%-9s"
,
inputFragmentStr
)
String
paddedRightNrStr
=
format
(
"%-9s"
,
inputFragmentStr
)
.
replace
(
' '
,
'0'
);
.
replace
(
' '
,
'0'
);
paddedRightNrStr
=
paddedRightNrStr
.
substring
(
0
,
9
);
paddedRightNrStr
=
paddedRightNrStr
.
substring
(
0
,
9
);
Double
nineDigits
=
Double
.
parseDouble
(
paddedRightNrStr
);
double
nineDigits
=
Double
.
parseDouble
(
paddedRightNrStr
);
params
.
setNanos
(
nineDigits
.
intValue
());
params
.
setNanos
((
int
)
nineDigits
);
dateNr
=
(
int
)
Math
.
round
(
nineDigits
/
1000000.0
);
result
.
set
(
Calendar
.
MILLISECOND
,
dateNr
);
break
;
break
;
case
AM_PM:
case
AM_PM:
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_AM_PM
,
params
,
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_AM_PM
,
params
,
formatTokenEnum
);
formatTokenEnum
);
if
(
inputFragmentStr
.
toUpperCase
().
startsWith
(
"A"
))
{
if
(
inputFragmentStr
.
toUpperCase
().
startsWith
(
"A"
))
{
result
.
set
(
Calendar
.
AM_PM
,
Calendar
.
AM
);
params
.
setAmPm
(
true
);
}
else
{
}
else
{
result
.
set
(
Calendar
.
AM_PM
,
Calendar
.
PM
);
params
.
setAmPm
(
false
);
}
}
break
;
break
;
case
TZH:
case
TZH:
inputFragmentStr
=
matchStringOrThrow
(
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
TimeZone
tz
=
result
.
getTimeZone
();
params
.
setTimeZoneHour
(
dateNr
);
int
offsetMillis
=
tz
.
getRawOffset
();
// purge min and sec
offsetMillis
=
(
offsetMillis
/
MILLIS_IN_HOUR
)
*
MILLIS_IN_HOUR
;
tz
.
setRawOffset
(
offsetMillis
+
dateNr
);
result
.
setTimeZone
(
tz
);
break
;
break
;
case
TZM:
case
TZM:
inputFragmentStr
=
matchStringOrThrow
(
inputFragmentStr
=
matchStringOrThrow
(
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
PATTERN_TWO_DIGITS_OR_LESS
,
params
,
formatTokenEnum
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
dateNr
=
Integer
.
parseInt
(
inputFragmentStr
);
tz
=
result
.
getTimeZone
();
params
.
setTimeZoneMinute
(
dateNr
);
offsetMillis
=
tz
.
getRawOffset
();
// purge hour
offsetMillis
=
offsetMillis
%
MILLIS_IN_HOUR
;
tz
.
setRawOffset
(
dateNr
*
MILLIS_IN_HOUR
+
offsetMillis
);
result
.
setTimeZone
(
tz
);
break
;
break
;
case
TZR:
case
TZR:
// Example: US/Pacific
String
s
=
params
.
getInputStr
();
tz
=
result
.
getTimeZone
();
for
(
String
tzName
:
TimeZone
.
getAvailableIDs
())
{
int
length
=
tzName
.
length
();
if
(
s
.
length
()
>=
length
&&
tzName
.
equalsIgnoreCase
(
s
.
substring
(
0
,
length
)))
{
tz
.
setID
(
tzName
);
result
.
setTimeZone
(
tz
);
inputFragmentStr
=
tzName
;
break
;
}
}
break
;
case
TZD:
case
TZD:
// Must correspond with TZR region. Example: PST (for US/Pacific
String
tzName
=
params
.
getInputStr
();
// standard time)
params
.
setTimeZone
(
TimeZone
.
getTimeZone
(
tzName
));
throwException
(
params
,
format
(
"token '%s' not supported yet."
,
inputFragmentStr
=
tzName
;
formatTokenEnum
.
name
()));
break
;
break
;
default
:
default
:
throw
new
IllegalArgumentException
(
format
(
throw
new
IllegalArgumentException
(
format
(
...
@@ -535,22 +498,33 @@ class ToDateTokenizer {
...
@@ -535,22 +498,33 @@ class ToDateTokenizer {
/**
/**
* Set the given field in the calendar.
* Set the given field in the calendar.
*
*
* @param c the calendar
* @param params the parameters with the input string
* @param params the parameters with the input string
* @param field the field to set
* @param field the field to set
* @param style the data type
* @return the matched value
* @return the matched value
*/
*/
static
String
setByName
(
Calendar
c
,
ToDateParser
params
,
int
field
,
static
String
setByName
(
ToDateParser
params
,
int
field
)
{
int
style
)
{
String
inputFragmentStr
=
null
;
String
inputFragmentStr
=
null
;
String
s
=
params
.
getInputStr
();
String
s
=
params
.
getInputStr
();
Map
<
String
,
Integer
>
timeStringMap
=
c
.
getDisplayNames
(
field
,
style
,
String
[]
values
=
ToChar
.
getNames
(
field
);
Locale
.
getDefault
());
for
(
int
i
=
0
;
i
<
values
.
length
;
i
++)
{
for
(
String
dayName
:
timeStringMap
.
keySet
())
{
String
dayName
=
values
[
i
];
if
(
dayName
==
null
)
{
continue
;
}
int
len
=
dayName
.
length
();
int
len
=
dayName
.
length
();
if
(
dayName
.
equalsIgnoreCase
(
s
.
substring
(
0
,
len
)))
{
if
(
dayName
.
equalsIgnoreCase
(
s
.
substring
(
0
,
len
)))
{
c
.
set
(
field
,
timeStringMap
.
get
(
dayName
));
switch
(
field
)
{
case
ToChar
.
MONTHS
:
case
ToChar
.
SHORT_MONTHS
:
params
.
setMonth
(
i
+
1
);
break
;
case
ToChar
.
WEEKDAYS
:
case
ToChar
.
SHORT_WEEKDAYS
:
// TODO
break
;
default
:
throw
new
IllegalArgumentException
();
}
inputFragmentStr
=
dayName
;
inputFragmentStr
=
dayName
;
break
;
break
;
}
}
...
@@ -558,7 +532,7 @@ class ToDateTokenizer {
...
@@ -558,7 +532,7 @@ class ToDateTokenizer {
if
(
inputFragmentStr
==
null
||
inputFragmentStr
.
isEmpty
())
{
if
(
inputFragmentStr
==
null
||
inputFragmentStr
.
isEmpty
())
{
throwException
(
params
,
format
(
throwException
(
params
,
format
(
"Tried to parse one of '%s' but failed (may be an internal error?)"
,
"Tried to parse one of '%s' but failed (may be an internal error?)"
,
timeStringMap
.
keySet
(
)));
Arrays
.
toString
(
values
)));
}
}
return
inputFragmentStr
;
return
inputFragmentStr
;
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/db/TestFunctions.java
浏览文件 @
778748d1
...
@@ -34,6 +34,7 @@ import java.util.ArrayList;
...
@@ -34,6 +34,7 @@ import java.util.ArrayList;
import
java.util.Calendar
;
import
java.util.Calendar
;
import
java.util.Currency
;
import
java.util.Currency
;
import
java.util.Date
;
import
java.util.Date
;
import
java.util.GregorianCalendar
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.Locale
;
import
java.util.Locale
;
import
java.util.Properties
;
import
java.util.Properties
;
...
@@ -56,6 +57,8 @@ import org.h2.util.StringUtils;
...
@@ -56,6 +57,8 @@ import org.h2.util.StringUtils;
import
org.h2.util.ToChar.Capitalization
;
import
org.h2.util.ToChar.Capitalization
;
import
org.h2.util.ToDateParser
;
import
org.h2.util.ToDateParser
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
import
org.h2.value.ValueTimestamp
;
import
org.h2.value.ValueTimestampTimeZone
;
/**
/**
* Tests for user defined functions and aggregates.
* Tests for user defined functions and aggregates.
...
@@ -1296,10 +1299,13 @@ public class TestFunctions extends TestBase implements AggregateFunction {
...
@@ -1296,10 +1299,13 @@ public class TestFunctions extends TestBase implements AggregateFunction {
}
}
private
void
testToDate
()
throws
ParseException
{
private
void
testToDate
()
throws
ParseException
{
final
int
month
=
DateTimeUtils
.
createGregorianCalendar
().
get
(
Calendar
.
MONTH
);
GregorianCalendar
calendar
=
DateTimeUtils
.
createGregorianCalendar
();
int
year
=
calendar
.
get
(
Calendar
.
YEAR
);
Date
date
=
null
;
int
month
=
calendar
.
get
(
Calendar
.
MONTH
)
+
1
;
date
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
).
parse
(
"1979-11-12"
);
// Default date in Oracle is the first day of the current month
String
defDate
=
year
+
"-"
+
month
+
"-1 "
;
ValueTimestamp
date
=
null
;
date
=
ValueTimestamp
.
parse
(
"1979-11-12"
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979-11-12T00:00:00Z"
,
"YYYY-MM-DD\"T\"HH24:MI:SS\"Z\""
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979-11-12T00:00:00Z"
,
"YYYY-MM-DD\"T\"HH24:MI:SS\"Z\""
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979*foo*1112"
,
"YYYY\"*foo*\"MM\"\"DD"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979*foo*1112"
,
"YYYY\"*foo*\"MM\"\"DD"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979-11-12"
,
"YYYY-MM-DD"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979-11-12"
,
"YYYY-MM-DD"
));
...
@@ -1309,8 +1315,7 @@ public class TestFunctions extends TestBase implements AggregateFunction {
...
@@ -1309,8 +1315,7 @@ public class TestFunctions extends TestBase implements AggregateFunction {
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979;11;12"
,
"YYYY;MM;DD"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979;11;12"
,
"YYYY;MM;DD"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979:11:12"
,
"YYYY:MM:DD"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979:11:12"
,
"YYYY:MM:DD"
));
date
=
new
SimpleDateFormat
(
"yyyy"
).
parse
(
"1979"
);
date
=
ValueTimestamp
.
parse
(
"1979-"
+
month
+
"-01"
);
setMonth
(
date
,
month
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979"
,
"YYYY"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979"
,
"YYYY"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979 AD"
,
"YYYY AD"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979 AD"
,
"YYYY AD"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979 A.D."
,
"YYYY A.D."
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1979 A.D."
,
"YYYY A.D."
));
...
@@ -1319,116 +1324,119 @@ public class TestFunctions extends TestBase implements AggregateFunction {
...
@@ -1319,116 +1324,119 @@ public class TestFunctions extends TestBase implements AggregateFunction {
assertEquals
(
date
,
ToDateParser
.
toDate
(
"+1979"
,
"SYYYY"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"+1979"
,
"SYYYY"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"79"
,
"RRRR"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"79"
,
"RRRR"
));
date
=
new
SimpleDateFormat
(
"yyyy-mm"
).
parse
(
"1970-12"
);
date
=
ValueTimestamp
.
parse
(
defDate
+
"00:12:00"
);
setMonth
(
date
,
month
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"12"
,
"MI"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"12"
,
"MI"
));
date
=
new
SimpleDateFormat
(
"yyyy-MM"
).
parse
(
"1970-1
1"
);
date
=
ValueTimestamp
.
parse
(
"1970-11-0
1"
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"11"
,
"MM"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"11"
,
"MM"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"11"
,
"Mm"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"11"
,
"Mm"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"11"
,
"mM"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"11"
,
"mM"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"11"
,
"mm"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"11"
,
"mm"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"XI"
,
"RM"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"XI"
,
"RM"
));
date
=
new
SimpleDateFormat
(
"yyyy"
).
parse
(
"9"
)
;
int
y
=
(
year
/
10
)
*
10
+
9
;
setMonth
(
date
,
month
);
date
=
ValueTimestamp
.
parse
(
y
+
"-"
+
month
+
"-01"
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"9"
,
"Y"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"9"
,
"Y"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"9"
,
"I"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"9"
,
"I"
));
date
=
new
SimpleDateFormat
(
"yyyy"
).
parse
(
"79"
)
;
y
=
(
year
/
100
)
*
100
+
79
;
setMonth
(
date
,
month
);
date
=
ValueTimestamp
.
parse
(
y
+
"-"
+
month
+
"-01"
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"79"
,
"YY"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"79"
,
"YY"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"79"
,
"IY"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"79"
,
"IY"
));
y
=
(
year
/
1_000
)
*
1_000
+
979
;
date
=
new
SimpleDateFormat
(
"yyyy"
).
parse
(
"979"
);
date
=
ValueTimestamp
.
parse
(
y
+
"-"
+
month
+
"-01"
);
setMonth
(
date
,
month
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"979"
,
"YYY"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"979"
,
"YYY"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"979"
,
"IYY"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"979"
,
"IYY"
));
// Gregorian calendar does not have a year 0.
// Gregorian calendar does not have a year 0.
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
date
=
new
SimpleDateFormat
(
"yyy"
).
parse
(
"-99"
);
date
=
ValueTimestamp
.
parse
(
"-99-"
+
month
+
"-01"
);
setMonth
(
date
,
month
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"0100 BC"
,
"YYYY BC"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"0100 BC"
,
"YYYY BC"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"0100 B.C."
,
"YYYY B.C."
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"0100 B.C."
,
"YYYY B.C."
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"100 BC"
,
"YYY BC"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"-0100"
,
"SYYYY"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"-0100"
,
"SYYYY"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"-0100"
,
"YYYY"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"-0100"
,
"YYYY"
));
// Gregorian calendar does not have a year 0.
// Gregorian calendar does not have a year 0.
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
date
=
new
SimpleDateFormat
(
"y"
).
parse
(
"0"
);
y
=
-((
year
/
1_000
)
*
1_000
+
99
);
setMonth
(
date
,
month
);
date
=
ValueTimestamp
.
parse
(
y
+
"-"
+
month
+
"-01"
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"100 BC"
,
"YYY BC"
));
// Gregorian calendar does not have a year 0.
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
y
=
-((
year
/
100
)
*
100
);
date
=
ValueTimestamp
.
parse
(
y
+
"-"
+
month
+
"-01"
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"01 BC"
,
"YY BC"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"01 BC"
,
"YY BC"
));
y
=
-((
year
/
10
)
*
10
);
date
=
ValueTimestamp
.
parse
(
y
+
"-"
+
month
+
"-01"
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1 BC"
,
"Y BC"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"1 BC"
,
"Y BC"
));
date
=
new
SimpleDateFormat
(
"hh:mm:ss"
).
parse
(
"08:12:00"
);
date
=
ValueTimestamp
.
parse
(
defDate
+
"08:12:00"
);
setMonth
(
date
,
month
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12 AM"
,
"HH:MI AM"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12 AM"
,
"HH:MI AM"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12 A.M."
,
"HH:MI A.M."
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12 A.M."
,
"HH:MI A.M."
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12"
,
"HH24:MI"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12"
,
"HH24:MI"
));
date
=
new
SimpleDateFormat
(
"hh:mm:ss"
).
parse
(
"08:12:00"
);
date
=
ValueTimestamp
.
parse
(
defDate
+
"08:12:00"
);
setMonth
(
date
,
month
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12"
,
"HH:MI"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12"
,
"HH:MI"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12"
,
"HH12:MI"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12"
,
"HH12:MI"
));
date
=
new
SimpleDateFormat
(
"hh:mm:ss"
).
parse
(
"08:12:34"
);
date
=
ValueTimestamp
.
parse
(
defDate
+
"08:12:34"
);
setMonth
(
date
,
month
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12:34"
,
"HH:MI:SS"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12:34"
,
"HH:MI:SS"
));
date
=
new
SimpleDateFormat
(
"ss"
).
parse
(
"34"
);
date
=
ValueTimestamp
.
parse
(
defDate
+
"12:00:00"
);
setMonth
(
date
,
month
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"12:00:00 PM"
,
"HH12:MI:SS AM"
));
date
=
ValueTimestamp
.
parse
(
defDate
+
"00:00:00"
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"12:00:00 AM"
,
"HH12:MI:SS AM"
));
date
=
ValueTimestamp
.
parse
(
defDate
+
"00:00:34"
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"34"
,
"SS"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"34"
,
"SS"
));
date
=
new
SimpleDateFormat
(
"yyyy hh:mm:ss"
).
parse
(
"1970 08:12:34"
);
date
=
ValueTimestamp
.
parse
(
defDate
+
"08:12:34"
);
setMonth
(
date
,
month
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"29554"
,
"SSSSS"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"29554"
,
"SSSSS"
));
date
=
new
SimpleDateFormat
(
"yyyy hh:mm:ss SSS"
).
parse
(
"1970 08:12:34 550"
);
date
=
ValueTimestamp
.
parse
(
defDate
+
"08:12:34.550"
);
setMonth
(
date
,
month
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12:34 550"
,
"HH:MI:SS FF"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12:34 550"
,
"HH:MI:SS FF"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12:34 55"
,
"HH:MI:SS FF2"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"08:12:34 55"
,
"HH:MI:SS FF2"
));
date
=
new
SimpleDateFormat
(
"hh:mm:ss"
).
parse
(
"14:04:00"
);
date
=
ValueTimestamp
.
parse
(
defDate
+
"14:04:00"
);
setMonth
(
date
,
month
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"02:04 P.M."
,
"HH:MI p.M."
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"02:04 P.M."
,
"HH:MI p.M."
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"02:04 PM"
,
"HH:MI PM"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"02:04 PM"
,
"HH:MI PM"
));
date
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
).
parse
(
"1970-12-12"
);
date
=
ValueTimestamp
.
parse
(
"1970-"
+
month
+
"-12"
);
// does not work in all timezones
assertEquals
(
date
,
ToDateParser
.
toDate
(
"12"
,
"DD"
));
// assertEquals(date, ToDateParser.toDate("12", "DD"));
date
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
).
parse
(
"1970-11-12"
);
date
=
ValueTimestamp
.
parse
(
year
+
(
calendar
.
isLeapYear
(
year
)
?
"11-11"
:
"-11-12"
)
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"316"
,
"DDD"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"316"
,
"DDD"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"316"
,
"DdD"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"316"
,
"DdD"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"316"
,
"dDD"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"316"
,
"dDD"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"316"
,
"ddd"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"316"
,
"ddd"
));
date
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
)
.
parse
(
"2013-01-29"
);
date
=
ValueTimestamp
.
parse
(
"2013-01-29"
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"
113029
"
,
"J"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"
2456322
"
,
"J"
));
if
(
Locale
.
getDefault
()
==
Locale
.
ENGLISH
)
{
if
(
Locale
.
getDefault
()
.
getLanguage
().
equals
(
"en"
)
)
{
date
=
new
SimpleDateFormat
(
"yyyy-MM-dd'T'HH:mm:ss"
).
parse
(
"9999-12-31T
23:59:59"
);
date
=
ValueTimestamp
.
parse
(
"9999-12-31
23:59:59"
);
assertEquals
(
date
,
ToDateParser
.
toDate
(
"31-DEC-9999 23:59:59"
,
"DD-MON-YYYY HH24:MI:SS"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"31-DEC-9999 23:59:59"
,
"DD-MON-YYYY HH24:MI:SS"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"31-DEC-9999 23:59:59"
,
"DD-MON-RRRR HH24:MI:SS"
));
assertEquals
(
date
,
ToDateParser
.
toDate
(
"31-DEC-9999 23:59:59"
,
"DD-MON-RRRR HH24:MI:SS"
));
SimpleDateFormat
ymd
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
);
assertEquals
(
ValueTimestamp
.
parse
(
"0001-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-0001"
,
"DD-MON-RRRR"
));
assertEquals
(
ymd
.
parse
(
"0001-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-0001"
,
"DD-MON-RRRR"
));
assertEquals
(
ValueTimestamp
.
parse
(
"9999-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-9999"
,
"DD-MON-RRRR"
));
assertEquals
(
ymd
.
parse
(
"9999-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-9999"
,
"DD-MON-RRRR"
));
assertEquals
(
ValueTimestamp
.
parse
(
"2000-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-000"
,
"DD-MON-RRRR"
));
assertEquals
(
ymd
.
parse
(
"2000-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-000"
,
"DD-MON-RRRR"
));
assertEquals
(
ValueTimestamp
.
parse
(
"1999-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-099"
,
"DD-MON-RRRR"
));
assertEquals
(
ymd
.
parse
(
"1999-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-099"
,
"DD-MON-RRRR"
));
assertEquals
(
ValueTimestamp
.
parse
(
"0100-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-100"
,
"DD-MON-RRRR"
));
assertEquals
(
ymd
.
parse
(
"0100-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-100"
,
"DD-MON-RRRR"
));
assertEquals
(
ValueTimestamp
.
parse
(
"2000-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-00"
,
"DD-MON-RRRR"
));
assertEquals
(
ymd
.
parse
(
"2000-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-00"
,
"DD-MON-RRRR"
));
assertEquals
(
ValueTimestamp
.
parse
(
"2049-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-49"
,
"DD-MON-RRRR"
));
assertEquals
(
ymd
.
parse
(
"2049-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-49"
,
"DD-MON-RRRR"
));
assertEquals
(
ValueTimestamp
.
parse
(
"1950-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-50"
,
"DD-MON-RRRR"
));
assertEquals
(
ymd
.
parse
(
"1950-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-50"
,
"DD-MON-RRRR"
));
assertEquals
(
ValueTimestamp
.
parse
(
"1999-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-99"
,
"DD-MON-RRRR"
));
assertEquals
(
ymd
.
parse
(
"1999-03-01"
),
ToDateParser
.
toDate
(
"1-MAR-99"
,
"DD-MON-RRRR"
));
}
}
}
private
static
void
setMonth
(
Date
date
,
int
month
)
{
assertEquals
(
ValueTimestampTimeZone
.
parse
(
"2000-05-10 10:11:12-08:15"
),
Calendar
c
=
DateTimeUtils
.
createGregorianCalendar
();
ToDateParser
.
toTimestampTz
(
"2000-05-10 10:11:12 -8:15"
,
"YYYY-MM-DD HH24:MI:SS TZH:TZM"
));
c
.
setTime
(
date
);
assertEquals
(
ValueTimestampTimeZone
.
parse
(
"2000-05-10 10:11:12-08:15"
),
c
.
set
(
Calendar
.
MONTH
,
month
);
ToDateParser
.
toTimestampTz
(
"2000-05-10 10:11:12 GMT-08:15"
,
"YYYY-MM-DD HH24:MI:SS TZR"
));
date
.
setTime
(
c
.
getTimeInMillis
());
assertEquals
(
ValueTimestampTimeZone
.
parse
(
"2000-02-10 10:11:12-08"
),
ToDateParser
.
toTimestampTz
(
"2000-02-10 10:11:12 US/Pacific"
,
"YYYY-MM-DD HH24:MI:SS TZR"
));
assertEquals
(
ValueTimestampTimeZone
.
parse
(
"2000-02-10 10:11:12-08"
),
ToDateParser
.
toTimestampTz
(
"2000-02-10 10:11:12 PST"
,
"YYYY-MM-DD HH24:MI:SS TZD"
));
}
}
private
void
testToCharFromDateTime
()
throws
SQLException
{
private
void
testToCharFromDateTime
()
throws
SQLException
{
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论