Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
778748d1
提交
778748d1
authored
2月 15, 2018
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Reimplement TO_DATE without a Calendar and fix a lot of bugs an incompatibilities
上级
aac17564
显示空白字符变更
内嵌
并排
正在显示
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
;
...
...
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
][];
...
...
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
get
DateParser
(
String
input
,
String
format
)
{
private
static
ToDateParser
get
TimestampParser
(
ConfigParam
param
,
String
input
,
String
format
)
{
ToDateParser
result
=
new
ToDateParser
(
ConfigParam
.
TO_DATE
,
input
,
format
);
ToDateParser
result
=
new
ToDateParser
(
param
,
input
,
format
);
parse
(
result
);
parse
(
result
);
return
result
;
return
result
;
}
}
private
static
ToDateParser
getTimestampParser
(
String
input
,
String
format
)
{
private
ValueTimestamp
getResultingValue
()
{
ToDateParser
result
=
new
ToDateParser
(
ConfigParam
.
TO_TIMESTAMP
,
input
,
format
);
long
dateValue
;
parse
(
result
);
if
(
absoluteDayValid
)
{
return
result
;
dateValue
=
DateTimeUtils
.
dateValueFromAbsoluteDay
(
absoluteDay
);
}
else
{
int
year
=
this
.
year
;
if
(
year
==
0
)
{
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
);
}
}
}
private
Timestamp
getResultingTimestamp
()
{
int
hour
;
Calendar
cal
=
(
Calendar
)
getResultCalendar
().
clone
();
if
(
hour12Valid
)
{
int
nanosToSet
=
nanos
==
null
?
hour
=
hour12
%
12
;
cal
.
get
(
Calendar
.
MILLISECOND
)
*
1000000
:
nanos
.
intValue
();
if
(!
isAM
)
{
cal
.
set
(
Calendar
.
MILLISECOND
,
0
);
hour
+=
12
;
Timestamp
ts
=
new
Timestamp
(
cal
.
getTimeInMillis
());
}
ts
.
setNanos
(
nanosToSet
);
}
else
{
return
ts
;
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
)
{
...
...
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
;
}
}
...
...
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"
));
}
}
}
assertEquals
(
ValueTimestampTimeZone
.
parse
(
"2000-05-10 10:11:12-08:15"
),
ToDateParser
.
toTimestampTz
(
"2000-05-10 10:11:12 -8:15"
,
"YYYY-MM-DD HH24:MI:SS TZH:TZM"
));
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 GMT-08:15"
,
"YYYY-MM-DD HH24:MI:SS TZR"
));
c
.
setTime
(
date
);
assertEquals
(
ValueTimestampTimeZone
.
parse
(
"2000-02-10 10:11:12-08"
),
c
.
set
(
Calendar
.
MONTH
,
month
);
ToDateParser
.
toTimestampTz
(
"2000-02-10 10:11:12 US/Pacific"
,
"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 PST"
,
"YYYY-MM-DD HH24:MI:SS TZD"
));
}
}
private
void
testToCharFromDateTime
()
throws
SQLException
{
private
void
testToCharFromDateTime
()
throws
SQLException
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论