Passa al contenuto
Menu
È necessario essere registrati per interagire con la community.
La domanda è stata contrassegnata
2 Risposte
2348 Visualizzazioni

In the entire application the time format used is 24h. In contrast, in Time Off app the type used is AM-PM. Is it possible to change this to use a 24h format everywhere?

Avatar
Abbandona
Risposta migliore

I made an account just for this and the one person that will have the same problem. 

The problem is that in the frontend odoo only uses the locale language code and not the time format options. 

If you know how to develop modules you can add the following code to the static code and add the file to your web.assets_backend then odoo will also respect the time format in chatter, forms and discuss. 

If anyoe else needs this and can't develop their own addons I could wrap it in an odoo 18 addon and make it public. Just respond to this. :)

/** @odoo-module */


import { user } from "@web/core/user";

import { _t } from "@web/core/l10n/translation";

import { rpc } from "@web/core/network/rpc";

import { session } from "@web/session";


// Cache for language formats to avoid repeated server calls

const langFormatCache = {};


/**

* Gets the user's preferred time format from res_lang model

* @returns {Promise<string>} The time format string (e.g. '%H:%M')

*/

async function getUserTimeFormat() {

// Check if we already have the format in cache

let userLang = user.lang || session.user_context.lang || 'en_US';


userLang = userLang.replace('-', '_');

if (langFormatCache[userLang]) {

return langFormatCache[userLang];

}


try {

// Query the server for language settings

const langData = await rpc('/web/dataset/call_kw', {

model: 'res.lang',

method: 'search_read',

args: [[['code', '=', userLang]], ['code', 'time_format', 'date_format', 'short_time_format']],

kwargs: {},

});

if (langData && langData.length) {

const timeFormat = langData[0].time_format || '%H:%M';

const shortTimeFormat = langData[0].short_time_format || '%H:%M';

// Cache the result

langFormatCache[userLang] = {

timeFormat,

shortTimeFormat

};

return langFormatCache[userLang];

}

return {

timeFormat: '%H:%M:%S', // Default format if not found

shortTimeFormat: '%H:%M'

};

} catch (error) {

return {

timeFormat: '%H:%M:%S', // Default format in case of errors

shortTimeFormat: '%H:%M'

}; // Return default formats in case of errors

}

}


// Translation function to convert from DateTime object to user-defined format

function formatTimeAccordingToUserPreferences(dateTime, hasSeconds, timeFormat = {

shortTimeFormat: '%H:%M',

timeFormat: '%H:%M:%S'

}) {

if (!dateTime) return '';


const localTimeFormat = hasSeconds ? timeFormat.timeFormat : timeFormat.shortTimeFormat;


// Extract hour and minute values from DateTime object

const hour = dateTime.hour;

const minute = dateTime.minute;

const second = dateTime.second;

// Handle different format placeholders

let formattedTime = localTimeFormat;

// Handle 24-hour format

formattedTime = formattedTime.replace(/%H/g, hour.toString().padStart(2, '0')); // 24h with leading zero

formattedTime = formattedTime.replace(/%k/g, hour.toString()); // 24h without leading zero

// Handle 12-hour format

const hour12 = hour % 12 || 12;

formattedTime = formattedTime.replace(/%I/g, hour12.toString().padStart(2, '0')); // 12h with leading zero

formattedTime = formattedTime.replace(/%l/g, hour12.toString()); // 12h without leading zero

// Handle minutes and seconds

formattedTime = formattedTime.replace(/%M/g, minute.toString().padStart(2, '0')); // Minutes with leading zero

formattedTime = formattedTime.replace(/%S/g, second.toString().padStart(2, '0')); // Seconds with leading zero

// Handle AM/PM indicator

const ampm = hour >= 12 ? 'PM' : 'AM';

formattedTime = formattedTime.replace(/%p/g, ampm); // AM/PM uppercase

formattedTime = formattedTime.replace(/%P/g, ampm.toLowerCase()); // am/pm lowercase

return formattedTime;

}


// Global Luxon patch

const patchLuxon = async function() {

if (!window.luxon || !window.luxon.DateTime) {

setTimeout(patchLuxon, 500);

return;

}


const userTimeFormat = await getUserTimeFormat();

const { DateTime } = window.luxon;

// Store the original toLocaleString method

const originalToLocaleString = DateTime.prototype.toLocaleString;

// Replace it with our own implementation

DateTime.prototype.toLocaleString = function(formatOpts, opts = {}) {

// Check if formatOpts is an object with time components

if (formatOpts && typeof formatOpts === 'object') {

const hasTimeComponents = formatOpts.hour !== undefined ||

formatOpts.minute !== undefined ||

formatOpts.second !== undefined;

if (hasTimeComponents) {

// Create a copy of format options without time components

const dateOnlyFormatOpts = { ...formatOpts };

delete dateOnlyFormatOpts.hour;

delete dateOnlyFormatOpts.minute;

const userHasSeconds = dateOnlyFormatOpts.second !== undefined;

delete dateOnlyFormatOpts.second;

let result = '';

// Only format the date part if there are date components left

const hasDateComponents = Object.keys(dateOnlyFormatOpts).length > 0;

if (hasDateComponents) {

// Get date portion using original formatter with date-only options

const datePart = originalToLocaleString.call(this, dateOnlyFormatOpts, opts);

result = datePart;

}

// Format time using our custom formatter

const timePart = formatTimeAccordingToUserPreferences(this, userHasSeconds, userTimeFormat);

// Combine date and time parts

if (hasDateComponents) {

// Only add separator if we have both date and time

result += ', ' + timePart;

} else {

result = timePart;

}

return result;

}

}

// Handle predefined formats like DateTime.TIME_SIMPLE

else if (formatOpts === DateTime.TIME_SIMPLE ||

formatOpts === DateTime.TIME_WITH_SECONDS) {

// These are time-only formats, use our custom formatter

return formatTimeAccordingToUserPreferences(this, userHasSeconds, userTimeFormat);

}

else if (formatOpts === DateTime.DATETIME_SHORT ||

formatOpts === DateTime.DATETIME_MED) {

// These are combined date+time formats

// Split into date and time parts for separate formatting

// First get original result

const originalResult = originalToLocaleString.call(this, formatOpts, opts);

// Then try to extract date part

const parts = originalResult.split(/,\s*|\s+at\s+|\s+/);

if (parts.length > 1) {

const datePart = parts[0];

const timePart = formatTimeAccordingToUserPreferences(this, userHasSeconds, userTimeFormat);

return `${datePart} ${timePart}`;

}

}

// For non-time formats or predefined formats we don't handle,

// use the original implementation;

return originalToLocaleString.call(this, formatOpts, opts);

};


};


// Execute patch when DOM is ready

document.addEventListener('DOMContentLoaded', () => {

// Patch Luxon globally

patchLuxon();

});

Avatar
Abbandona
Risposta migliore

I guess you are using English(US) and custom time format. In that case it won`t affect the date+time format in Time-Off. 

Changing language to English (UK) solves problem.

Avatar
Abbandona
Autore

We are using Catalan and Spanish languages. The time format is the expected on the whole aplication.
However, on the Time Off app the time format is AM-PM.
It is the latter that we would like to change so that the time format is the same throughout Odoo.

This is just a workaround that works for us.
Good luck waiting help from odoo

Post correlati Risposte Visualizzazioni Attività
0
feb 25
668
0
lug 24
877
1
mag 24
2056
1
nov 23
1089
0
dic 21
3348