Detecting Regional Settings (List Separator) from Web

Detecting regional settings (List Separator) from web

Here's a JavaScript solution that I just wrote based on the method shown here:

function getListSeparator() {
var list = ['a', 'b'], str;
if (list.toLocaleString) {
str = list.toLocaleString();
if (str.indexOf(';') > 0 && str.indexOf(',') == -1) {
return ';';
}
}
return ',';
}

The key is in the toLocaleString() method that uses the system list separator.

You could use JavaScript to get the list separator and set it in a cookie which you could then detect from your server.

I checked all the Windows Locales, and it seems that the default list separator is virtually always either ',' or ';'. For some locales the drop-down list in the Control Panel offers both options; for others it offers just ','. One locale, Divehi, has a strange character that I've not seen before as the list separator, and, for any locale, it is possible for the user to enter any string they want as the list separator.

Putting random strings as the separator in a CSV file sounds like trouble to me, so my function above will only return either a ';' or a '.', and it will only return a ';' if it can't find a ',' in the Array.toLocaleString string. I'm not entirely sure about whether array.toLocaleString has a format that's guaranteed across browsers, hence the indexOf checks rather than picking out a character at a specific index.

Using Array.toLocaleString to get the list separator works on IE6, IE7, and IE8, but unfortunately it doesn't seem to work on Firefox, Safari, Opera, and Chrome (or at least the versions of those browsers on my computer): they all seem to separate array items with a comma, irrespective of the Windows "list separator" setting.

Also worth noting that by default Excel seems to use the system "decimal separator" when it's parsing numbers out of CSV files. Yuk. So, if you're localizing the list separator you might want to localize the decimal separator too.

python csv list separator based on regional settings

Write an XLS file with xlwt.

Take 2: Use the locale module and some heuristics:

>>> import locale
>>> locale.setlocale(locale.LC_ALL, '') # set to user's locale, not "C"
'English_Australia.1252'
>>> dec_pt_chr = locale.localeconv()['decimal_point']
>>> if dec_pt_chr == ",":
... list_delimiter = ";"
... else:
... list_delimiter = ","
...
>>> print repr(dec_pt_chr), repr(list_delimiter)
'.' ','
>>> locale.setlocale(locale.LC_ALL, 'French_France.1252')
'French_France.1252'
>>> dec_pt_chr = locale.localeconv()['decimal_point']
>>> if dec_pt_chr == ",":
... list_delimiter = ";"
... else:
... list_delimiter = ","
...
>>> print repr(dec_pt_chr), repr(list_delimiter)
',' ';'
>>>

Get list separator character for any locale

I am not sure if my answer will satisfy your requirements but I suggest (especially as you don't want to change the locale on the server) to use a function that will give you the answer:

To my knowledge (and also Wikipedia's it seems) the list separator in a CSV is a comma unless the decimal point of the locale is a comma, in that case the list separator is a semicolon.

So you could get a list of all locales that use a comma (Unicode U+002C) as separator using this command:

cd /usr/share/i18n/locales/
grep decimal_point.*2C *_* -l

and you could then take this list to determine the appropriate list separator:

function get_csv_list_separator($locale) {
$locales_with_comma_separator = "az_AZ be_BY bg_BG bs_BA ca_ES crh_UA cs_CZ da_DK de_AT de_BE de_DE de_LU el_CY el_GR es_AR es_BO es_CL es_CO es_CR es_EC es_ES es_PY es_UY es_VE et_EE eu_ES eu_ES@euro ff_SN fi_FI fr_BE fr_CA fr_FR fr_LU gl_ES hr_HR ht_HT hu_HU id_ID is_IS it_IT ka_GE kk_KZ ky_KG lt_LT lv_LV mg_MG mk_MK mn_MN nb_NO nl_AW nl_NL nn_NO pap_AN pl_PL pt_BR pt_PT ro_RO ru_RU ru_UA rw_RW se_NO sk_SK sl_SI sq_AL sq_MK sr_ME sr_RS sr_RS@latin sv_SE tg_TJ tr_TR tt_RU@iqtelif uk_UA vi_VN wo_SN");
if (stripos($locales_with_comma_separator, $locale) !== false) {
return ";";
}
return ",";
}

(the list of locales is taken from my own Debian machine, I don't know about the completeness of the list)

If you don't want to have this static list of locales (though I assume that this doesn't change that often), you can of course generate the list using the command above and cache it.

As a final note, according to RFC4180 section 2.6 the list separator actually never changes but rather fields containing a comma (so this also means floating numbers, depending on the locale) should be enclosed in double-quotes. Though (as linked above) not many people follow the RFC standard.

Detect if the CSV separator is ; or ,

There is QLocale::groupSeparator():

QChar separator = QLocale().groupSeparator();

Edit:

But that it not a correct answer. Group separator is a character used in long numbers between number groups, for example: "1,234.56". In that example group separator is comma and decimal separator is period.

It seems that the QLocale doesn't contain list separator at all. You might try to make a guess according to what decimal separator is used. If decimal separator is . then use , as a CSV separator, if decimal separator is , then use ; as a CSV separator. But I don't know if that covers all languages.

Local separator for CSV files generation in Typescript (or Javascript)

I think the solution you have in your answer might be as good as it gets. Here's a question/answer regarding a similar issue (finding the current locale's decimal separator) - the accepted answer is very similar to the solution in your question: https://stackoverflow.com/a/1308446/1063392

If you're worried about the separator consisting of more than 1 character (although I think that's a reasonable assumption to make), you could make your function select everything between the two characters in your test array instead of blindly taking the character at [1]:

function SetSeparator() {  //var list = ['a', 'b'];  //var s = list.toLocaleString();    // let's pretend the current separator is ||  var s = 'a||b';    var reg = /a(.*)b/;  var sep = reg.exec(s)[1]  document.writeln('The separator of the current locale is: "' + sep + '"');}
SetSeparator();

How to get current regional settings in C#?

As @Christian proposed ClearCachedData is the method to use. But according to MSDN:

The ClearCachedData method does not
refresh the information in the
Thread.CurrentCulture property for
existing threads

So you will need to first call the function and then start a new thread. In this new thread you can use the CurrentCulture to obtain the fresh values of the culture.

class Program
{
private class State
{
public CultureInfo Result { get; set; }
}

static void Main(string[] args)
{
Thread.CurrentThread.CurrentCulture.ClearCachedData();
var thread = new Thread(
s => ((State)s).Result = Thread.CurrentThread.CurrentCulture);
var state = new State();
thread.Start(state);
thread.Join();
var culture = state.Result;
// Do something with the culture
}

}

Note, that if you also need to reset CurrentUICulture, you should do it separately

Thread.CurrentThread.CurrentUICulture.ClearCachedData()


Related Topics



Leave a reply



Submit