Skip to content

Commit cac5b94

Browse files
mbuechnercboehme
authored andcommitted
Added new attributes era and removeLeadingZeros to DateFormat
1 parent 7cd72ad commit cac5b94

File tree

2 files changed

+96
-21
lines changed

2 files changed

+96
-21
lines changed

src/main/java/org/culturegraph/mf/morph/functions/DateFormat.java

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
*/
1616
package org.culturegraph.mf.morph.functions;
1717

18-
import java.text.ParseException;
1918
import java.text.SimpleDateFormat;
19+
import java.util.Calendar;
2020
import java.util.Collections;
21-
import java.util.Date;
21+
import java.util.GregorianCalendar;
2222
import java.util.HashSet;
2323
import java.util.Locale;
2424
import java.util.Set;
@@ -27,13 +27,25 @@
2727

2828
/**
2929
* Format date/time strings in Metamorph. By default the input format is
30-
* dd.MM.yyyy and the output format is dd. MMMM yyyy.
31-
*
30+
* dd.MM.yyyy and the output format is {@link java.text.DateFormat.Field#LONG}.
31+
* <br/>
32+
* The Attribute removeLeadingZeros will remove all leading zeros from all
33+
* numbers in the output date.
34+
* <br/>
35+
* The attribute era is used to specify if the date is BC or AD. Default
36+
* value is AUTO. To understand that, three short examples:
37+
* <ul><li>Input: 20.07.356 (era=BC)</li>
38+
* <li>Output (German location): 20. Juli 0356 v. Chr.</li>
39+
* <ul><li>Input: 20.07.356 (era=AD,removeLeadingZeros=true)</li>
40+
* <li>Output (German location): 20. Juli 356</li>
41+
* <li>Input: 20.07.-356 (era=AUTO)</li>
42+
* <li>Output (German location): 20. Juli 0357 v. Chr. (there is NO year 0;
43+
* see ISO 8601, Proleptic Gregorian Calendar)</li></ul>
44+
* <p/>
3245
* Examples of using this function in Metamorph:
33-
* <ul>
34-
* <li>Default date format: <code>&lt;dateformat /&gt;</code></li>
35-
* <li>Read ISO-dates and generate German style dates:
36-
* <code>&lt;dateformat inputformat="yyyy-MM-dd" outputformat="dd.MM.yyyy" /&gt;</code></li>
46+
* <ul><li>Default date format: <code>&lt;dateformat /&gt;</code></li>
47+
* <li>Read ISO-dates and generate German style dates:
48+
* <code>&lt;dateformat inputformat="yyyy-MM-dd" outputformat="dd.MM.yyyy" /&gt;</code></li>
3749
* </ul>
3850
*
3951
* @author Michael Büchner
@@ -42,11 +54,15 @@ public class DateFormat extends AbstractSimpleStatelessFunction {
4254

4355
public static final String DEFAULT_INPUT_FORMAT = "dd.MM.yyyy";
4456
public static final DateFormats DEFAULT_OUTPUT_FORMAT = DateFormats.LONG;
57+
public static final boolean DEFAULT_REMOVE_LEADING_ZEROS = false;
58+
public static final Era DEFAULT_ERA = Era.AUTO;
4559

4660
private static final Set<String> SUPPORTED_LANGUAGES;
4761

4862
private String inputFormat = DEFAULT_INPUT_FORMAT;
4963
private DateFormats outputFormat = DEFAULT_OUTPUT_FORMAT;
64+
private Era era = DEFAULT_ERA;
65+
private boolean removeLeadingZeros = DEFAULT_REMOVE_LEADING_ZEROS;
5066
private Locale outputLocale = Locale.getDefault();
5167

5268
/**
@@ -73,6 +89,29 @@ int getFormatId() {
7389

7490
}
7591

92+
/**
93+
* Supported eras (basically AUTO, AD and BC). Maps to
94+
* {@link java.util.GregorianCalendar}.
95+
*
96+
* @author Michael Büchner
97+
*/
98+
public enum Era {
99+
AD(GregorianCalendar.AD),
100+
BC(GregorianCalendar.BC),
101+
AUTO(-1);
102+
103+
private final int eraId;
104+
105+
Era(final int eraId) {
106+
this.eraId = eraId;
107+
}
108+
109+
int getEraId() {
110+
return eraId;
111+
}
112+
113+
}
114+
76115
static {
77116
final Set<String> set = new HashSet<String>();
78117
Collections.addAll(set, Locale.getISOLanguages());
@@ -81,15 +120,34 @@ int getFormatId() {
81120

82121
@Override
83122
public final String process(final String value) {
84-
String result = value;
123+
String result;
85124
try {
86-
final java.text.DateFormat inputDateFormat = new SimpleDateFormat(inputFormat);
87-
final Date date = inputDateFormat.parse(value);
88-
result = java.text.DateFormat.getDateInstance(outputFormat.getFormatId(), outputLocale).format(date);
125+
final Calendar c = Calendar.getInstance();
126+
final SimpleDateFormat sdf = new SimpleDateFormat(inputFormat);
127+
c.setTime(sdf.parse(value));
128+
if (era == Era.BC) {
129+
c.set(Calendar.ERA, GregorianCalendar.BC);
130+
} else if (era == Era.AD) {
131+
c.set(Calendar.ERA, GregorianCalendar.AD);
132+
}
133+
134+
final SimpleDateFormat sdfp = (SimpleDateFormat) java.text.DateFormat.getDateInstance(outputFormat.getFormatId(), outputLocale);
135+
String p = sdfp.toPattern();
136+
if (c.get(Calendar.ERA) == GregorianCalendar.BC) {
137+
p = p.replace("yyyy", "yyyy G");
138+
}
139+
140+
final SimpleDateFormat sdfo = new SimpleDateFormat(p, outputLocale);
141+
result = sdfo.format(c.getTime());
142+
143+
if (removeLeadingZeros) {
144+
result = result.replaceAll("([0]{1,})([0-9]{1,})", "$2");
145+
}
146+
89147
} catch (final IllegalArgumentException e) {
90148
throw new MorphDefException("The date/time format is not supported.", e);
91-
} catch (final ParseException e) {
92-
// Nothing to do
149+
} catch (final Exception e) {
150+
result = value;
93151
}
94152
return result;
95153
}
@@ -102,11 +160,18 @@ public final void setOutputFormat(final DateFormats outputFormat) {
102160
this.outputFormat = outputFormat;
103161
}
104162

163+
public final void setEra(final Era era) {
164+
this.era = era;
165+
}
166+
167+
public final void setRemoveLeadingZeros(final boolean removeLeadingZeros) {
168+
this.removeLeadingZeros = removeLeadingZeros;
169+
}
170+
105171
public final void setLanguage(final String language) {
106172
if (!SUPPORTED_LANGUAGES.contains(language)) {
107173
throw new MorphDefException("Language '" + language + "' not supported.");
108174
}
109175
this.outputLocale = new Locale(language);
110176
}
111-
112-
}
177+
}

src/main/resources/schemata/metamorph.xsd

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -909,8 +909,8 @@
909909
</annotation>
910910
<simpleType>
911911
<restriction base="string">
912-
<enumeration value="record"></enumeration>
913-
<enumeration value="entity"></enumeration>
912+
<enumeration value="record" />
913+
<enumeration value="entity" />
914914
</restriction>
915915
</simpleType>
916916
</attribute>
@@ -921,9 +921,9 @@
921921
</annotation>
922922
<simpleType>
923923
<restriction base="string">
924-
<enumeration value="name"></enumeration>
925-
<enumeration value="value"></enumeration>
926-
<enumeration value="name-value"></enumeration>
924+
<enumeration value="name" />
925+
<enumeration value="value" />
926+
<enumeration value="name-value" />
927927
</restriction>
928928
</simpleType>
929929
</attribute>
@@ -995,6 +995,16 @@
995995
</restriction>
996996
</simpleType>
997997
</attribute>
998+
<attribute name="era" use="optional" default="AUTO">
999+
<simpleType>
1000+
<restriction base="string">
1001+
<enumeration value="AUTO" />
1002+
<enumeration value="AD" />
1003+
<enumeration value="BC" />
1004+
</restriction>
1005+
</simpleType>
1006+
</attribute>
1007+
<attribute name="removeLeadingZeros" type="boolean" use="optional" default="false" />
9981008
<attribute name="language" type="string" use="optional" />
9991009
</complexType>
10001010
</element>

0 commit comments

Comments
 (0)