Hello,
I have created a custom field type that displays the date time in the UTC time zone with the following class:
import java.sql.Timestamp;
import java.util.Date;
import java.util.Map;
import java.util.TimeZone;
import org.apache.log4j.Logger;
import org.apache.commons.lang3.StringUtils;
import com.atlassian.jira.config.properties.APKeys;
import com.atlassian.jira.config.properties.ApplicationProperties;
import com.atlassian.jira.datetime.DateTimeFormatter;
import com.atlassian.jira.datetime.DateTimeFormatterFactory;
import com.atlassian.jira.datetime.DateTimeStyle;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.customfields.impl.DateTimeCFType;
import com.atlassian.jira.issue.customfields.impl.FieldValidationException;
import com.atlassian.jira.issue.customfields.impl.rest.DateTimeCustomFieldOperationsHandler;
import com.atlassian.jira.issue.customfields.manager.GenericConfigManager;
import com.atlassian.jira.issue.customfields.persistence.CustomFieldValuePersister;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.fields.OrderableField;
import com.atlassian.jira.issue.fields.layout.field.FieldLayoutItem;
import com.atlassian.jira.issue.fields.rest.RestFieldOperationsHandler;
import com.atlassian.jira.issue.history.DateTimeFieldChangeLogHelper;
import com.atlassian.jira.issue.views.util.csv.CsvDateFormatter;
import com.atlassian.jira.security.JiraAuthenticationContext;
import com.atlassian.jira.util.I18nHelper;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.JiraImport;
@Scanned
public class UTCDateTimeFieldType extends DateTimeCFType {
DateTimeFormatter datePickerFormatter;
JiraAuthenticationContext jiraAuthenticationContext;
ApplicationProperties applicationProperties;
public UTCDateTimeFieldType(
@JiraImport CustomFieldValuePersister customFieldValuePersister,
@JiraImport GenericConfigManager genericConfigManager,
@JiraImport DateTimeFormatterFactory dateTimeFormatterFactory,
@JiraImport JiraAuthenticationContext jiraAuthenticationContext,
@JiraImport("jiraApplicationProperties") ApplicationProperties applicationProperties,
@JiraImport DateTimeFieldChangeLogHelper dateTimeFieldChangeLogHelper,
@JiraImport CsvDateFormatter csvDateFormatter) {
super(customFieldValuePersister, genericConfigManager, dateTimeFormatterFactory, jiraAuthenticationContext, applicationProperties, dateTimeFieldChangeLogHelper, csvDateFormatter);
this.datePickerFormatter = dateTimeFormatterFactory.formatter().withZone(TimeZone.getTimeZone("UTC")).withStyle(DateTimeStyle.DATE_TIME_PICKER);
this.jiraAuthenticationContext = jiraAuthenticationContext;
this.applicationProperties = applicationProperties;
}
final Logger logging = Logger.getLogger(UTCDateTimeFieldType.class);
@Override
public String getStringFromSingularObject(final Date customFieldObject) {
return this.datePickerFormatter.format(customFieldObject);
}
@Override
public Date getSingularObjectFromString(final String string) throws FieldValidationException {
if (StringUtils.isEmpty(string)) {
return null;
}
try {
Date date = this.datePickerFormatter.parse(string);
return new Timestamp(date.getTime());
} catch (IllegalArgumentException e) {
final I18nHelper i18nBean = jiraAuthenticationContext.getI18nHelper();
throw new FieldValidationException(i18nBean.getText("fields.validation.data.format", applicationProperties.getDefaultBackedString(APKeys.JIRA_DATE_TIME_PICKER_JAVA_FORMAT)));
}
}
@Override
public String getNow() {
return this.datePickerFormatter.format(new Date());
}
@Override
public Map<String, Object> getVelocityParameters(final Issue issue, final CustomField field, final FieldLayoutItem fieldLayoutItem) {
final Map<String, Object> map = super.getVelocityParameters(issue, field, fieldLayoutItem);
map.put("dateTimePicker", Boolean.TRUE);
map.put("datePickerFormatter", this.datePickerFormatter);
map.put("titleFormatter", this.datePickerFormatter.withStyle(DateTimeStyle.COMPLETE));
map.put("iso8601Formatter", this.datePickerFormatter.withStyle(DateTimeStyle.ISO_8601_DATE_TIME));
return map;
}
@Override
public RestFieldOperationsHandler getRestFieldOperation(CustomField field) {
return new DateTimeCustomFieldOperationsHandler(field, this.datePickerFormatter, getI18nBean());
}
}
The most important line for setting the time zone is this one:
this.datePickerFormatter = dateTimeFormatterFactory.formatter().withZone(TimeZone.getTimeZone("UTC")).withStyle(DateTimeStyle.DATE_TIME_PICKER);
Now, I want to create a custom field searcher. The default DateTimeRangeSearcher uses the time zone of the current user.
Does anyone have an idea how to create a searcher that uses the UTC time zone?
Kind regards,
Julia
Could you please share the solution? Thanks in advance
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello Javier Portillo,
sure.
I created implementations of com.atlassian.jira.timezone.TimeZoneManager (UtcTimeZoneManagerImpl) and com.atlassian.jira.jql.util.JqlDateSupport (UtcJqlDateSupportImpl) where I replaced the time zones with the UTC time zone and the time zone manager with my implementation.
Then I created the searcher:
package com.scolution.jira.plugins.fields;
import com.atlassian.core.util.Clock;
import com.atlassian.jira.config.properties.ApplicationProperties;
import com.atlassian.jira.datetime.DateTimeFormatterFactory;
import com.atlassian.jira.issue.customfields.searchers.DateTimeRangeSearcher;
import com.atlassian.jira.issue.customfields.searchers.transformer.CustomFieldInputHelper;
import com.atlassian.jira.jql.operand.JqlOperandResolver;
import com.atlassian.jira.jql.util.JqlDateSupport;
import com.atlassian.jira.security.JiraAuthenticationContext;
import com.atlassian.jira.template.VelocityTemplatingEngine;
import com.atlassian.jira.timezone.TimeZoneManager;
import com.atlassian.jira.util.velocity.VelocityRequestContextFactory;
import com.atlassian.jira.web.action.util.CalendarLanguageUtil;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.JiraImport;
import com.scolution.jira.plugins.fields.impl.UtcJqlDateSupportImpl;
import com.scolution.jira.plugins.fields.impl.UtcTimeZoneManagerImpl;
import javax.inject.Inject;
@Scanned
public class UtcDateTimeFieldSearcher extends DateTimeRangeSearcher {
@Inject
public UtcDateTimeFieldSearcher(
@JiraImport JiraAuthenticationContext context,
@JiraImport JqlOperandResolver jqlOperandResolver,
@JiraImport VelocityRequestContextFactory velocityRenderContext,
@JiraImport ApplicationProperties applicationProperties,
@JiraImport VelocityTemplatingEngine templatingEngine,
@JiraImport CalendarLanguageUtil calendarUtils,
@JiraImport JqlDateSupport dateSupport,
@JiraImport CustomFieldInputHelper customFieldInputHelper,
@JiraImport TimeZoneManager timeZoneManager,
@JiraImport DateTimeFormatterFactory dateTimeFormatterFactory,
@JiraImport Clock clock) {
super(context, jqlOperandResolver, velocityRenderContext, applicationProperties, templatingEngine, calendarUtils,
new UtcJqlDateSupportImpl(clock, new UtcTimeZoneManagerImpl()), customFieldInputHelper, new UtcTimeZoneManagerImpl(), dateTimeFormatterFactory);
}
}
The custom field searcher in the atlassian-plugin.xml:
<customfield-searcher key="utc-datetime-range-searcher" name="UTC Date Time Range Searcher"
class="com.scolution.jira.plugins.fields.UtcDateTimeFieldSearcher">
<description>Allow searching for a date and time that is between two other dates and times</description>
<valid-customfield-type package="${atlassian.plugin.key}" key="utc-date-time-field-type"/>
</customfield-searcher>
Kind regards,
Julia Janky
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.