Last active
August 29, 2015 14:06
-
-
Save saaj/0d6bb9b70964a1313cf5 to your computer and use it in GitHub Desktop.
Simplified LDML to POSIX datetime format converter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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