How to convert Timezone key pair to short timezone codes?

I am trying to get the current user timezone, pass this as a variable to the velocity template and then according to the value of the timezone I am manipulating timestamp values on a table.

My problem is that I am getting timezone results in “Europe/Berlin” or “Europe/London” format. But I need it as "de-DE "or “en-EN” etc.
I am almost there.
Does anyone maybe know how I can convert my output of “Europe/London” to something like “en-EN” on step 1?
I have come across many classes and services from JIRA that deals with similar stuff but couldn’t pinpoint if I can use one of them. TimeZoneManager, TimeZoneInfo, TimeZoneService,TimeZoneInfo.

  1. This is how I get the current user
public String getLoggedInUserTimezone() {
        ExtendedPreferences extPref = userPreferencesManager.getExtendedPreferences(authenticationContext.getLoggedInUser());
        return extPref.getString(PreferenceKeys.USER_TIMEZONE);

Output: “Europe/Berlin”

  1. This is how I add it into Velocity
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        context.put("timezone", networkService.getLoggedInUserTimezone());
  1. This is how I make the value available to JavaScript in the template
<input id="timezone" name="timezone" type="hidden"
  1. This is how the JavaScript access the variable and manipulates it
function formatDate() {
    const table = document.getElementById("ti-table");
    const creationTimeCell = 4;
    let timezone = document.getElementById("timezone").value;

    for (let i = 1, row; row = table.rows[i]; i++) {
        let currentDate = document.getElementById("ti-table").rows[i].cells[creationTimeCell].innerHTML;
        let formattedLocaleDateString = new Date(currentDate).toLocaleDateString([timezone], {});
        console.log("formattedLocaleDateString: " + formattedLocaleDateString);
        let formattedLocaleTimeString = new Date(currentDate).toLocaleTimeString([timezone], {
            hourCycle: 'h24',
            hour: "2-digit",
            minute: "2-digit"
        let newFormattedLocaleDateTime = formattedLocaleDateString + " - " + formattedLocaleTimeString;
        document.getElementById("ti-table").rows[i].cells[creationTimeCell].innerHTML = newFormattedLocaleDateTime;


This is where it gives me an error called
Uncaught RangeError: invalid language tag: "Europe/London" , my guess is it is because it expects in en-EN format. As a last resort, I might add a map of time zones and their corresponding short codes in JavaScript, but I rather not do that.

Okay I have found a solution that works a lot different but solved the main problem.

I have used the Jira DateTimeFormatter in a service component, which defines a DateTimeFormatter specific for the currently logged in User, injected this in the Velocity context in my Servlet and then called the format() method on the .VM Template.

Looks like this:

public class SomeServiceImpl implements SomeService {

    private final DateTimeFormatter dateTimeFormatter;

    public SomeServiceImpl (DateTimeFormatter dateTimeFormatter) {
        this.dateTimeFormatter = dateTimeFormatter.forLoggedInUser();

    public DateTimeFormatter defineDateTimeFormatterForLoggedInUser() {
        return dateTimeFormatter;
The servlet, where it gets put into the context
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            context.put("dateTimeFormatter", someService.defineDateTimeFormatterForLoggedInUser());

and on the .VM