mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
Merge pull request #82 from dscho/dates
Implement date parsing / formatting
This commit is contained in:
commit
e485a468f0
24
classpath/java/text/ParseException.java
Normal file
24
classpath/java/text/ParseException.java
Normal file
@ -0,0 +1,24 @@
|
||||
/* Copyright (c) 2008-2013, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.text;
|
||||
|
||||
public class ParseException extends Exception {
|
||||
private int errorOffset;
|
||||
|
||||
public ParseException(String message, int errorOffset) {
|
||||
super(message);
|
||||
this.errorOffset = errorOffset;
|
||||
}
|
||||
|
||||
public int getErrorOffset() {
|
||||
return errorOffset;
|
||||
}
|
||||
}
|
39
classpath/java/text/ParsePosition.java
Normal file
39
classpath/java/text/ParsePosition.java
Normal file
@ -0,0 +1,39 @@
|
||||
/* Copyright (c) 2008-2013, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.text;
|
||||
|
||||
public class ParsePosition {
|
||||
private int index, errorIndex = -1;
|
||||
|
||||
public ParsePosition(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public int getErrorIndex() {
|
||||
return errorIndex;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setErrorIndex(int i) {
|
||||
errorIndex = i;
|
||||
}
|
||||
|
||||
public void setIndex(int i) {
|
||||
index = i;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "index: " + index + "(error index: " + errorIndex + ")";
|
||||
}
|
||||
}
|
98
classpath/java/text/SimpleDateFormat.java
Normal file
98
classpath/java/text/SimpleDateFormat.java
Normal file
@ -0,0 +1,98 @@
|
||||
/* Copyright (c) 2008-2013, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.text;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
public class SimpleDateFormat {
|
||||
private String pattern;
|
||||
|
||||
public SimpleDateFormat(String pattern) {
|
||||
this.pattern = pattern;
|
||||
if (! "yyyy-MM-dd'T'HH:mm:ss".equals(pattern)) {
|
||||
throw new UnsupportedOperationException("Unsupported pattern: " + pattern);
|
||||
}
|
||||
}
|
||||
|
||||
public StringBuffer format(Date date, StringBuffer buffer, FieldPosition position) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
pad(buffer, calendar.get(Calendar.YEAR), 4);
|
||||
buffer.append('-');
|
||||
pad(buffer, calendar.get(Calendar.MONTH) + 1, 2);
|
||||
buffer.append('-');
|
||||
pad(buffer, calendar.get(Calendar.DAY_OF_MONTH), 2);
|
||||
buffer.append("T");
|
||||
pad(buffer, calendar.get(Calendar.HOUR_OF_DAY), 2);
|
||||
buffer.append(':');
|
||||
pad(buffer, calendar.get(Calendar.MINUTE), 2);
|
||||
buffer.append(':');
|
||||
pad(buffer, calendar.get(Calendar.SECOND), 2);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public Date parse(String text) {
|
||||
return parse(text, new ParsePosition(0));
|
||||
}
|
||||
|
||||
public Date parse(String text, ParsePosition position) {
|
||||
int index = position.getIndex();
|
||||
try {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
index = parseField(text, index, 4, calendar, Calendar.YEAR, 0);
|
||||
index = expectPrefix(text, index, "-");
|
||||
index = parseField(text, index, 2, calendar, Calendar.MONTH, -1);
|
||||
index = expectPrefix(text, index, "-");
|
||||
index = parseField(text, index, 2, calendar, Calendar.DAY_OF_MONTH, 0);
|
||||
index = expectPrefix(text, index, "T");
|
||||
index = parseField(text, index, 2, calendar, Calendar.HOUR_OF_DAY, 0);
|
||||
index = expectPrefix(text, index, ":");
|
||||
index = parseField(text, index, 2, calendar, Calendar.MINUTE, 0);
|
||||
index = expectPrefix(text, index, ":");
|
||||
index = parseField(text, index, 2, calendar, Calendar.SECOND, 0);
|
||||
position.setIndex(index);
|
||||
return calendar.getTime();
|
||||
} catch (ParseException e) {
|
||||
position.setErrorIndex(index);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void pad(StringBuffer buffer, int value, int digits) {
|
||||
int i = value == 0 ? 1 : value;
|
||||
while (i > 0) {
|
||||
i /= 10;
|
||||
--digits;
|
||||
}
|
||||
while (digits-- > 0) {
|
||||
buffer.append('0');
|
||||
}
|
||||
buffer.append(value);
|
||||
}
|
||||
|
||||
private static int parseField(String text, int offset, int length, Calendar calendar, int field, int adjustment) throws ParseException {
|
||||
if (text.length() < offset + length) throw new ParseException("Short date: " + text, offset);
|
||||
try {
|
||||
int value = Integer.parseInt(text.substring(offset, offset + length), 10);
|
||||
calendar.set(field, value + adjustment);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ParseException("Not a number: " + text, offset);
|
||||
}
|
||||
return offset + length;
|
||||
}
|
||||
|
||||
private static int expectPrefix(String text, int offset, String prefix) throws ParseException {
|
||||
if (text.length() <= offset) throw new ParseException("Short date: " + text, offset);
|
||||
if (! text.substring(offset).startsWith(prefix)) throw new ParseException("Parse error: " + text, offset);
|
||||
return offset + prefix.length();
|
||||
}
|
||||
}
|
@ -55,6 +55,10 @@ public abstract class Calendar {
|
||||
time = date.getTime();
|
||||
}
|
||||
|
||||
public Date getTime() {
|
||||
return new Date(time);
|
||||
}
|
||||
|
||||
public abstract void roll(int field, boolean up);
|
||||
public abstract void add(int field, int amount);
|
||||
|
||||
@ -102,6 +106,23 @@ public abstract class Calendar {
|
||||
parseIntoFields(this.time);
|
||||
}
|
||||
|
||||
public Date getTime() {
|
||||
long days = fields[DAY_OF_MONTH] - 1;
|
||||
long years = fields[YEAR] - EPOCH_LEAP_YEAR;
|
||||
days += years * 365 + years / 4 + 1 - DAYS_TO_EPOCH;
|
||||
for (int month = 0; month < fields[MONTH]; month++) {
|
||||
days += DAYS_IN_MONTH[0][month];
|
||||
}
|
||||
if (fields[MONTH] < 2 && isLeapYear(fields[YEAR])) {
|
||||
days--;
|
||||
}
|
||||
long time = MILLIS_PER_DAY * days
|
||||
+ MILLIS_PER_HOUR * fields[HOUR_OF_DAY]
|
||||
+ MILLIS_PER_MINUTE * fields[MINUTE]
|
||||
+ MILLIS_PER_SECOND * fields[SECOND];
|
||||
return new Date(time);
|
||||
}
|
||||
|
||||
private static boolean isLeapYear(int year) {
|
||||
return (year%4 == 0) && (year%100 != 0) || (year%400 == 0);
|
||||
}
|
||||
|
25
test/Dates.java
Normal file
25
test/Dates.java
Normal file
@ -0,0 +1,25 @@
|
||||
import java.text.FieldPosition;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class Dates {
|
||||
private final static long EPOCH = 1234567890;
|
||||
private final static String TEXT = "2009-02-13T23:31:30";
|
||||
|
||||
private static void expect(boolean v) {
|
||||
if (! v) throw new RuntimeException();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||||
Date date = format.parse("1970-01-01T00:00:00");
|
||||
expect(0 == date.getTime());
|
||||
|
||||
date = new Date(EPOCH * 1000l);
|
||||
String actual = format.format(date, new StringBuffer(), new FieldPosition(0)).toString();
|
||||
expect(TEXT.equals(actual));
|
||||
|
||||
date = format.parse(TEXT);
|
||||
expect(EPOCH == date.getTime() / 1000l);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user