wip(i18n): 改进 laydate 面板中的日期格式处理

pull/2698/head
sight 2025-07-11 13:31:51 +08:00
parent b103454951
commit 780b374a44
6 changed files with 97 additions and 16 deletions

View File

@ -41,9 +41,12 @@ i18n.set({
verifyErrorPromptTitle: '提示'
},
laydate: {
months: ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二'],
months: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
weeks: ['日', '一', '二', '三', '四', '五', '六'],
time: ['时', '分', '秒'],
literal: {
year: '年'
},
selectDate: '选择日期',
selectTime: '选择时间',
startTime: '开始时间',

View File

@ -44,6 +44,9 @@ export default {
months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
weeks: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
time: ['Hour', 'Minute', 'Second'],
literal: {
year: ''
},
selectDate: 'Select Date',
selectTime: 'Select Time',
startTime: 'Start Time',

View File

@ -43,6 +43,9 @@ export default {
months: ['Janv', 'Févr', 'Mars', 'Avr', 'Mai', 'Juin', 'Juil', 'Août', 'Sept', 'Oct', 'Nov', 'Déc'],
weeks: ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa'],
time: ['Heure', 'Minute', 'Seconde'],
literal: {
year: ''
},
selectDate: 'Sélec. date',
selectTime: 'Sélec. heure',
startTime: 'Heure de début',

View File

@ -40,9 +40,12 @@ export default {
verifyErrorPromptTitle: '提示'
},
laydate: {
months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
months: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
weeks: ['日', '一', '二', '三', '四', '五', '六'],
time: ['時', '分', '秒'],
literal: {
year: '年'
},
selectDate: '選擇日期',
selectTime: '選擇時間',
startTime: '開始時間',

View File

@ -53,9 +53,12 @@ layui.define('lay', function(exports) {
verifyErrorPromptTitle: '提示'
},
laydate: {
months: ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二'],
months: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
weeks: ['日', '一', '二', '三', '四', '五', '六'],
time: ['时', '分', '秒'],
literal: {
year: '年'
},
selectDate: '选择日期',
selectTime: '选择时间',
startTime: '开始时间',
@ -263,6 +266,10 @@ layui.define('lay', function(exports) {
return value
}
function isDef(value) {
return value !== null && value !== undefined;
}
var resolveValue = memoize(function(path, obj, defaultValue){
var pathParts = path.split(':');
var locale = pathParts[0];
@ -273,7 +280,7 @@ layui.define('lay', function(exports) {
if (layui.cache.debug) {
var isFallback = defaultValue === value || value === path;
var isNotFound = !value || isFallback;
var isNotFound = !isDef(value) || isFallback;
if (isNotFound) {
hint.errorOnce("Not found '" + path + "' key in '" + locale + "' locale messages.", 'warn');
}
@ -282,7 +289,7 @@ layui.define('lay', function(exports) {
}
}
return value || path;
return isDef(value) ? value : path;
});
var i18n = {
@ -321,7 +328,7 @@ layui.define('lay', function(exports) {
var locale = (options && options.locale) || config.locale;
var i18nMessages = config.messages[locale];
var namespace = locale + ':';
var fallbackMessage = options && options.default;
var fallbackMessage = (options && lay.hasOwn(options, 'default')) ? options.default : undefined;
if (!i18nMessages) {
hint.errorOnce("Locale '" + locale + "' not found. Please add i18n messages for this locale first.", 'error');

View File

@ -13,6 +13,39 @@ layui.define(['lay', 'i18n'], function(exports) {
var MOD_NAME = 'laydate';
var MOD_ID = 'lay-' + MOD_NAME + '-id'; // 已渲染过的索引标记名
var zhCN = 'zh-CN'; // 简体中文语言码
var YearBeforeMonthLocale = ['eu-ES', 'ja-JP', 'km-KH', 'ko-KR', 'pt-BR', 'si-LK', 'ms-MY', 'ug-CN', 'zh-CN', 'zh-HK', 'zh-TW']; // 年份在前的语言
function addSpaceBetweenChars(str) {
if (typeof str !== 'string' || str.length <= 1) {
return str;
}
let result = '';
for (let i = 0; i < str.length - 1; i++) {
var char = str[i];
var nextChar = str[i + 1];
result += char;
// 判断当前字符和下一个字符的类型
var isCharDigit = isDigit(char);
var isNextCharDigit = isDigit(nextChar);
// 在数字和非数字(非空格)之间添加空格
if (
(isCharDigit && !isNextCharDigit && nextChar !== ' ') || // 数字 → 非数字(非空格)
(char !== ' ' && !isCharDigit && isNextCharDigit) // 非空格非数字 → 数字
) {
result += ' ';
}
}
result += str[str.length - 1]; // 添加最后一个字符
return result;
}
function isDigit(char) {
var code = char.charCodeAt(0);
return code >= 48 && code <= 57; // '0' 到 '9' 的 ASCII 码范围
}
// 外部调用
var laydate = {
@ -114,6 +147,24 @@ layui.define(['lay', 'i18n'], function(exports) {
// 更新 i18n 消息对象
that.i18nMessages = that.getI18nMessages();
// 处理日期面板顶部年月顺序
// 这是一个变通的方法,因为 i18nMessages.monthBeforeYear 不存在
if(typeof that.i18nMessages.monthBeforeYear !== 'boolean'){
if(!window.Intl){
that.i18nMessages.monthBeforeYear = !(YearBeforeMonthLocale.indexOf(options.lang) > -1);
}else{
var formatter = new Intl.DateTimeFormat(options.lang, { year: 'numeric', month: 'short' });
var parts = formatter.formatToParts(new Date(1970, 0));
var order = [];
parts.map(function(part) {
if (part.type === 'year' || part.type === 'month') {
order.push(part.type);
}
})
that.i18nMessages.monthBeforeYear = order[0] === 'month';
}
}
// 若重复执行 render则视为 reload 处理
if(elem[0] && elem.attr(MOD_ID)){
var newThat = thisModule.getThis(elem.attr(MOD_ID));
@ -206,6 +257,15 @@ layui.define(['lay', 'i18n'], function(exports) {
locale: locale,
default: ['Hour', 'Minute', 'Second']
}),
literal: {
year: i18n.$t('laydate.literal.year', null, {
locale: locale,
default: ''
})
},
monthBeforeYear: i18n.$t('laydate.monthBeforeYear', null, {
locale: locale
}),
selectDate: i18n.$t('laydate.selectDate', null, {
locale: locale,
default: 'Select Date'
@ -1539,12 +1599,14 @@ layui.define(['lay', 'i18n'], function(exports) {
if(!that.panelYM) that.panelYM = {};
that.panelYM[index] = {year: dateTime.year, month: dateTime.month};
if(options.lang === zhCN){
lay(elemYM[0]).attr('lay-type', 'year').html(dateTime.year + ' 年')
lay(elemYM[1]).attr('lay-type', 'month').html((dateTime.month + 1) + ' 月');
var normalizedYearStr = addSpaceBetweenChars(dateTime.year + lang.literal.year);
var normalizedMonthStr = addSpaceBetweenChars(lang.months[dateTime.month]);
if(!lang.monthBeforeYear){
lay(elemYM[0]).attr('lay-type', 'year').html(normalizedYearStr);
lay(elemYM[1]).attr('lay-type', 'month').html(normalizedMonthStr);
} else {
lay(elemYM[0]).attr('lay-type', 'month').html(lang.months[dateTime.month]);
lay(elemYM[1]).attr('lay-type', 'year').html(dateTime.year);
lay(elemYM[0]).attr('lay-type', 'month').html(normalizedMonthStr);
lay(elemYM[1]).attr('lay-type', 'year').html(normalizedYearStr);
}
//初始默认选择器
@ -1636,8 +1698,8 @@ layui.define(['lay', 'i18n'], function(exports) {
,elemYM = lay(elemHeader[2]).find('span')
,elemCont = that.elemCont[index || 0]
,haveList = lay(elemCont).find('.'+ ELEM_LIST)[0]
,isCN = options.lang === zhCN
,text = isCN ? '年' : ''
,isMonthBeforeYear = lang.monthBeforeYear
,text = lang.literal.year
,listYM = that.listYM[index] || {}
,hms = ['hours', 'minutes', 'seconds']
@ -1685,7 +1747,7 @@ layui.define(['lay', 'i18n'], function(exports) {
yearNum++;
});
lay(elemYM[isCN ? 0 : 1]).attr('lay-ym', (yearNum - 8) + '-' + listYM[1])
lay(elemYM[!isMonthBeforeYear ? 0 : 1]).attr('lay-ym', (yearNum - 8) + '-' + listYM[1])
.html((startY + text) + ' - ' + (yearNum - 1 + text));
}
@ -1702,7 +1764,7 @@ layui.define(['lay', 'i18n'], function(exports) {
};
i + 1 == listYM[1] && lay(li).addClass(THIS);
li.innerHTML = lang.months[i] + (isCN ? '月' : '');
li.innerHTML = lang.months[i];
ul.appendChild(li);
/*
@ -1724,7 +1786,7 @@ layui.define(['lay', 'i18n'], function(exports) {
that.cellRender(li, {year: listYM[0], month: i + 1, date: 1}, 'month');
});
lay(elemYM[isCN ? 0 : 1]).attr('lay-ym', listYM[0] + '-' + listYM[1])
lay(elemYM[!isMonthBeforeYear ? 0 : 1]).attr('lay-ym', listYM[0] + '-' + listYM[1])
.html(listYM[0] + text);
}