Pretty simple question: I want to add a switch to my globalize format skeleton, so that it adds an "o'clock" or German "Uhr" after the time. Right now, I'm using the following pattern:
yMMddHHmm
I found the o'clock string in the respective cldr files, but I don't know how to add them to the skeleton.
Here's my code:
Globalize.formatDate(dTermin, { skeleton: 'yMMddHHmm' });
Thank you in advance for your help!
There's no skeleton that would give you "o'clock" kinda output [1]. Although, if you really want that format and are willing to provide the i18n data for all the locales you think could support it you can use globalize's raw option like:
// Not recommended anyway...
if (locale === "en") {
formatter = globalize.dateFormatter({raw: "HH 'o''clock'"});
}
Though, it's usually a not recommended approach since you have to maintain this list of custom formatters yourself.
1: In order to check, I've grep'ed the whole CLDR and found no match.
Related
I'm trying to use the new Javascript internationalization API, and would like to know if there is a way to get the decimal and thousands (grouping) separator for a Intl.NumberFormat instance?
There is a resolvedOptions method on the object, but that does not provide the symbols.
In case anybody's wondering, then for en-US, these would be a comma , and period ., such as in 1,000.00.
If nothing else, as a trick solution (that doesn't pass the Turkey Test; see comment), you can use the output of toLocaleString() to determine information about number formatting in a locale. For the current locale, for example:
var decimalSeparator =
(12345.6789).toLocaleString().match(/345(.*)67/)[1];
var thousandSeparator =
(12345.6789).toLocaleString().match(/12(.*)345/)[1];
var numberOfDecimals =
(12345.6789).toLocaleString().match(/345(\D*)(\d+)$/)[2].length;
The same trick can be used for currency formatting, using e.g. (12345.6789).toLocaleString("en-GB", { style: "currency" }).
I'm afraid ECMA-402 standard does not define the API that let you access separators. There is also another problem - at the moment the adoption of ECMA-402 is not as wide as we wish.
Therefore for the time being, if I were you I would look to something like CLDR JSON bindings or iLib which apparently provides these information through LocaleInfo's getDecimalSeparator() and getGroupingSeparator() functions.
BTW. iLib seems to use CLDR as a source of information.
I'd like to use the JavaScript toLocaleUpperCase() method to make sure that the capitalization works correctly for the Turkish language. I cannot be sure, however, that Turkish will be set as the user's locale.
Is there a way in modern browsers to set the locale in run time, if I know for sure that the string is in Turkish?
(I ran into this problem while thinking about Turkish, but actually it can be any other language.)
There isn't really anything much out there but I came across this JavaScript setlocale function script that you might find useful.
You unfortunately cannot set locale during runtime. All hope is not lost though, there are many good libraries on npm for you to use. Check out https://www.npmjs.com/package/upper-case and https://www.npmjs.com/package/lower-case for example, it will work for many other languages too.
If that's too much, you can roll your own simple library:
var ALL_LETTERS_LOWERCASE = 'abcçdefgğhıijklmnoöprsştuüvyz';
var ALL_LETTERS_UPPERCASE = 'ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ';
function toLowerCaseLetter(letter) {
letter_index = ALL_LETTERS_UPPERCASE.indexOf(letter);
return ALL_LETTERS_LOWERCASE[letter_index];
}
function toLowerCase(my_str) {
var lower_cased = ''
for (letter of my_str) {
lower_cased += toLowerCaseLetter(letter);
}
return lower_cased;
}
console.log(toLowerCase('ÇDEFGĞHIİJKLMNOÖPRSŞTUÜ'))
Very similar for upper case version.
This option may not have existed back in 2013 but may help new visitors on this topic:
According to MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase) the function toLocaleUpperCase takes an optional parameter 'locale'.
Setting the right language tag is a topic on its own (https://www.w3.org/International/articles/language-tags/). Simplest example looks like this
'selam dünya'.toLocaleUpperCase('tr'); // SELAM DÜNYA
The below answer to another thread seems to make a start on what I think I need, but I am having difficulties in implementing it.
The best library for that purpose would probably be Globalize. It
allows you to specify the locale (it is called culture but it is
actually the same), the format (built-in or your own) and actually
parse string to given date:
var dateString = "lunes, 29 de agosto de 2011"; // seems like long
date format in Spanish var date = Globalize.parseDate( dateString,
"D", "es" );
You would need to attach appropriate culture file as well as reference
to Globalize to make it work. Please mind that cultures are already
defined in the library, so don't be afraid of the message on the web
page, you actually don't need .Net.
If someone could turn this into a working example I could then take this and adjust to what I need.
However ... does anyone know of an alternative method?
My string for example is:
"Set 24, 2012 20:40:20" which has the month in Romanian.
I need it to be
"Sep 24, 2012 20:40:20" which has the month in English.
I need a solution that can take the language code (ie en, es, pl, ru, ro etc) and convert the month in the string (needs to be able to handle all 12 months, not just the one in the above string) from the foreign language to English.
Any speedy help would be most appreciated so that I can get my site back up and running at full speed again.
If you require any further information from me please ask :)
Regards
Ross
#Jukka K. Korpela
I have this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Testing Globalize</title>
<meta name="keywords" content="Globalize, Testing">
<meta name="description" content="Trying to get globalize to work.">
<script src="https://github.com/jquery/globalize/blob/master/lib/globalize.js"></script>
<script src="https://github.com/jquery/globalize/blob/master/lib/cultures/globalize.cultures.js"></script>
<script>
var monthString = 'sep'; // replace by code that extracts the string
var lang = 'ro'; // replace by code that picks up the right language
var month = Globalize.parseDate(monthString, 'MMM', lang);
if(month) {
document.write(Globalize.format(month, 'MMM', 'en'));
} else {
alert('Unrecognized month: ' + monthString);
}
</script>
</head>
But it doesnt work when I test in "http://htmledit.squarefree.com/" please help :)
I think u could use datejs for your purpose.
It is capable of parsing your date data in any language available (150+ as the state) via a culturefile and then save it in english or any other language you desire.
Have a look : http://code.google.com/p/datejs/
The way to do such things in Globalize.js is to read the string using one locale, write it using another locale. You need to check the success of reading by some test that checks against null value (since this value signals an error). Like this:
<script src="globalize.js"></script>
<script src="globalize.cultures.js"></script>
<script>
var monthString = 'sep.'; // replace by code that extracts the string
var lang = 'ro'; // replace by code that picks up the right language
var month = Globalize.parseDate(monthString, 'MMM', lang);
if(month) {
document.write(Globalize.format(month, 'MMM', 'en'));
} else {
alert('Unrecognized month: ' + monthString);
}
This parses just the month abbreviation, or “short name” of month.
The problem is with the variation inside cultures. For example, for Romanian language, the short name of September is “sep.” in Globalize.js data (mainly based on .NET data; Datejs is probably based on the same data here) but “sept.” in CLDR data, and your example mentions “Set”!
Globalize.js reads names case-insensitively, but otherwise it uses the exact string in its locale definitions (e.g., “sep” won’t do if the definition says “sep.”). There are various ways around this. At the simplest, edit the locale definitions in Globalize.js to match those used in your data. Alternatively, you can create an alternate locale (a variant) with different month names and parse the name using it if it does not parse according to the basic locale. So this is a way to allow, on input, different sets of month names for a language.
Of course, if it’s only a matter of mapping short month names from different languages into English, you could simply write the code for it directly. But you would still need to get the names into your objects from somewhere – from .NET, from CLDR, or from your actual data.
I've stumble upon this difficulty back in 2013, and did work on a small utility to address the problem.
I published my v3 yesterday : https://framagit.org/Siltaar/month_nb
It supports 69 languages, and you don't have to know the language of your month name to get it's number. It's based on a re-usable standalone JSON tree structure for the data and a small tree-walking loop to find the results.
To use it, simply include both the data and the tree-walker files in a web page :
<script src="month_nb_json.js" type="text/javascript"></script>
<script src="month_nb.js" type="text/javascript"></script>
Then you'll be able to use it :
>> month_nb('août');
8
It's part of my Meta-Press.es project, which got some funding and that I'll continue to work on for at least the next 6 years (started in 2013…).
Else, it exists https://github.com/datejs/Datejs which is a human contributed translation approach.
I'm using the excellent (but large) DateJS library to handle dates and times in my webapp. I just came across something that I'm not sure how to handle.
I want my users to be able to enter Time strings only, without a date, but they should be able to enter it in any manner they please. For instance:
5:00 pm
17:00
5:00pm
5:00p
5p
etc.
Using Date.parse(value) converts these strings into a full date, which is exactly what I want. However, it also allows the user to enter any other part of a date string, such as:
sat 5pm
1/1/2010 5pm
etc.
I'm trying to use DateJS to validate an input field for a time value. Something like:
function validateTime(value) {
return Date.parse(value) !== null;
}
Is there a way to use DateJS features to solve this? There are other SO questions that provide solutions, but if DateJS has a way to do this, I don't really want to add more custom code to my app to do this.
Shortly after asking my question, I discovered that Date.parseExact() can take an array of format strings. Somehow I'm missed that. I managed to get something working with the following code:
function validateTime(input) {
return Date.parseExact(input, [
"H:m",
"h:mt",
"h:m t",
"ht","h t"]) != null ||
Date.parseExact(input, [
"h:mtt",
"h:m tt",
"htt","h tt"]) != null;
};
Note that some formats don't seem to be able to be included together at the same time, which is why I split them into two separate parseExact() calls. In this case, I couldn't include any string that contained a single t in it with format strings that contained a double tt in it.
The additive approach seems cumbersome. Takes away the beauty of DateJS in my opinion. I needed the same solution and decided to just sneakily append the date in front of my input string before parsing with DateJS:
var parsed = Date.parse(Date.today().toString('M/d/yyyy') + ' ' + this.value);
if (parsed) {
alert(parsed.toString('h:mm tt'));
}
Now DateJS will not be sniffing around for any of its date-part parsing patterns, as you have already subbed it in.
Hope this helps someone!
I've recently abandoned mouse-driven, platform-specific GUI editors and committed entirely to vim. The experience so far has been fantastic, but I'm stuck when it comes to Javascript.
The ever-popular taglist utility (using Exuberant Ctags) has been great for everything but Javascript. With the language's overly-free form and structure, taglist could only pick up a handful of functions when I opened it up -- only those defined in the format:
function FUNCNAME (arg1, arg2) {
but no variables or function objects defined like:
var myFunc = function (arg1, arg2) {
So I googled a bit and found the following definition set for ctags, which I put in my ~/.ctags file:
--langdef=js
--langmap=js:.js
--regex-js=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*\{/\1/,object/
--regex-js=/([A-Za-z0-9._$()]+)[ \t]*[:=][ \t]*function[ \t]*\(/\1/,function/
--regex-js=/function[ \t]+([A-Za-z0-9._$]+)[ \t]*([^])])/\1/,function/
--regex-js=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*\[/\1/,array/
--regex-js=/([^= ]+)[ \t]*=[ \t]*[^""]'[^'']*/\1/,string/
--regex-js=/([^= ]+)[ \t]*=[ \t]*[^'']"[^""]*/\1/,string/
After that, running ctags from the command line was fantastic. It found every function and object that I needed it to find.
The problem is that the taglist.vim plugin isn't seeing those new results. When I open my javascript file in vim and hit :TlistToggle, I get the exact same meager handful of functions I got before. I hit 'u' to update the list, with no effect.
Digging into taglist.vim, I found this:
" java language
let s:tlist_def_java_settings = 'java;p:package;c:class;i:interface;' .
\ 'f:field;m:method'
" javascript language
let s:tlist_def_javascript_settings = 'javascript;f:function'
...which implies we're only looking at one specific kind of output from the ctags utility for javascript. Unfortunately, I'm not savvy enough with taglist or vim in general (yet) to discover what change I can make to get all those wonderful ctags command-line results to show up in vim.
Help appreciated!
Got it! I dove into the taglist.vim code for awhile, and this is what I found:
taglist.vim forces ctags to use the same filetype that vim is using. So even though the ~/.ctags snippet I found via google is assigning my much-needed definitions to the new "js" language and applying it to files that end in .js, taglist is forcing ctags into using the "JavaScript" filetype that vim is using -- which is built right into ctags already.
The solution is to change the ~/.ctags file from what I've posted above to this:
--regex-JavaScript=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*new[ \t]+Object\(/\1/o,object/
--regex-JavaScript=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*\{/\1/o,object/
--regex-JavaScript=/([A-Za-z0-9._$()]+)[ \t]*[:=][ \t]*function[ \t]*\(/\1/f,function/
--regex-JavaScript=/function[ \t]+([A-Za-z0-9._$]+)[ \t]*\([^\]\)]*\)/\1/f,function/
--regex-JavaScript=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*new[ \t]+Array\(/\1/a,array/
--regex-JavaScript=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*\[/\1/a,array/
--regex-JavaScript=/([^= ]+)[ \t]*=[ \t]*[^""]'[^'']*/\1/s,string/
--regex-JavaScript=/([^= ]+)[ \t]*=[ \t]*[^'']"[^""]*/\1/s,string/
which alters the pre-existing JavaScript language definition directly, rather than creating a new language definition within ctags. Now, when taglib forces vim's registered filetype, the new definitions are used. Also missing from the previously posted ~/.ctags lines was the "kind" letter that Al mentioned in his answer, so those are included in my updated version as well.
From there, drop the following into your ~/.vimrc to activate the new types:
let g:tlist_javascript_settings = 'javascript;s:string;a:array;o:object;f:function'
All-in-all, the new regex lines aren't perfect -- they'll definitely need some tweaking to avoid a lot of false positives, and it might be nice to separate out constants and such. But now, at least, I have the ability to do that :).
Edit: Added instructions on how to activate types without editing the plugin, and vastly improved the main ctags function regex to avoid some false-positives.
Edit 2: Added more array and object definitions to the ctags regex.
I ran into this post on a google search, and although your findings are excellent, I think we can improve them. This is the results of a bit of hacking on your solution:
.ctags
--regex-JavaScript=/^var[ \t]+([a-zA-Z0-9_$]+) = \[/\1/a,array/
--regex-JavaScript=/^var[ \t]+([a-zA-Z0-9_$]+) = \{/\1/o,object/
--regex-JavaScript=/^var[ \t]+([a-zA-Z0-9_$]+) = (^{^[)+/\1/r,var/
--regex-JavaScript=/^[ \t]*(this\.)?([A-Za-z0-9_$()]+)[ \t]*[:=][ \t]*function[ \t]*\(\)/\2/u,function/
--regex-JavaScript=/^[ \t]*function ([a-z0-9]+[A-Za-z0-9_]*)/\1/u,function/
--regex-JavaScript=/^[ \t]*([A-Za-z0-9]+)\.prototype\.([a-z0-9]+[A-Za-z0-9_]*)/\1 : \2/u,function/
--regex-JavaScript=/^[ \t]*function ([A-Z]+[A-Za-z0-9_]*)/\1/o,object/
.vimrc
let g:tlist_javascript_settings = 'javascript;r:var;s:string;a:array;o:object;u:function'
This gets rid of a few more false positives, and adds some more features in, as a tradeoff for getting rid of some of the more problematic regexes. I'll keep updating if I find I need more.
Edit: I've gotten everything working really nicely now; I feel like this result is solid. The only major deficiency is that it doesn't work on comma separated variable definitions. That seems particularly nasty. Maybe another day. :)
Note also that I changed the .vimrc. This isn't because I'm a freak; it's because somehow taglist or ctags or something has some default values set, and if you don't change it, then you get a lot of doubles where functions and vars are concerned, which really drives me insane (I pay super attention to detail.. :P )
Edit: More tweaks. It picks up on prototype function declarations now, and doesn't do some other stupid stuff.
The best-practice solution, which is also very new, neat and easy way to get JavaScript source-code browsing / tag-list in Vim, is using Mozilla's DoctorJS (formerly known as jsctags).
See my answer for this question for more info.
Enjoy. :)
I've not used javascript or taglist much, but looking through :help taglist-extend, it looks like your definitions (listed above) rename the javascript output to js, so you'll probably need something like (in your vimrc):
let tlist_js_settings = 'js;f:function;m:method'
This is assuming that the ctags 'kind' is 'f' for function and 'm' for method. Have a look at your tags file and see what the 'kind' column looks like. By way of example, my C code tags file includes this line:
ADC_CR1_AWDCH_0 .\LibraryModules\CMSIS\Headers\stm32f10x.h 2871;" d
This is a #define of a symbol ADC_CR1_AWDCH_0, which is in the listed file at line 2871. The 'd' is the ctags 'kind' for a defined name. Hopefully that will give you enough to get you going.
As an aside, I'm not sure whether the override will work correctly, so it might be worth naming your file 'myfile.mjs' and changing your langmap to js:.mjs until it's working properly. Then at least you'll know whether your problems are associated with misidentification of files or the actual parsing.
Hi thanks to Tom Frost for his question and research, I think there is a little problem with the 4th line regexp of your final answer:
--regex-JavaScript=/function[ \t]+([A-Za-z0-9._$]+)[ \t]*\([^\]\)]*\)/\1/f,function/
Doesn't worked for me, I pulled it a bit and now works ok:
--regex-JavaScript=/function[ \t]+([A-Za-z0-9._$]+)[ \t]*\([^\)]*\)/\1/f,function/
PD. The others answers' regexps posted here doesn't work at all at least for me :-?
To avoid duplicate entries from ctags' built in javascript support I define 'js' language as in original post and help taglist use ctags with it. I also make sure that tagnames are stripped from some less useful bits (quotes, "this.", ".prototype"). I don't use object/array/string/var regexps, but it's easy to combine my regexps with the other suggestions.
~/.ctags:
--langdef=js
--langmap=js:.js
--regex-js=/["']?(this\.)?([A-Za-z0-9_$]+)["']?((\.prototype)?(\.[A-Za-z0-9_$]+))?[ \t]*[:=][ \t]*function/\2\5/f,function/
--regex-js=/function[ \t]+([A-Za-z0-9_$]+)/\1/f,function/
~/.vimrc:
let g:tlist_javascript_settings = 'js;f:function'