Skip to content

Commit 6b9b7e1

Browse files
committed
Adds a dateformat function to Metamorph for converting various date formats.
(cherry picked from commit 0b882fe) (cherry picked from commit 37f4a54) Conflicts: src/main/java/org/culturegraph/mf/morph/functions/DateFormat.java
1 parent 82be110 commit 6b9b7e1

File tree

5 files changed

+174
-2
lines changed

5 files changed

+174
-2
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Copyright 2014 Deutsche Nationalbibliothek
3+
*
4+
* Licensed under the Apache License, Version 2.0 the "License";
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.culturegraph.mf.morph.functions;
17+
18+
import java.text.ParseException;
19+
import java.text.SimpleDateFormat;
20+
import java.util.Collections;
21+
import java.util.Date;
22+
import java.util.HashSet;
23+
import java.util.Locale;
24+
import java.util.Set;
25+
26+
import org.culturegraph.mf.exceptions.MorphDefException;
27+
28+
/**
29+
* 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+
*
32+
* 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>
37+
* </ul>
38+
*
39+
* @author Michael Büchner
40+
*/
41+
public class DateFormat extends AbstractSimpleStatelessFunction {
42+
43+
public static final String DEFAULT_INPUT_FORMAT = "dd.MM.yyyy";
44+
public static final DateFormats DEFAULT_OUTPUT_FORMAT = DateFormats.LONG;
45+
46+
private static final Set<String> SUPPORTED_LANGUAGES;
47+
48+
private String inputFormat = DEFAULT_INPUT_FORMAT;
49+
private DateFormats outputFormat = DEFAULT_OUTPUT_FORMAT;
50+
private Locale outputLocale = Locale.getDefault();
51+
52+
/**
53+
* Supported date formats. Maps to the date formats in
54+
* {@link java.text.DateFormat}.
55+
*
56+
* @author Christoph Böhme
57+
*/
58+
public enum DateFormats {
59+
FULL(java.text.DateFormat.FULL),
60+
LONG(java.text.DateFormat.LONG),
61+
MEDIUM(java.text.DateFormat.MEDIUM),
62+
SHORT(java.text.DateFormat.SHORT);
63+
64+
private final int formatId;
65+
66+
DateFormats(final int formatId) {
67+
this.formatId = formatId;
68+
}
69+
70+
int getFormatId() {
71+
return formatId;
72+
}
73+
74+
}
75+
76+
static {
77+
final Set<String> set = new HashSet<String>();
78+
Collections.addAll(set, Locale.getISOLanguages());
79+
SUPPORTED_LANGUAGES = Collections.unmodifiableSet(set);
80+
}
81+
82+
@Override
83+
public final String process(final String value) {
84+
String result = value;
85+
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);
89+
} catch (final IllegalArgumentException e) {
90+
throw new MorphDefException("The date/time format is not supported.", e);
91+
} catch (final ParseException e) {
92+
// Nothing to do
93+
}
94+
return result;
95+
}
96+
97+
public final void setInputFormat(final String inputFormat) {
98+
this.inputFormat = inputFormat;
99+
}
100+
101+
public final void setOutputFormat(final DateFormats outputFormat) {
102+
this.outputFormat = outputFormat;
103+
}
104+
105+
public final void setLanguage(final String language) {
106+
if (!SUPPORTED_LANGUAGES.contains(language)) {
107+
throw new MorphDefException("Language '" + language + "' not supported.");
108+
}
109+
this.outputLocale = new Locale(language);
110+
}
111+
112+
}

src/main/resources/morph-functions.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ switch-name-value org.culturegraph.mf.morph.functions.SwitchNameValue
2222
unique org.culturegraph.mf.morph.functions.Unique
2323
script org.culturegraph.mf.morph.functions.Script
2424
setreplace org.culturegraph.mf.morph.functions.SetReplace
25-
timestamp org.culturegraph.mf.morph.functions.Timestamp
25+
timestamp org.culturegraph.mf.morph.functions.Timestamp
26+
dateformat org.culturegraph.mf.morph.functions.DateFormat

src/main/resources/schemata/metamorph.xsd

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,7 @@
660660
<element ref="tns:not-equals" />
661661
<element ref="tns:case" />
662662
<element ref="tns:timestamp" />
663+
<element ref="tns:dateformat" />
663664
<element ref="tns:htmlanchor" />
664665
<element ref="tns:trim" />
665666
<element ref="tns:split" />
@@ -977,6 +978,26 @@
977978
</complexType>
978979
</element>
979980

981+
<element name="dateformat">
982+
<annotation>
983+
<documentation>Format a date in a specific format.</documentation>
984+
</annotation>
985+
<complexType>
986+
<attribute name="inputformat" type="string" use="optional" default="dd.MM.yyyy" />
987+
<attribute name="outputformat" use="optional" default="LONG">
988+
<simpleType>
989+
<restriction base="string">
990+
<enumeration value="FULL" />
991+
<enumeration value="LONG" />
992+
<enumeration value="MEDIUM" />
993+
<enumeration value="SHORT" />
994+
</restriction>
995+
</simpleType>
996+
</attribute>
997+
<attribute name="language" type="string" use="optional" />
998+
</complexType>
999+
</element>
1000+
9801001
<element name="constant">
9811002
<annotation>
9821003
<documentation>Sets literal value to a constant.</documentation>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<metamorph-test version="1.0"
3+
xmlns="http://www.culturegraph.org/metamorph-test" xmlns:mm="http://www.culturegraph.org/metamorph"
4+
xmlns:cgxml="http://www.culturegraph.org/cgxml">
5+
6+
<test-case name="Specify output format in DateFormat">
7+
<input type="text/x-cg+xml">
8+
<cgxml:cgxml version="1.0">
9+
<cgxml:records>
10+
<cgxml:record id="1">
11+
<cgxml:literal name="date" value="23.04.1564" />
12+
</cgxml:record>
13+
</cgxml:records>
14+
</cgxml:cgxml>
15+
</input>
16+
17+
<transformation type="text/x-metamorph+xml">
18+
<mm:metamorph version="1">
19+
<mm:rules>
20+
<mm:data source="date">
21+
<mm:dateformat outputformat="LONG" language="en"/>
22+
</mm:data>
23+
</mm:rules>
24+
</mm:metamorph>
25+
</transformation>
26+
27+
<result type="text/x-cg+xml">
28+
<cgxml:cgxml version="1.0">
29+
<cgxml:records>
30+
<cgxml:record id="1">
31+
<cgxml:literal name="date" value="April 23, 1564" />
32+
</cgxml:record>
33+
</cgxml:records>
34+
</cgxml:cgxml>
35+
</result>
36+
</test-case>
37+
38+
</metamorph-test>

src/test/java/org/culturegraph/mf/morph/functions/FunctionTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,5 @@
2424
* @author Markus Michael Geipel
2525
*/
2626
@RunWith(TestSuite.class)
27-
@TestDefinitions({"Basic.xml","Lookup.xml","Stateful.xml", "Unique.xml", "Misc.xml", "Script.xml", "Regexp.xml"})
27+
@TestDefinitions({"Basic.xml","Lookup.xml","Stateful.xml", "Unique.xml", "Misc.xml", "Script.xml", "Regexp.xml", "DateFormat.xml"})
2828
public final class FunctionTest {/*bind to xml test*/}

0 commit comments

Comments
 (0)