i18n work in rendering context (WIP) (#1592)
This commit is contained in:
parent
2ce5bbd0d8
commit
a111989bb4
|
@ -42,6 +42,7 @@ import javax.annotation.Nullable;
|
|||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
@ -820,6 +821,11 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
|
|||
return DateTimeUtil.toHumanDisplay(getTimeZone(), getPrecision(), getValue(), getValueAsString());
|
||||
}
|
||||
|
||||
public String toHumanDisplay(Locale locale) {
|
||||
return DateTimeUtil.toHumanDisplay(locale, getTimeZone(), getPrecision(), getValue());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a human readable version of this date/time using the system local format, converted to the local timezone
|
||||
* if neccesary.
|
||||
|
|
|
@ -24,8 +24,11 @@ import org.hl7.fhir.r5.model.Coding;
|
|||
import org.hl7.fhir.r5.model.Enumeration;
|
||||
import org.hl7.fhir.r5.model.Extension;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StringType;
|
||||
import org.hl7.fhir.r5.renderers.CodeSystemRenderer.Translateable;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.KnownLinkType;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.MultiLanguagePolicy;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities.CodeSystemNavigator;
|
||||
|
@ -38,6 +41,27 @@ import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
|||
|
||||
public class CodeSystemRenderer extends TerminologyRenderer {
|
||||
|
||||
public class Translateable {
|
||||
|
||||
private String lang;
|
||||
private StringType value;
|
||||
|
||||
public Translateable(String lang, StringType value) {
|
||||
this.lang = lang;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getLang() {
|
||||
return lang;
|
||||
}
|
||||
|
||||
public StringType getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private Boolean doMarkdown = null;
|
||||
|
||||
public CodeSystemRenderer(RenderingContext context) {
|
||||
|
@ -426,34 +450,47 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
if (hasDefinitions) {
|
||||
td = tr.td();
|
||||
if (c != null &&c.hasDefinitionElement()) {
|
||||
if (getContext().getLang() == null) {
|
||||
if (hasMarkdownInDefinitions(cs)) {
|
||||
addMarkdown(renderStatusDiv(c.getDefinitionElement(), td), c.getDefinition());
|
||||
} else {
|
||||
renderStatus(c.getDefinitionElement(), td).addText(c.getDefinition());
|
||||
}
|
||||
} else if (getContext().getLang().equals("*")) {
|
||||
// translations of the definition might come from either the translation extension, or from the designations
|
||||
StringType defn = context.getTranslatedElement(c.getDefinitionElement());
|
||||
boolean sl = false;
|
||||
for (ConceptDefinitionDesignationComponent cd : c.getDesignation())
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "definition") && cd.hasLanguage() && !c.getDefinition().equalsIgnoreCase(cd.getValue()))
|
||||
sl = true;
|
||||
td.addText((sl ? cs.getLanguage("en")+": " : ""));
|
||||
if (hasMarkdownInDefinitions(cs))
|
||||
addMarkdown(renderStatusDiv(c.getDefinitionElement(), td), c.getDefinition());
|
||||
else
|
||||
renderStatus(c.getDefinitionElement(), td).addText(c.getDefinition());
|
||||
for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) {
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "definition") && cd.hasLanguage() && !c.getDefinition().equalsIgnoreCase(cd.getValue())) {
|
||||
td.br();
|
||||
td.addText(cd.getLanguage()+": "+cd.getValue());
|
||||
sl = true;
|
||||
}
|
||||
}
|
||||
} else if (getContext().getLang().equals(cs.getLanguage()) || (getContext().getLang().equals("en") && !cs.hasLanguage())) {
|
||||
renderStatus(c.getDefinitionElement(), td).addText(c.getDefinition());
|
||||
|
||||
if (getContext().getMultiLanguagePolicy() == MultiLanguagePolicy.NONE && (sl || ToolingExtensions.hasLanguageTranslations(defn))) {
|
||||
if (hasMarkdownInDefinitions(cs)) {
|
||||
addMarkdown(renderStatusDiv(defn, td), defn.asStringValue());
|
||||
} else {
|
||||
renderStatus(defn, td).addText(defn.asStringValue());
|
||||
}
|
||||
} else {
|
||||
List<Translateable> list = new ArrayList<>();
|
||||
list.add(new Translateable(cs.getLanguage(), defn));
|
||||
for (Extension ext : defn.getExtensionsByUrl(ToolingExtensions.EXT_TRANSLATION)) {
|
||||
list.add(new Translateable(ext.getExtensionString("lang"), ext.getExtensionByUrl("content").getValueStringType()));
|
||||
}
|
||||
for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) {
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "definition") && cd.hasLanguage() && cd.getLanguage().equals(getContext().getLang())) {
|
||||
td.addText(cd.getValue());
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "definition") && cd.hasLanguage() && !c.getDefinition().equalsIgnoreCase(cd.getValue())) {
|
||||
list.add(new Translateable(cd.getLanguage(), cd.getValueElement()));
|
||||
}
|
||||
}
|
||||
boolean first = true;
|
||||
for (Translateable ti : list) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
td.br();
|
||||
}
|
||||
|
||||
if (ti.lang != null) {
|
||||
td.addText(ti.lang + ": ");
|
||||
}
|
||||
if (hasMarkdownInDefinitions(cs)) {
|
||||
addMarkdown(renderStatusDiv(ti.getValue(), td), ti.getValue().asStringValue());
|
||||
} else {
|
||||
renderStatus(ti.getValue(), td).addText(ti.getValue().asStringValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -346,7 +346,7 @@ public class DataRenderer extends Renderer implements CodeResolver {
|
|||
if (JurisdictionUtilities.isJurisdiction(system)) {
|
||||
return JurisdictionUtilities.displayJurisdiction(system+"#"+code);
|
||||
}
|
||||
ValidationResult t = getContext().getWorker().validateCode(getContext().getTerminologyServiceOptions().withLanguage(context.getLang()).withVersionFlexible(true), system, version, code, null);
|
||||
ValidationResult t = getContext().getWorker().validateCode(getContext().getTerminologyServiceOptions().withLanguage(context.getLocale().toString()).withVersionFlexible(true), system, version, code, null);
|
||||
|
||||
if (t != null && t.getDisplay() != null)
|
||||
return t.getDisplay();
|
||||
|
|
|
@ -843,8 +843,8 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
}
|
||||
|
||||
public void markLanguage(XhtmlNode x) {
|
||||
x.setAttribute("lang", context.getLang());
|
||||
x.setAttribute("xml:lang", context.getLang());
|
||||
x.setAttribute("lang", context.getLocale().toString());
|
||||
x.setAttribute("xml:lang", context.getLocale().toString());
|
||||
x.addTag(0, "hr");
|
||||
x.addTag(0, "p").b().tx(context.getLocale().getDisplayName());
|
||||
x.addTag(0, "hr");
|
||||
|
|
|
@ -6,9 +6,11 @@ import java.time.ZoneId;
|
|||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
|
@ -18,11 +20,8 @@ import org.hl7.fhir.r5.context.IWorkerContext;
|
|||
import org.hl7.fhir.r5.elementmodel.Element;
|
||||
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine.IEvaluationContext;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.BaseDateTimeType;
|
||||
import org.hl7.fhir.r5.model.DateTimeType;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Enumeration;
|
||||
import org.hl7.fhir.r5.model.Extension;
|
||||
import org.hl7.fhir.r5.model.PrimitiveType;
|
||||
import org.hl7.fhir.r5.model.StringType;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.IReferenceResolver;
|
||||
|
@ -36,6 +35,40 @@ import org.hl7.fhir.utilities.Utilities;
|
|||
import org.hl7.fhir.utilities.i18n.RenderingI18nContext;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
|
||||
/**
|
||||
* Managing Language when rendering
|
||||
*
|
||||
* You can specify a language to use when rendering resources by setting the setLocale() on
|
||||
* the super class. The locale drives the following:
|
||||
* - choice of java supplied rendering phrase, if translations are provided for the locale
|
||||
* - integer and date formats used (but see below for date formats)
|
||||
* - automatic translation of coded values, if language supplements are available
|
||||
* - choosing text representation considering the FHIR translation extension
|
||||
*
|
||||
* By default, the locale is null, and the default locale for the underlying system is used.
|
||||
* If you set locale to a specific value, then that value will be used instead of the default locale.
|
||||
*
|
||||
* By default, only a single language is rendered, based on the locale. Where resources contain
|
||||
* multiple language content (designations in CodeSystem and ValueSet, or using the translation
|
||||
* extension), you can control what languages are presented using the properties multiLanguagePolicy
|
||||
* and languages
|
||||
* - multiLanguagePolicy: NONE (default), DESIGNATIONS, ALL
|
||||
* - languages: a list of allowed languages. Default is empty which means all languages in scope via multiLanguagePolicy
|
||||
*
|
||||
* Managing Date/Time Formatting
|
||||
*
|
||||
* This class has multiple parameters that influence date/time formatting when rendering resources
|
||||
*
|
||||
* - The default rendering is using the default java locale as above
|
||||
* - If you setLocale() to something, then the defaults for the locale will be used
|
||||
* - Else you can set the values of dateTimeFormat, dateFormat, dateYearFormat and dateYearMonthFormat
|
||||
*
|
||||
* If you set the value of locale, the values of dateTimeFormat, dateFormat, dateYearFormat and dateYearMonthFormat are
|
||||
* reset to the system defaults
|
||||
*
|
||||
* Timezones: by default, date/times are rendered in their source timezone
|
||||
*
|
||||
*/
|
||||
public class RenderingContext extends RenderingI18nContext {
|
||||
|
||||
// provides liquid templates, if they are available for the content
|
||||
|
@ -176,6 +209,12 @@ public class RenderingContext extends RenderingI18nContext {
|
|||
}
|
||||
}
|
||||
|
||||
public enum MultiLanguagePolicy {
|
||||
NONE, // ONLY render the language in the locale
|
||||
DESIGNATIONS, // in addition to the locale language, render designations from other languages (eg. as found in code systems and value sets
|
||||
ALL // in addition to translations in designations, look for an render translations (WIP)
|
||||
}
|
||||
|
||||
private IWorkerContext worker;
|
||||
private MarkDownProcessor markdown;
|
||||
private ResourceRendererMode mode;
|
||||
|
@ -185,7 +224,15 @@ public class RenderingContext extends RenderingI18nContext {
|
|||
private IEvaluationContext services;
|
||||
private ITypeParser parser;
|
||||
|
||||
private String lang;
|
||||
// i18n related fields
|
||||
private MultiLanguagePolicy multiLanguagePolicy = MultiLanguagePolicy.NONE;
|
||||
private Set<String> allowedLanguages = new HashSet<>();
|
||||
private ZoneId timeZoneId;
|
||||
private DateTimeFormatter dateTimeFormat;
|
||||
private DateTimeFormatter dateFormat;
|
||||
private DateTimeFormatter dateYearFormat;
|
||||
private DateTimeFormatter dateYearMonthFormat;
|
||||
|
||||
private String localPrefix; // relative link within local context
|
||||
private int headerLevelContext;
|
||||
private boolean canonicalUrlsAsLinks;
|
||||
|
@ -212,11 +259,6 @@ public class RenderingContext extends RenderingI18nContext {
|
|||
private boolean showComments = false;
|
||||
|
||||
private FhirPublication targetVersion;
|
||||
private ZoneId timeZoneId;
|
||||
private DateTimeFormatter dateTimeFormat;
|
||||
private DateTimeFormatter dateFormat;
|
||||
private DateTimeFormatter dateYearFormat;
|
||||
private DateTimeFormatter dateYearMonthFormat;
|
||||
private boolean copyButton;
|
||||
private ProfileKnowledgeProvider pkp;
|
||||
private String changeVersion;
|
||||
|
@ -233,13 +275,13 @@ public class RenderingContext extends RenderingI18nContext {
|
|||
* @param markdown - appropriate markdown processing engine
|
||||
* @param terminologyServiceOptions - options to use when looking up codes
|
||||
* @param specLink - path to FHIR specification
|
||||
* @param lang - langauage to render in
|
||||
* @param locale - i18n for rendering
|
||||
*/
|
||||
public RenderingContext(IWorkerContext worker, MarkDownProcessor markdown, ValidationOptions terminologyServiceOptions, String specLink, String localPrefix, String lang, ResourceRendererMode mode, GenerationRules rules) {
|
||||
public RenderingContext(IWorkerContext worker, MarkDownProcessor markdown, ValidationOptions terminologyServiceOptions, String specLink, String localPrefix, Locale locale, ResourceRendererMode mode, GenerationRules rules) {
|
||||
super();
|
||||
this.worker = worker;
|
||||
this.markdown = markdown;
|
||||
this.lang = lang;
|
||||
this.locale = locale;
|
||||
this.links.put(KnownLinkType.SPEC, specLink);
|
||||
this.localPrefix = localPrefix;
|
||||
this.mode = mode;
|
||||
|
@ -247,12 +289,10 @@ public class RenderingContext extends RenderingI18nContext {
|
|||
if (terminologyServiceOptions != null) {
|
||||
this.terminologyServiceOptions = terminologyServiceOptions;
|
||||
}
|
||||
// default to US locale - discussion here: https://github.com/hapifhir/org.hl7.fhir.core/issues/666
|
||||
this.locale = new Locale.Builder().setLanguageTag("en-US").build();
|
||||
}
|
||||
|
||||
public RenderingContext copy() {
|
||||
RenderingContext res = new RenderingContext(worker, markdown, terminologyServiceOptions, getLink(KnownLinkType.SPEC), localPrefix, lang, mode, rules);
|
||||
RenderingContext res = new RenderingContext(worker, markdown, terminologyServiceOptions, getLink(KnownLinkType.SPEC), localPrefix, locale, mode, rules);
|
||||
|
||||
res.resolver = resolver;
|
||||
res.templateProvider = templateProvider;
|
||||
|
@ -291,6 +331,8 @@ public class RenderingContext extends RenderingI18nContext {
|
|||
|
||||
res.terminologyServiceOptions = terminologyServiceOptions.copy();
|
||||
res.typeMap.putAll(typeMap);
|
||||
res.multiLanguagePolicy = multiLanguagePolicy;
|
||||
res.allowedLanguages.addAll(allowedLanguages);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -330,8 +372,16 @@ public class RenderingContext extends RenderingI18nContext {
|
|||
return markdown;
|
||||
}
|
||||
|
||||
public String getLang() {
|
||||
return lang;
|
||||
public MultiLanguagePolicy getMultiLanguagePolicy() {
|
||||
return multiLanguagePolicy;
|
||||
}
|
||||
|
||||
public void setMultiLanguagePolicy(MultiLanguagePolicy multiLanguagePolicy) {
|
||||
this.multiLanguagePolicy = multiLanguagePolicy;
|
||||
}
|
||||
|
||||
public Set<String> getAllowedLanguages() {
|
||||
return allowedLanguages;
|
||||
}
|
||||
|
||||
public String getLocalPrefix() {
|
||||
|
@ -502,14 +552,6 @@ public class RenderingContext extends RenderingI18nContext {
|
|||
return ref;
|
||||
}
|
||||
|
||||
public RenderingContext setLang(String lang) {
|
||||
this.lang = lang;
|
||||
if (lang != null) {
|
||||
setLocale(new Locale(lang));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public RenderingContext setLocalPrefix(String localPrefix) {
|
||||
this.localPrefix = localPrefix;
|
||||
return this;
|
||||
|
@ -746,8 +788,8 @@ public class RenderingContext extends RenderingI18nContext {
|
|||
|
||||
|
||||
public String getTranslated(PrimitiveType<?> t) {
|
||||
if (lang != null) {
|
||||
String v = ToolingExtensions.getLanguageTranslation(t, lang);
|
||||
if (locale != null) {
|
||||
String v = ToolingExtensions.getLanguageTranslation(t, locale.toString());
|
||||
if (v != null) {
|
||||
return v;
|
||||
}
|
||||
|
@ -755,18 +797,32 @@ public class RenderingContext extends RenderingI18nContext {
|
|||
return t.asStringValue();
|
||||
}
|
||||
|
||||
public StringType getTranslatedElement(PrimitiveType<?> t) {
|
||||
if (locale != null) {
|
||||
StringType v = ToolingExtensions.getLanguageTranslationElement(t, locale.toString());
|
||||
if (v != null) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
if (t instanceof StringType) {
|
||||
return (StringType) t;
|
||||
} else {
|
||||
return new StringType(t.asStringValue());
|
||||
}
|
||||
}
|
||||
|
||||
public String getTranslatedCode(Base b, String codeSystem) {
|
||||
|
||||
if (b instanceof org.hl7.fhir.r5.model.Element) {
|
||||
org.hl7.fhir.r5.model.Element e = (org.hl7.fhir.r5.model.Element) b;
|
||||
if (lang != null) {
|
||||
String v = ToolingExtensions.getLanguageTranslation(e, lang);
|
||||
if (locale != null) {
|
||||
String v = ToolingExtensions.getLanguageTranslation(e, locale.toString());
|
||||
if (v != null) {
|
||||
return v;
|
||||
}
|
||||
// no? then see if the tx service can translate it for us
|
||||
try {
|
||||
ValidationResult t = getContext().validateCode(getTerminologyServiceOptions().withLanguage(lang).withVersionFlexible(true),
|
||||
ValidationResult t = getContext().validateCode(getTerminologyServiceOptions().withLanguage(locale.toString()).withVersionFlexible(true),
|
||||
codeSystem, null, e.primitiveValue(), null);
|
||||
if (t.isOk() && t.getDisplay() != null) {
|
||||
return t.getDisplay();
|
||||
|
@ -788,14 +844,14 @@ public class RenderingContext extends RenderingI18nContext {
|
|||
}
|
||||
|
||||
public String getTranslatedCode(Enumeration<?> e, String codeSystem) {
|
||||
if (lang != null) {
|
||||
String v = ToolingExtensions.getLanguageTranslation(e, lang);
|
||||
if (locale != null) {
|
||||
String v = ToolingExtensions.getLanguageTranslation(e, locale.toString());
|
||||
if (v != null) {
|
||||
return v;
|
||||
}
|
||||
// no? then see if the tx service can translate it for us
|
||||
try {
|
||||
ValidationResult t = getContext().validateCode(getTerminologyServiceOptions().withLanguage(lang).withVersionFlexible(true),
|
||||
ValidationResult t = getContext().validateCode(getTerminologyServiceOptions().withLanguage(locale.toString()).withVersionFlexible(true),
|
||||
codeSystem, null, e.getCode(), null);
|
||||
if (t.isOk() && t.getDisplay() != null) {
|
||||
return t.getDisplay();
|
||||
|
@ -818,14 +874,14 @@ public class RenderingContext extends RenderingI18nContext {
|
|||
}
|
||||
|
||||
public String getTranslatedCode(Element e, String codeSystem) {
|
||||
if (lang != null) {
|
||||
if (locale != null) {
|
||||
// first we look through the translation extensions
|
||||
for (Element ext : e.getChildrenByName("extension")) {
|
||||
String url = ext.getNamedChildValue("url");
|
||||
if (url.equals(ToolingExtensions.EXT_TRANSLATION)) {
|
||||
Base e1 = ext.getExtensionValue("lang");
|
||||
|
||||
if (e1 != null && e1.primitiveValue() != null && e1.primitiveValue().equals(lang)) {
|
||||
if (e1 != null && e1.primitiveValue() != null && e1.primitiveValue().equals(locale.toString())) {
|
||||
e1 = ext.getExtensionValue("content");
|
||||
if (e1 != null && e1.isPrimitive()) {
|
||||
return e1.primitiveValue();
|
||||
|
@ -835,7 +891,7 @@ public class RenderingContext extends RenderingI18nContext {
|
|||
}
|
||||
// no? then see if the tx service can translate it for us
|
||||
try {
|
||||
ValidationResult t = getContext().validateCode(getTerminologyServiceOptions().withLanguage(lang).withVersionFlexible(true),
|
||||
ValidationResult t = getContext().validateCode(getTerminologyServiceOptions().withLanguage(locale.toString()).withVersionFlexible(true),
|
||||
codeSystem, null, e.primitiveValue(), null);
|
||||
if (t.isOk() && t.getDisplay() != null) {
|
||||
return t.getDisplay();
|
||||
|
|
|
@ -776,6 +776,15 @@ public class ToolingExtensions {
|
|||
// throw new Error("Attempt to assign multiple OIDs to value set "+vs.getName()+" ("+vs.getUrl()+"). Has "+readStringExtension(vs, EXT_OID)+", trying to add "+oid);
|
||||
// }
|
||||
|
||||
public static boolean hasLanguageTranslations(Element element) {
|
||||
for (Extension e : element.getExtension()) {
|
||||
if (e.getUrl().equals(EXT_TRANSLATION)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hasLanguageTranslation(Element element, String lang) {
|
||||
for (Extension e : element.getExtension()) {
|
||||
if (e.getUrl().equals(EXT_TRANSLATION)) {
|
||||
|
@ -802,6 +811,20 @@ public class ToolingExtensions {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static StringType getLanguageTranslationElement(Element element, String lang) {
|
||||
for (Extension e : element.getExtension()) {
|
||||
if (e.getUrl().equals(EXT_TRANSLATION)) {
|
||||
Extension e1 = ExtensionHelper.getExtension(e, "lang");
|
||||
|
||||
if (e1 != null && e1.getValue() != null && e1.getValue() instanceof CodeType && ((CodeType) e1.getValue()).getValue().equals(lang)) {
|
||||
e1 = ExtensionHelper.getExtension(e, "content");
|
||||
return ((StringType) e1.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void addLanguageTranslation(Element element, String lang, String value) {
|
||||
if (Utilities.noString(lang) || Utilities.noString(value))
|
||||
return;
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.hl7.fhir.utilities;
|
|||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.commons.lang3.time.FastDateFormat;
|
||||
|
@ -42,4 +43,25 @@ public class DateTimeUtil {
|
|||
return ourHumanDateTimeFormat.format(theValue);
|
||||
}
|
||||
}
|
||||
|
||||
public static String toHumanDisplay(Locale locale, TimeZone theTimeZone, TemporalPrecisionEnum thePrecision, Date theValue) {
|
||||
Calendar value = theTimeZone != null ? Calendar.getInstance(theTimeZone) : Calendar.getInstance();
|
||||
value.setTime(theValue);
|
||||
|
||||
FastDateFormat dateFormat = FastDateFormat.getDateInstance(FastDateFormat.MEDIUM, locale);
|
||||
FastDateFormat dateTimeFormat = FastDateFormat.getDateTimeInstance(FastDateFormat.MEDIUM, FastDateFormat.MEDIUM, locale);
|
||||
|
||||
switch (thePrecision) {
|
||||
case YEAR:
|
||||
case MONTH:
|
||||
case DAY:
|
||||
return dateFormat.format(value);
|
||||
case MILLI:
|
||||
case SECOND:
|
||||
default:
|
||||
return dateTimeFormat.format(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -29,7 +29,7 @@ public abstract class I18nBase {
|
|||
if (Objects.nonNull(locale)) {
|
||||
return locale;
|
||||
} else {
|
||||
return Locale.US;
|
||||
return Locale.getDefault();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue