Skip to content

Instantly share code, notes, and snippets.

@saaj
Last active August 29, 2015 14:06
Show Gist options
  • Save saaj/0d6bb9b70964a1313cf5 to your computer and use it in GitHub Desktop.
Save saaj/0d6bb9b70964a1313cf5 to your computer and use it in GitHub Desktop.
Simplified LDML to POSIX datetime format converter
/**
* Simplified datetime format string converter from LDML (Locale Data Markup
* Language) aka CLDR (Unicode Common Locale Data Repository) format to POSIX
* aka strftime format.
*
* Main usecase is using complete localization from CLDR with D3, which
* implements POSIX style of date formatting.
*
* References:
* - http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
* - http://pubs.opengroup.org/onlinepubs/007908799/xsh/strftime.html
* - https://github.com/mbostock/d3/wiki/Time-Formatting#format
*
* @license LGPLv2.1+
* @author saaj
*/
var _ldmlToPosixMap = {
// 03.09.1985 04:09:06 -04:00
'y' : '%Y', // year: 1985
'yy' : '%y', // year: 85
'yyyy' : '%Y', // year: 1985
'M' : '%-m', // month: 9
'MM' : '%m', // month: 09
'MMM' : '%b', // month: Sept
'MMMM' : '%B', // month: September
'd' : '%e', // day: 3
'dd' : '%d', // day: 03
'D' : '%j', // day: 246
'EEEE' : '%A', // day: Tuesday
'h' : '%-I', // 12-hour: 4
'hh' : '%I', // 12-hour: 04
'H' : '%-H', // 24-hour: 4
'HH' : '%H', // 24-hour: 04
'm' : '%-M', // minute: 9
'mm' : '%M', // minute: 09
's' : '%-S', // second: 6
'ss' : '%S', // second: 06
'a' : '%p', // AM or PM: AM
'Z' : '%Z', // timezone: -0400
'z' : '%Z', // only possible is -0400
'zzzz' : '%Z' // only possible is -0400
};
function convertLdmlToPosix(format)
{
Object.keys(_ldmlToPosixMap)
.sort(function(a, b)
{
// replace longest first
return b.length - a.length;
})
.map(function(key)
{
// Python dict.items
return [key, _ldmlToPosixMap[key]];
})
.forEach(function(pair)
{
// avoid double replace, e.g. 'dd' -> '%d' -> '%%w'
var regex = new RegExp('(%-?)?' + pair[0], 'g');
format = format.replace(regex, function(match, percentGroup)
{
return percentGroup ? match : pair[1];
});
});
return format;
}
console.assert(convertLdmlToPosix('EEEE, MMMM d, y') == '%A, %B %e, %Y');
console.assert(convertLdmlToPosix('MMMM d, y') == '%B %e, %Y');
console.assert(convertLdmlToPosix('MMM d, y') == '%b %e, %Y');
console.assert(convertLdmlToPosix('M/d/yy') == '%-m/%e/%y');
console.assert(convertLdmlToPosix('h:mm:ss a Z') == '%-I:%M:%S %p %Z');
console.assert(convertLdmlToPosix('h:mm:ss a Z') == '%-I:%M:%S %p %Z');
console.assert(convertLdmlToPosix('h:mm:ss a') == '%-I:%M:%S %p');
console.assert(convertLdmlToPosix('h:mm a') == '%-I:%M %p');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment