Jira Cloud and Azure DevOps have different APIs that support different data formats, even for the same type of data. Azure DevOps uses the HTML format, while Jira uses Wiki.
When transferring date-time information between both platforms, transformers need to work behind the scenes to convert between both formatting styles. That’s the only way to get coherent data.
But, this conversion is not available by default due to the lack of compatibility. So, a third-party tool is needed to bridge this gap.
In this article, I’ll discuss how to sync date and time formats between Azure DevOps and Jira Cloud using Exalate.
Use Case Requirements
If your Jira and Azure DevOps instances are hosted in different time zones, and you need to manipulate the date-time fields so that the same date is kept, here is how we do it.
Let us assume the two teams are 5 hours apart. Here is what we can do:
- “Due Date” and “Start Date” are custom date-time fields in Azure DevOps
- “Start date” is a custom date field in Jira
- “Due” is the standard due date field in Jira
We would like to add 5 hours to the Jira timestamp when they are received in the Azure DevOps instance. Then, we would like to subtract 5 hours from the Azure DevOps timestamp when they are received in Jira.
How to Use Exalate to Sync Date and Time Formats between Azure DevOps Jira Cloud
Exalate comes with an AI-powered scripting engine that allows you to write mapping rules for any connection.
It supports the Groovy language, which you can use to write the transformation algorithm for the date-time information.
Follow these steps to get started with Exalate:
Install Exalate and Set Up a Connection
To get started, install Exalate on both Jira Cloud and Azure DevOps from their respective marketplaces or from the integrations page.
For Exalate to handle this use, you need to set up a Script Mode connection. You can follow the complete configuration guide to see how it’s done—it’s pretty simple.
Once connected, click Configure Sync and navigate to the Rules tab, where you’ll set up sync rules.
In the Rules tab, you’ll find default scripts for syncing basic fields like summary, description, comments, and attachments. To sync custom fields or behaviors, you’ll need to add your own scripts.
The Rules tab is divided into:
- Outgoing Sync: Defines the information sent from Jira to Azure DevOps.
- Incoming Sync: Maps the information received from Azure DevOps into Jira.
The same exists on the Azure DevOps side.
Jira Outgoing Script
replica.customFields."Start date" = issue.customFields."Start date"
replica.due = issue.due
replica.customFields."Start date" = issue.customFields."Start date"
replica.due = issue.due
The script for the data going out of Jira is being fetched from the custom field named “Start date”, while the due date is going over as the replica.due
expression.
Jira Incoming Script
import java.text.SimpleDateFormat
import java.text.DateFormat
import java.util.Calendar
import java.util.Date
def datePattern = "yyyy-MM-dd HH:mm:ss";
DateFormat formatter = new SimpleDateFormat(datePattern);
dateString = replica."start"
dateString = dateString.replaceAll("T"," ").trim();
dateString = dateString.replaceAll("Z"," ").trim();
date = formatter.parse(dateString);
def timestamp = date.time
Calendar calendar = Calendar.getInstance()
calendar.timeInMillis = timestamp
calendar.add(Calendar.HOUR_OF_DAY, -5)
def updatedTimestamp = calendar.timeInMillis
issue.customFields."Start date".value = updatedTimestamp
dateString = replica."duedate"
dateString = dateString.replaceAll("T"," ").trim();
dateString = dateString.replaceAll("Z"," ").trim();
date = formatter.parse(dateString);
timestamp = date.time
calendar.timeInMillis = timestamp
calendar.add(Calendar.HOUR_OF_DAY, -5)
issue.due = calendar.getTime()
The code snippet above allows you to set the datePattern
and parsing it through a formatter. It also fetches the timestamp down to milliseconds from the calendar.
The calendar.add(Calendar.HOUR_OF_DAY, -5)
expression specifies that the timestamp coming into Jira should be at least 5 hours behind the original time obtained from Azure DevOps.
Azure DevOps Outgoing Script
replica."start" = workItem."Microsoft.VSTS.Scheduling.StartDate"
replica."duedate" = workItem."Microsoft.VSTS.Scheduling.DueDate"
This code snippet fetches the start and due dates from the default Microsoft Azure DevOps Server (formerly VSTS or Visual Studio Team System).
Azure DevOps Incoming Script
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
def convertJiraTimeToAdoTime(String dateString){
if(dateString == null) return
String inputFormat = "yyyy-MM-dd HH:mm:ss.S"
String outputFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
// Create SimpleDateFormat objects for the input and output formats
SimpleDateFormat inputDateFormat = new SimpleDateFormat(inputFormat)
SimpleDateFormat outputDateFormat = new SimpleDateFormat(outputFormat)
// Parse the input date string into a Date object
Date date = inputDateFormat.parse(dateString)
def timestamp = date.time
Calendar calendar = Calendar.getInstance()
calendar.timeInMillis = timestamp
calendar.add(Calendar.HOUR_OF_DAY, 5)
def updatedTimestamp = calendar.timeInMillis
// Convert the Date object into the output format
return outputDateFormat.format(updatedTimestamp) // String
}
// does not set the field
String inputDateString = replica.customFields."Start date"?.value
workItem."Microsoft.VSTS.Scheduling.StartDate" = convertJiraTimeToAdoTime(inputDateString)
inputDateString = replica.due
workItem."Microsoft.VSTS.Scheduling.DueDate" = convertJiraTimeToAdoTime(inputDateString)
This code snippet converts the incoming date-time information into a string before parsing it as input into the date object. It then fetches the date from the calendar to be 5 hours ahead of the time fetched from the Jira Cloud instance.
Once you’re done, review the scripts to make sure everything is in order before publishing the changes.
That’s all! Your date-time formats are now in sync between Azure DevOps and Jira Cloud.
Using script-based solutions like Exalate can seem overwhelming at first, but if done correctly, they can be very effective for your integration needs.
Have any specific use case that requires handling different data formats? Just ask our integration engineers for a walkthrough of what’s possible.

Learn more about how Qualco implements a Jira Azure DevOps integration using Exalate to cut down average incident resolution time