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?
Odoo is the world's easiest all-in-one management software.
It includes hundreds of business apps:
- CRM
- e-Commerce
- Contabilità
- Magazzino
- PoS
- Project
- MRP
La domanda è stata contrassegnata
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();
});
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.
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
Ti stai godendo la conversazione? Non leggere soltanto, partecipa anche tu!
Crea un account oggi per scoprire funzionalità esclusive ed entrare a far parte della nostra fantastica community!
RegistratiPost correlati | Risposte | Visualizzazioni | Attività | |
---|---|---|---|---|
|
0
feb 25
|
668 | ||
|
0
lug 24
|
877 | ||
|
1
mag 24
|
2056 | ||
|
1
nov 23
|
1089 | ||
|
0
dic 21
|
3348 |