Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
geomultisens
gms-aux
Commits
0c0f4813
Commit
0c0f4813
authored
Mar 05, 2018
by
Daniel Eggert
Browse files
extended timestamp parser
parent
ddda876c
Changes
1
Hide whitespace changes
Inline
Side-by-side
gms-database/src/main/java/de/potsdam/gfz/gms/database/shared/Timestamp.java
View file @
0c0f4813
...
...
@@ -24,1163 +24,1167 @@ import java.util.Date;
/**
* @author Daniel Eggert (daniel.eggert@gfz-potsdam.de)
*
*/
public
class
Timestamp
implements
Comparable
<
Timestamp
>,
Serializable
{
private
static
final
long
serialVersionUID
=
4399474003723453591L
;
public
static
abstract
class
TimeUnits
{
public
static
final
int
UNDEFINED
=
-
1
;
public
static
final
int
SECONDS
=
0
;
public
static
final
int
MINUTES
=
1
;
public
static
final
int
HOURS
=
2
;
public
static
final
int
DAYS
=
3
;
public
static
final
int
WEEKS
=
4
;
public
static
final
int
MONTHS
=
5
;
public
static
final
int
YEARS
=
6
;
public
static
final
int
DECADES
=
7
;
public
static
final
int
NUM_UNITS
=
DECADES
+
1
;
public
static
final
int
MINUTE_IN_SECS
=
60
;
public
static
final
int
HOUR_IN_MINUTES
=
60
;
public
static
final
int
HOUR_IN_SECS
=
MINUTE_IN_SECS
*
HOUR_IN_MINUTES
;
public
static
final
int
DAY_IN_HOURS
=
24
;
public
static
final
int
DAY_IN_MINUTES
=
DAY_IN_HOURS
*
HOUR_IN_MINUTES
;
public
static
final
int
DAY_IN_SECS
=
DAY_IN_HOURS
*
HOUR_IN_SECS
;
public
static
final
int
WEEK_IN_DAYS
=
7
;
public
static
final
int
MONTH_IN_DAYS
=
30
;
public
static
final
int
YEAR_IN_DAYS
=
365
;
public
static
final
int
YEAR_IN_MONTHS
=
12
;
public
static
final
int
DECADES_IN_YEARS
=
10
;
public
static
String
getUnitName
(
int
unit
)
{
switch
(
unit
)
{
case
UNDEFINED:
return
"Undefined"
;
case
SECONDS:
return
"Seconds"
;
case
MINUTES:
return
"Minutes"
;
case
HOURS:
return
"Hours"
;
case
DAYS:
return
"Days"
;
case
WEEKS:
return
"Weeks"
;
case
MONTHS:
return
"Months"
;
case
YEARS:
return
"Years"
;
case
DECADES:
return
"Decades"
;
default
:
return
"N/A"
;
}
}
public
static
long
getUnitInsSeconds
(
int
unit
)
{
switch
(
unit
)
{
case
SECONDS:
return
1
;
case
MINUTES:
return
MINUTE_IN_SECS
;
case
HOURS:
return
HOUR_IN_SECS
;
case
DAYS:
return
DAY_IN_SECS
;
case
WEEKS:
return
WEEK_IN_DAYS
*
DAY_IN_SECS
;
case
MONTHS:
return
MONTH_IN_DAYS
*
DAY_IN_SECS
;
case
YEARS:
return
YEAR_IN_DAYS
*
DAY_IN_SECS
;
case
DECADES:
return
DECADES_IN_YEARS
*
YEAR_IN_DAYS
*
DAY_IN_SECS
;
}
return
0
;
}
/**
* Returns the center of the given TimeUnit within the next bigger TimeUnit,<br>
* e.g. getMidValue(TimeUnits.MONTHS) returns 6
*
* @param unit
* @return
*/
public
static
int
getMidValue
(
int
unit
)
{
switch
(
unit
)
{
case
SECONDS:
return
MINUTE_IN_SECS
/
2
;
case
MINUTES:
return
HOUR_IN_MINUTES
/
2
;
case
HOURS:
return
DAY_IN_HOURS
/
2
;
case
DAYS:
return
MONTH_IN_DAYS
/
2
;
case
WEEKS:
return
2
;
case
MONTHS:
return
YEAR_IN_MONTHS
/
2
;
default
:
return
0
;
}
}
}
/**
* Parses the given string an returns the corresponding timestamp.<br>
* The only supported formats (for now) are:<br>
* [time only] "HH:mm:ss"<br>
* [date only] "dd.MM.yyyy"<br>
* [full] "HH:mm:ss dd.MM.yyyy"<br>
* [iso8601] "yyyy.MM.ddTHH:mm:ssZ"
*
* @param timeString
* @return
*/
public
static
Timestamp
parse
(
String
dateTimeString
)
{
final
int
len
=
dateTimeString
.
length
();
if
(
len
<
5
)
{
// parse year only
return
parseYearOnly
(
dateTimeString
);
}
else
if
(
len
==
8
)
{
if
(
dateTimeString
.
contains
(
"|"
))
{
// parse date with month literal
return
parseDateWithMonthLiteral
(
dateTimeString
);
}
else
{
// parse time only
return
parseTime
(
dateTimeString
,
new
Timestamp
());
}
}
else
if
(
len
==
10
)
{
// parse date only
return
parseDate
(
dateTimeString
);
}
else
if
(
len
==
19
)
{
// parse full timestamp
return
parseTime
(
dateTimeString
.
substring
(
0
,
8
),
parseDate
(
dateTimeString
.
substring
(
9
)));
}
else
if
(
len
==
20
||
len
==
24
)
{
return
parseISO8601
(
dateTimeString
);
}
throw
new
IllegalArgumentException
(
"invalid text string given: "
+
dateTimeString
);
}
/**
* @param dateTimeString
* @return
*/
private
static
Timestamp
parseISO8601
(
String
dateTimeString
)
{
Timestamp
t
=
new
Timestamp
();
// parse and set year
t
.
setYear
(
Integer
.
parseInt
(
dateTimeString
.
substring
(
0
,
4
)));
// parse and set month
t
.
setMonth
(
Integer
.
parseInt
(
dateTimeString
.
substring
(
5
,
7
)));
// parse and set day
t
.
setDay
(
Integer
.
parseInt
(
dateTimeString
.
substring
(
8
,
10
)));
// parse and set hour
t
.
setHour
(
Integer
.
parseInt
(
dateTimeString
.
substring
(
11
,
13
)));
// parse and set minute
t
.
setMinute
(
Integer
.
parseInt
(
dateTimeString
.
substring
(
14
,
16
)));
// parse and set second
t
.
setSecond
(
Integer
.
parseInt
(
dateTimeString
.
substring
(
17
,
19
)));
return
t
;
}
private
static
Timestamp
parseYearOnly
(
String
dateString
)
{
Timestamp
t
=
new
Timestamp
();
t
.
setYear
(
Integer
.
parseInt
(
dateString
));
return
t
;
}
/**
* @param dateTimeString
* @return
*/
private
static
Timestamp
parseDateWithMonthLiteral
(
String
dateTimeString
)
{
String
[]
split
=
dateTimeString
.
split
(
"\\|"
);
return
new
Timestamp
(
Integer
.
parseInt
(
split
[
1
]),
getMonthFromLiteral
(
split
[
0
]),
1
);
}
private
static
Timestamp
parseDate
(
String
dateString
)
{
String
[]
split
=
dateString
.
split
(
"\\D"
);
if
(
dateString
.
contains
(
"."
))
{
// day will be first and year will be last
String
day
=
split
[
0
];
split
[
0
]
=
split
[
2
];
split
[
2
]
=
day
;
}
return
new
Timestamp
(
Integer
.
parseInt
(
split
[
0
]),
Integer
.
parseInt
(
split
[
1
]),
Integer
.
parseInt
(
split
[
2
]));
}
private
static
Timestamp
parseTime
(
String
timeString
,
Timestamp
timestamp
)
{
String
[]
split
=
timeString
.
split
(
":"
);
timestamp
.
setHour
(
Integer
.
parseInt
(
split
[
0
]));
timestamp
.
setMinute
(
Integer
.
parseInt
(
split
[
1
]));
timestamp
.
setSecond
(
Integer
.
parseInt
(
split
[
2
]));
return
timestamp
;
}
public
static
final
int
JAN
=
1
;
public
static
final
int
FEB
=
2
;
public
static
final
int
MAR
=
3
;
public
static
final
int
APR
=
4
;
public
static
final
int
MAY
=
5
;
public
static
final
int
JUN
=
6
;
public
static
final
int
JUL
=
7
;
public
static
final
int
AUG
=
8
;
public
static
final
int
SEP
=
9
;
public
static
final
int
OCT
=
10
;
public
static
final
int
NOV
=
11
;
public
static
final
int
DEC
=
12
;
public
static
final
Timestamp
NULL
=
new
Timestamp
();
public
static
final
Timestamp
MIN
=
new
Timestamp
(
1
,
1
,
1
);
public
static
final
Timestamp
MAX
=
new
Timestamp
(
Short
.
MAX_VALUE
/
2
,
12
,
31
);
private
int
date
=
0
;
private
int
time
=
0
;
/**
*
*/
public
Timestamp
(
int
year
,
int
month
,
int
day
,
int
hour
,
int
minute
,
int
second
)
{
setYear
(
year
);
setMonth
(
month
);
setDay
(
day
);
setHour
(
hour
);
setMinute
(
minute
);
setSecond
(
second
);
}
public
int
getTime
()
{
return
time
;
}
public
int
getDate
()
{
return
date
;
}
public
Timestamp
(
int
...
fields
)
{
int
year
=
0
;
int
month
=
0
,
day
=
0
,
hour
=
0
,
minute
=
0
,
second
=
0
;
switch
(
fields
.
length
)
{
case
6
:
second
=
fields
[
5
];
case
5
:
minute
=
fields
[
4
];
case
4
:
hour
=
fields
[
3
];
case
3
:
day
=
fields
[
2
];
case
2
:
month
=
fields
[
1
];
case
1
:
year
=
fields
[
0
];
break
;
}
set
(
year
,
month
,
day
,
hour
,
minute
,
second
);
}
public
Timestamp
()
{
}
/**
* Don't use with {@link java.util.Date#getTime()}
*
* @param dateTime
* @see {@link Timestamp#setFromDateTimeLong(long)}, {@link Timestamp#getDateTimeAsLong()}
*/
public
Timestamp
(
long
dateTime
)
{
setFromDateTimeLong
(
dateTime
);
}
public
Timestamp
(
Timestamp
toCopy
)
{
if
(
toCopy
==
null
)
{
return
;
}
this
.
date
=
toCopy
.
date
;
this
.
time
=
toCopy
.
time
;
}
@Override
public
int
hashCode
()
{
return
(
31
+
date
)
*
31
+
time
;
}
public
boolean
hasValidDate
()
{
return
date
!=
0
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
obj
==
null
||
!(
obj
instanceof
Timestamp
))
{
return
false
;
}
if
(
obj
instanceof
Timestamp
)
{
Timestamp
ft
=
(
Timestamp
)
obj
;
return
this
.
date
==
ft
.
date
&&
this
.
time
==
ft
.
time
;
}
else
{
return
false
;
}
// return this.compareTo((Timestamp) obj) == 0;
}
public
void
setYear
(
int
year
)
{
date
=
((
year
<<
16
)
&
(
0xffff0000
))
|
(
date
&
(
0xffff
));
}
public
int
getYear
()
{
return
date
>>
16
;
}
public
void
setMonth
(
int
month
)
{
date
=
((
month
<<
8
)
&
0xff00
)
|
(
date
&
(
0xffff00ff
));
}
public
int
getMonth
()
{
return
(
date
>>
8
)
&
(
0xff
);
}
public
void
setDay
(
int
day
)
{
date
=
(
day
&
0xff
)
|
(
date
&
(
0xffffff00
));
}
public
int
getDay
()
{
return
date
&
(
0xff
);
}
public
void
setHour
(
int
hour
)
{
time
=
(
hour
<<
24
)
|
(
time
&
(
0x00ffffff
));
}
public
int
getHour
()
{
return
time
>>
24
;
}
public
void
setMinute
(
int
minute
)
{
time
=
((
minute
<<
16
)
&
0xff0000
)
|
(
time
&
(
0xff00ffff
));
}
public
int
getMinute
()
{
return
(
time
>>
16
)
&
(
0xff
);
}
public
void
setSecond
(
int
second
)
{
time
=
((
second
<<
8
)
&
0xff00
)
|
(
time
&
(
0xffff00ff
));
}
public
int
getSecond
()
{
return
(
time
>>
8
)
&
(
0xff
);
}
public
int
getDecade
()
{
return
(
getYear
()
/
10
)
*
10
;
}
public
Timestamp
truncate
(
int
unit
)
{
if
(
unit
==
TimeUnits
.
DECADES
)
{
Timestamp
dec
=
new
Timestamp
();
dec
.
setYear
(
getDecade
());
return
dec
;
}
int
year
=
getYear
();
int
month
=
0
;
int
day
=
0
;
int
hour
=
0
;
int
minute
=
0
;
int
second
=
0
;
if
(
unit
<
TimeUnits
.
YEARS
)
{
month
=
getMonth
();
}
if
(
unit
<
TimeUnits
.
MONTHS
)
{
day
=
getDay
();
if
(
unit
==
TimeUnits
.
WEEKS
)
{
// truncate week - bind to Mondays
int
weekDay
=
weekDay
(
year
,
month
,
day
);
day
-=
weekDay
;
// handle underflow
if
(
day
<
1
)
{
// we moved to the previous month
if
(--
month
<
1
)
{
// we moved to the previous year
--
year
;
month
=
12
;
}
day
+=
getNumDaysInMonth
(
year
,
month
);
}
}
}
if
(
unit
<
TimeUnits
.
DAYS
)
{
hour
=
getHour
();
}
if
(
unit
<
TimeUnits
.
HOURS
)
{
minute
=
getMinute
();
}
if
(
unit
<
TimeUnits
.
MINUTES
)
{
second
=
getSecond
();
}
return
new
Timestamp
(
year
,
month
,
day
,
hour
,
minute
,
second
);
}
/**
* Returns a new timestamp instance plus amount units from this date apart.
*
* @param amount
* @param unit
* @return
*/
public
Timestamp
plus
(
int
amount
,
int
unit
)
{
Timestamp
ts
=
null
;
int
year
=
0
;
int
month
=
0
;
int
day
=
0
;
switch
(
unit
)
{
case
TimeUnits
.
SECONDS
:
// create jd with time
double
jdWithTime
=
getJulianDayWithTime
();
// now add the seconds as day fraction
double
secsInDays
=
amount
;
secsInDays
/=
TimeUnits
.
DAY_IN_SECS
;
jdWithTime
+=
secsInDays
;
return
new
Timestamp
().
setFromJulianDayWithTime
(
jdWithTime
);
case
TimeUnits
.
MINUTES
:
// make seconds from minutes
amount
*=
TimeUnits
.
MINUTE_IN_SECS
;
return
plus
(
amount
,
TimeUnits
.
SECONDS
);
case
TimeUnits
.
HOURS
:
// make seconds from hours
amount
*=
TimeUnits
.
HOUR_IN_SECS
;
return
plus
(
amount
,
TimeUnits
.
SECONDS
);
case
TimeUnits
.
DAYS
:
int
jd
=
getJulianDay
();
ts
=
fromJulianDay
(
jd
+
amount
);
// copy time
ts
.
time
=
this
.
time
;
return
ts
;
case
TimeUnits
.
WEEKS
:
// make days from week
amount
*=
TimeUnits
.
WEEK_IN_DAYS
;
return
plus
(
amount
,
TimeUnits
.
DAYS
);
case
TimeUnits
.
MONTHS
:
year
=
getYear
();
month
=
getMonth
();
day
=
getDay
();
if
(
amount
>
12
)
{
year
+=
amount
/
12
;
amount
=
amount
%
12
;
}
month
+=
amount
;
// handle overflow
if
(
month
>
12
)
{
++
year
;
month
-=
12
;
}
// handle num days per month
if
(
day
>
28
)
{
day
=
Math
.
min
(
day
,
getNumDaysInMonth
(
year
,
month
));
}
ts
=
new
Timestamp
(
year
,
month
,
day
);
ts
.
time
=
this
.
time
;
return
ts
;
case
TimeUnits
.
YEARS
:
year
=
getYear
()
+
amount
;
month
=
getMonth
();
day
=
getDay
();
// handle leap years
if
(
month
==
FEB
&&
day
==
29
)
{
day
=
Math
.
min
(
day
,
getNumDaysInMonth
(
year
,
month
));
}
ts
=
new
Timestamp
(
year
,
month
,
day
);
ts
.
time
=
this
.
time
;
return
ts
;
case
TimeUnits
.
DECADES
:
// make decades years
amount
*=
TimeUnits
.
DECADES_IN_YEARS
;
return
plus
(
amount
,
TimeUnits
.
YEARS
);
}
return
ts
;
}
/**
* Set this timestamp to the same values as the other
*
* @param other
*/
public
void
set
(
Timestamp
other
)
{
this
.
date
=
other
.
date
;
this
.
time
=
other
.
time
;
}
public
double
getJulianDayWithTime
()
{
return
appendTimeToJulianDay
(
julianDay
(
getYear
(),
getMonth
(),
getDay
()),
getHour
(),
getMinute
(),
getSecond
());
}
public
int
getJulianDay
()
{
return
julianDay
(
getYear
(),
getMonth
(),
getDay
());
}
public
Timestamp
setFromJulianDayWithTime
(
double
jdWithTime
)
{
int
jd
=
(
int
)
jdWithTime
;
setFromJulianDay
(
jd
);
// remove date part which leaves the time fraction
setTimeFromDayFraction
(
jdWithTime
-
jd
);
return
this
;
}
public
void
set
(
int
year
,
int
month
,
int
day
,
int
hour
,
int
minute
,
int
second
)
{
setYear
(
year
);
setMonth
(
month
);
setDay
(
day
);
setHour
(
hour
);
setMinute
(
minute
);
setSecond
(
second
);
}
public
int
getCalendarWeek
()
{
return
calendarWeek
(
getYear
(),
getMonth
(),
getDay
());
}
public
static
Timestamp
now
()
{
return
fromDate
(
new
Date
());
}
/**
* Calendar week 1..54
*
* @return
*/
public
static
int
calendarWeek
(
int
year
,
int
month
,
int
day
)
{
// what weekday is the first day of the year
int
firstWeekDay
=
weekDay
(
year
,
JAN
,
1
);
int
dayOfYear
=
dayOfYear
(
year
,
month
,
day
);
return
1
+
(
dayOfYear
+
firstWeekDay
-
1
)
/
7
;
}
public
int
getDayOfYear
()
{
return
dayOfYear
(
getYear
(),
getMonth
(),
getDay
());
}