Support localized AM/PM markers.

This commit is contained in:
Jun Omae 2011-08-11 14:43:48 +09:00
parent 04efa5859c
commit cb98a45fd6
19 changed files with 103 additions and 41 deletions

View file

@ -32,6 +32,8 @@ function Timepicker() {
currentText: 'Now', currentText: 'Now',
closeText: 'Done', closeText: 'Done',
ampm: false, ampm: false,
amNames: ['AM', 'A'],
pmNames: ['PM', 'P'],
timeFormat: 'hh:mm tt', timeFormat: 'hh:mm tt',
timeSuffix: '', timeSuffix: '',
timeOnlyTitle: 'Choose Time', timeOnlyTitle: 'Choose Time',
@ -163,6 +165,8 @@ $.extend(Timepicker.prototype, {
}, },
timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker'); timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');
}); });
tp_inst.amNames = $.map(tp_inst._defaults.amNames, function(val) { return val.toUpperCase() });
tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function(val) { return val.toUpperCase() });
tp_inst.hour = tp_inst._defaults.hour; tp_inst.hour = tp_inst._defaults.hour;
tp_inst.minute = tp_inst._defaults.minute; tp_inst.minute = tp_inst._defaults.minute;
@ -219,10 +223,11 @@ $.extend(Timepicker.prototype, {
.replace(/m{1,2}/ig, '(\\d?\\d)') .replace(/m{1,2}/ig, '(\\d?\\d)')
.replace(/s{1,2}/ig, '(\\d?\\d)') .replace(/s{1,2}/ig, '(\\d?\\d)')
.replace(/l{1}/ig, '(\\d?\\d?\\d)') .replace(/l{1}/ig, '(\\d?\\d?\\d)')
.replace(/t{1,2}/ig, '(am|pm|a|p)?') .replace(/t{1,2}/ig, this._getPatternAmpm())
.replace(/z{1}/ig, '((\\+|-)\\d\\d\\d\\d)?') .replace(/z{1}/ig, '((\\+|-)\\d\\d\\d\\d)?')
.replace(/\s/g, '\\s?') + this._defaults.timeSuffix + '$', .replace(/\s/g, '\\s?') + this._defaults.timeSuffix + '$',
order = this._getFormatPositions(), order = this._getFormatPositions(),
ampm = '',
treg; treg;
if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]); if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]);
@ -239,15 +244,20 @@ $.extend(Timepicker.prototype, {
treg = timeString.match(new RegExp(regstr, 'i')); treg = timeString.match(new RegExp(regstr, 'i'));
if (treg) { if (treg) {
if (order.t !== -1) if (order.t !== -1) {
this.ampm = ((treg[order.t] === undefined || treg[order.t].length === 0) ? if (treg[order.t] === undefined || treg[order.t].length === 0) {
'' : ampm = '';
(treg[order.t].charAt(0).toUpperCase() == 'A') ? 'AM' : 'PM').toUpperCase(); this.ampm = '';
} else {
ampm = $.inArray(treg[order.t].toUpperCase(), this.amNames) !== -1 ? 'AM' : 'PM';
this.ampm = this._defaults[ampm == 'AM' ? 'amNames' : 'pmNames'][0];
}
}
if (order.h !== -1) { if (order.h !== -1) {
if (this.ampm == 'AM' && treg[order.h] == '12') if (ampm == 'AM' && treg[order.h] == '12')
this.hour = 0; // 12am = 0 hour this.hour = 0; // 12am = 0 hour
else if (this.ampm == 'PM' && treg[order.h] != '12') else if (ampm == 'PM' && treg[order.h] != '12')
this.hour = (parseFloat(treg[order.h]) + 12).toFixed(0); // 12pm = 12 hour, any other pm = hour + 12 this.hour = (parseFloat(treg[order.h]) + 12).toFixed(0); // 12pm = 12 hour, any other pm = hour + 12
else this.hour = Number(treg[order.h]); else this.hour = Number(treg[order.h]);
} }
@ -263,6 +273,20 @@ $.extend(Timepicker.prototype, {
return false; return false;
}, },
//########################################################################
// pattern for standard and localized AM/PM markers
//########################################################################
_getPatternAmpm: function() {
var markers = [];
o = this._defaults;
if (o.amNames)
$.merge(markers, o.amNames);
if (o.pmNames)
$.merge(markers, o.pmNames);
markers = $.map(markers, function(val) { return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&') });
return '(' + markers.join('|') + ')?';
},
//######################################################################## //########################################################################
// figure out position of time elements.. cause js cant do named captures // figure out position of time elements.. cause js cant do named captures
//######################################################################## //########################################################################
@ -706,7 +730,8 @@ $.extend(Timepicker.prototype, {
minute = (this.minute_slider) ? this.minute_slider.slider('value') : false, minute = (this.minute_slider) ? this.minute_slider.slider('value') : false,
second = (this.second_slider) ? this.second_slider.slider('value') : false, second = (this.second_slider) ? this.second_slider.slider('value') : false,
millisec = (this.millisec_slider) ? this.millisec_slider.slider('value') : false, millisec = (this.millisec_slider) ? this.millisec_slider.slider('value') : false,
timezone = (this.timezone_select) ? this.timezone_select.val() : false; timezone = (this.timezone_select) ? this.timezone_select.val() : false,
o = this._defaults;
if (typeof(hour) == 'object') hour = false; if (typeof(hour) == 'object') hour = false;
if (typeof(minute) == 'object') minute = false; if (typeof(minute) == 'object') minute = false;
@ -719,11 +744,15 @@ $.extend(Timepicker.prototype, {
if (second !== false) second = parseInt(second,10); if (second !== false) second = parseInt(second,10);
if (millisec !== false) millisec = parseInt(millisec,10); if (millisec !== false) millisec = parseInt(millisec,10);
var ampm = (hour < 12) ? 'AM' : 'PM'; var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0];
// If the update was done in the input field, the input field should not be updated. // If the update was done in the input field, the input field should not be updated.
// If the update was done using the sliders, update the input field. // If the update was done using the sliders, update the input field.
var hasChanged = (hour != this.hour || minute != this.minute || second != this.second || millisec != this.millisec || (this.ampm.length > 0 && this.ampm != ampm) || timezone != this.timezone); var hasChanged = (hour != this.hour || minute != this.minute
|| second != this.second || millisec != this.millisec
|| (this.ampm.length > 0
&& (hour < 12) != ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1))
|| timezone != this.timezone);
if (hasChanged) { if (hasChanged) {
@ -737,10 +766,10 @@ $.extend(Timepicker.prototype, {
this._limitMinMaxDateTime(this.inst, true); this._limitMinMaxDateTime(this.inst, true);
} }
if (this._defaults.ampm) this.ampm = ampm; if (o.ampm) this.ampm = ampm;
this._formatTime(); this._formatTime();
if (this.$timeObj) this.$timeObj.text(this.formattedTime + this._defaults.timeSuffix); if (this.$timeObj) this.$timeObj.text(this.formattedTime + o.timeSuffix);
this.timeDefined = true; this.timeDefined = true;
if (hasChanged) this._updateDateTime(); if (hasChanged) this._updateDateTime();
}, },
@ -763,38 +792,35 @@ $.extend(Timepicker.prototype, {
_formatTime: function(time, format, ampm) { _formatTime: function(time, format, ampm) {
if (ampm == undefined) ampm = this._defaults.ampm; if (ampm == undefined) ampm = this._defaults.ampm;
time = time || { hour: this.hour, minute: this.minute, second: this.second, millisec: this.millisec, ampm: this.ampm, timezone: this.timezone }; time = time || { hour: this.hour, minute: this.minute, second: this.second, millisec: this.millisec, ampm: this.ampm, timezone: this.timezone };
var tmptime = format || this._defaults.timeFormat.toString(); var tmptime = (format || this._defaults.timeFormat).toString();
var hour = parseInt(time.hour, 10);
if (ampm) { if (ampm) {
var hour12 = ((time.ampm == 'AM') ? (time.hour) : (time.hour % 12)); if (!$.inArray(time.ampm.toUpperCase(), this.amNames) !== -1)
hour12 = (Number(hour12) === 0) ? 12 : hour12; hour = hour % 12;
tmptime = tmptime.toString() if (hour === 0)
.replace(/hh/g, ((hour12 < 10) ? '0' : '') + hour12) hour = 12;
.replace(/h/g, hour12)
.replace(/mm/g, ((time.minute < 10) ? '0' : '') + time.minute)
.replace(/m/g, time.minute)
.replace(/ss/g, ((time.second < 10) ? '0' : '') + time.second)
.replace(/s/g, time.second)
.replace(/l/g, ((time.millisec < 10) ? '00' : (time.millisec < 100) ? '0': '') + time.millisec)
.replace(/TT/g, time.ampm.toUpperCase())
.replace(/Tt/g, time.ampm.toUpperCase())
.replace(/tT/g, time.ampm.toLowerCase())
.replace(/tt/g, time.ampm.toLowerCase())
.replace(/T/g, time.ampm.charAt(0).toUpperCase())
.replace(/t/g, time.ampm.charAt(0).toLowerCase())
.replace(/z/g, time.timezone);
} else {
tmptime = tmptime.toString()
.replace(/hh/g, ((time.hour < 10) ? '0' : '') + time.hour)
.replace(/h/g, time.hour)
.replace(/mm/g, ((time.minute < 10) ? '0' : '') + time.minute)
.replace(/m/g, time.minute)
.replace(/ss/g, ((time.second < 10) ? '0' : '') + time.second)
.replace(/s/g, time.second)
.replace(/l/g, ((time.millisec < 10) ? '00' : (time.millisec < 100) ? '0': '') + time.millisec)
.replace(/z/g, time.timezone);
tmptime = $.trim(tmptime.replace(/t/gi, ''));
} }
tmptime = tmptime.replace(/(?:hh?|mm?|ss?|[tT]{1,2}|[lz])/g, function(match) {
switch (match.toLowerCase()) {
case 'hh': return ('0' + hour).slice(-2);
case 'h': return hour;
case 'mm': return ('0' + time.minute).slice(-2);
case 'm': return time.minute;
case 'ss': return ('0' + time.second).slice(-2);
case 's': return time.second;
case 'l': return ('00' + time.millisec).slice(-3);
case 'z': return time.timezone;
case 't': case 'tt':
if (ampm) {
var _ampm = time.ampm;
if (match.length == 1)
_ampm = _ampm.charAt(0);
return match.charAt(0) == 'T' ? _ampm.toUpperCase() : _ampm.toLowerCase();
}
return '';
}
});
if (arguments.length) return tmptime; if (arguments.length) return tmptime;
else this.formattedTime = tmptime; else this.formattedTime = tmptime;

View file

@ -12,6 +12,8 @@
currentText: 'Ara', currentText: 'Ara',
closeText: 'Tancar', closeText: 'Tancar',
timeFormat: 'hh:mm', timeFormat: 'hh:mm',
amNames: ['AM', 'A'],
pmNames: ['PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['ca']); $.timepicker.setDefaults($.timepicker.regional['ca']);

View file

@ -12,6 +12,8 @@
currentText: 'Nyní', currentText: 'Nyní',
closeText: 'Zavřít', closeText: 'Zavřít',
timeFormat: 'h:m', timeFormat: 'h:m',
amNames: ['dop.', 'AM', 'A'],
pmNames: ['odp.', 'PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['cs']); $.timepicker.setDefaults($.timepicker.regional['cs']);

View file

@ -12,6 +12,8 @@
currentText: 'Jetzt', currentText: 'Jetzt',
closeText: 'Fertig', closeText: 'Fertig',
timeFormat: 'hh:mm tt', timeFormat: 'hh:mm tt',
amNames: ['vorm.', 'AM', 'A'],
pmNames: ['nachm.', 'PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['de']); $.timepicker.setDefaults($.timepicker.regional['de']);

View file

@ -12,6 +12,8 @@
currentText: 'Τώρα', currentText: 'Τώρα',
closeText: 'Κλείσιμο', closeText: 'Κλείσιμο',
timeFormat: 'hh:mm', timeFormat: 'hh:mm',
amNames: ['π.μ.', 'AM', 'A'],
pmNames: ['μ.μ.', 'PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['el']); $.timepicker.setDefaults($.timepicker.regional['el']);

View file

@ -12,6 +12,8 @@
currentText: 'Ahora', currentText: 'Ahora',
closeText: 'Cerrar', closeText: 'Cerrar',
timeFormat: 'hh:mm', timeFormat: 'hh:mm',
amNames: ['a.m.', 'AM', 'A'],
pmNames: ['p.m.', 'PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['es']); $.timepicker.setDefaults($.timepicker.regional['es']);

View file

@ -12,6 +12,8 @@
currentText: 'Praegu', currentText: 'Praegu',
closeText: 'Valmis', closeText: 'Valmis',
timeFormat: 'hh:mm tt', timeFormat: 'hh:mm tt',
amNames: ['AM', 'A'],
pmNames: ['PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['et']); $.timepicker.setDefaults($.timepicker.regional['et']);

View file

@ -12,6 +12,8 @@
currentText: 'Maintenant', currentText: 'Maintenant',
closeText: 'Terminé', closeText: 'Terminé',
timeFormat: 'hh:mm', timeFormat: 'hh:mm',
amNames: ['AM', 'A'],
pmNames: ['PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['fr']); $.timepicker.setDefaults($.timepicker.regional['fr']);

View file

@ -12,6 +12,8 @@
currentText: "עכשיו", currentText: "עכשיו",
closeText:"סגור", closeText:"סגור",
timeFormat: "hh:mm tt", timeFormat: "hh:mm tt",
amNames: ['לפנה"צ', AM', 'A'],
pmNames: ['אחה"צ', PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional["he"]); $.timepicker.setDefaults($.timepicker.regional["he"]);

View file

@ -12,6 +12,8 @@
currentText: 'Most', currentText: 'Most',
closeText: 'Kész', closeText: 'Kész',
timeFormat: 'hh:mm tt', timeFormat: 'hh:mm tt',
amNames: ['de.', 'AM', 'A'],
pmNames: ['du.', 'PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['hu']); $.timepicker.setDefaults($.timepicker.regional['hu']);

View file

@ -12,6 +12,8 @@
currentText: 'Sekarang', currentText: 'Sekarang',
closeText: 'OK', closeText: 'OK',
timeFormat: 'hh:mm tt', timeFormat: 'hh:mm tt',
amNames: ['AM', 'A'],
pmNames: ['PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['id']); $.timepicker.setDefaults($.timepicker.regional['id']);

View file

@ -12,6 +12,8 @@
currentText: 'Adesso', currentText: 'Adesso',
closeText: 'Chiudi', closeText: 'Chiudi',
timeFormat: 'hh:mm', timeFormat: 'hh:mm',
amNames: ['m.', 'AM', 'A'],
pmNames: ['p.', 'PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['it']); $.timepicker.setDefaults($.timepicker.regional['it']);

View file

@ -12,6 +12,8 @@
currentText: '現時刻', currentText: '現時刻',
closeText: '閉じる', closeText: '閉じる',
timeFormat: 'hh:mm tt', timeFormat: 'hh:mm tt',
amNames: ['午前', 'AM', 'A'],
pmNames: ['午後', 'PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['ja']); $.timepicker.setDefaults($.timepicker.regional['ja']);

View file

@ -12,6 +12,8 @@
currentText: 'Dabar', currentText: 'Dabar',
closeText: 'Uždaryti', closeText: 'Uždaryti',
timeFormat: 'hh:mm', timeFormat: 'hh:mm',
amNames: ['priešpiet', 'AM', 'A'],
pmNames: ['popiet', 'PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['lt']); $.timepicker.setDefaults($.timepicker.regional['lt']);

View file

@ -12,6 +12,8 @@
currentText: 'Vandaag', currentText: 'Vandaag',
closeText: 'Sluiten', closeText: 'Sluiten',
timeFormat: 'hh:mm tt', timeFormat: 'hh:mm tt',
amNames: ['AM', 'A'],
pmNames: ['PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['nl']); $.timepicker.setDefaults($.timepicker.regional['nl']);

View file

@ -12,6 +12,8 @@
currentText: 'Acum', currentText: 'Acum',
closeText: 'Închide', closeText: 'Închide',
timeFormat: 'hh:mm', timeFormat: 'hh:mm',
amNames: ['AM', 'A'],
pmNames: ['PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['ro']); $.timepicker.setDefaults($.timepicker.regional['ro']);

View file

@ -12,6 +12,8 @@
currentText: 'Теперь', currentText: 'Теперь',
closeText: 'Закрыть', closeText: 'Закрыть',
timeFormat: 'hh:mm tt', timeFormat: 'hh:mm tt',
amNames: ['AM', 'A'],
pmNames: ['PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['ru']); $.timepicker.setDefaults($.timepicker.regional['ru']);

View file

@ -12,6 +12,8 @@
currentText: 'Şu an', currentText: 'Şu an',
closeText: 'Tamam', closeText: 'Tamam',
timeFormat: 'hh:mm', timeFormat: 'hh:mm',
amNames: ['AM', 'A'],
pmNames: ['PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['tr']); $.timepicker.setDefaults($.timepicker.regional['tr']);

View file

@ -12,6 +12,8 @@
currentText: 'Hiện thời', currentText: 'Hiện thời',
closeText: 'Đóng' closeText: 'Đóng'
timeFormat: 'h:m', timeFormat: 'h:m',
amNames: ['SA', 'AM', 'A'],
pmNames: ['CH', 'PM', 'P'],
ampm: false ampm: false
}; };
$.timepicker.setDefaults($.timepicker.regional['vi']); $.timepicker.setDefaults($.timepicker.regional['vi']);