Is there a way to get locale from country or timezone? - python

I was programming a program in Python, where I need to output date as per user's locale:
Get a list of timezones in a country specified as per user input (did that using pytz)
Get the locale of the user (which I am unable to figure out how to do)
Is there a way to get locale from county/timezone or some other method needs to be followed?
Or do I need to get the locale input from user itself?
EDIT
The program is to be a web-app. The user can provide me his country. But does he have to explicitly provide me the locale also or can I get it from his timezone/country?

"Locale" is a country + language pair.
You have country + timezone. But no info about the language.
I don't think it's possible to convert country + timezone into a single 'correct' locale... in countries with multiple languages there is not a 1:1 relation between language and timezone.
The closest I can see is to use Babel:
from babel import Locale
Locale.parse('und_BR') # 'und' here means unknown language, BR is country
>>> Locale('pt', territory='BR')
This gives you a single 'most likely' (or default) locale for the country. To handle the languages properly you need to ask the user their preferred language.

Related

Python/Django: How to make sure "string".upper and "string".lower work with different languages?

I have a problem with upper and lower functions in Python/Django. I have the following line of code:
UserInfo.objects.get(id=user_id).city.upper()
The problem is that some of the Turkish users let me know that they are seeing the wrong information. For example one of them is from a city called "izmir". The upper function converts that into "IZMIR" it turns out the actual result should be "İZMİR".
What is the right way to use upper or lower functions for any given language? I read about changing the server locale as an answer. Changing server locale for each user request does not make sense to me. What about multi-threaded applications that handle different users simultaneously?
Thanks in advance for your time.
I would suggest you to use PyICU
>>> from icu import UnicodeString, Locale
>>> tr = Locale("TR")
>>> s = UnicodeString("I")
>>> print(unicode(s.toLower(tr)))
ı
>>> s = UnicodeString("i")
>>> print(unicode(s.toUpper(tr)))
İ
Firstly ask your user to select his preferred language and convert his city to that's language in uppercase.

Get system country location while offline

I'm looking to accept date input into a script and running into the conundrum of how to differentiate between 040507 // 04052007 and 050407 // 05042007 when user intends April 5th, 2007 (or May 4th, 2007). The US tends to follow the first form, but other countries the second.
I know I can use IP/GPS in some instances, but I'm looking for a method that works offline, maybe from system location/language?
I'm primarily looking for a Windows solution, but surely others will be useful in future/to others.
NB I'm not considering timezone a good option, as different countries in the same timezone can use different conventions.
Judging by your date formats, I think your user manually enters the date. Unfortunately, locality will have little to do with how it is entered. I am in the US but prefer to input my date with the full year.
A simple way would be to force a standard or accept either way and test for which was entered.
def test():
while True:
testdate = input()
if testdate.isdigit() and len(testdate) == 6:
#do something
break
elif testdate.isdigit() and len(testdate) == 8:
#do something
break
else:
print("Please enter correct format")
This would check to make sure only digits are entered and then checks the length to determine which format was used.
You could force a standard by specifying “ddmmyyyy” and only accept an 8 digit input.
If I’m wrong on how the date is given, let me know and I’ll update accordingly.
EDIT:
If you want to guess the user’s format by determining their location, you can use the locale module.
import locale
print(locale.getlocale())
Output:
('en_US', 'UTF-8')
Another way using locale is to check the international currency symbol of the locale.
import locale
locale.setlocale(locale.LC_ALL, "")
print(locale.localeconv()['int_curr_symbol'])
Output:
USD
Here is a list of currency codes: https://www.ibm.com/support/knowledgecenter/en/SSZLC2_7.0.0/com.ibm.commerce.payments.developer.doc/refs/rpylerl2mst97.htm
You could always check the OS default language, using getdefaultlocale(), and you could use that to guide how you parse dates:
>>>import locale
>>>locale.getdefaultlocale()
('en_US', 'cp1252')
This wouldn't be exact, as I would enter dates the same way no matter what locale my computer is using, but it could give you a starting point.

Robot Framework How to get different timezone and locale for different country?

In robot framework, the current supported keyword to get timezone is:
${month} Get Current Date result_format=%B%Y
which will return: July 2017
The question is how to get current date from other country and locale?
as example in Vietnam should return: Tháng Bảy 2017
and Thailand should return : กรกฎาคม พ.ศ. 2560
Unfortunately, python doesn't have good built-in support for formatting dates in locales other than the current one. You can temporarily switch locales, but that's not a great solution.
You can use the the Babel package to format the dates, though it doesn't provide precisely the same value you expect -- the case is slightly different.
For example, you could create a keyword that dates a month, year, and locale, and returns the formatted version.
First, create a python file named CustomKeywords.py with the following contents:
# CustomKeywords.py
import datetime
from babel.dates import format_date
class CustomKeywords:
def get_date_for_locale(self, locale, year, month=1, day=1):
d = datetime.date(int(year), int(month), int(day))
return format_date(d, "MMMM Y", locale=locale)
Next, import this library into your test case and then call get date for locale to get the date for a given locale:
*** Settings ***
Library CustomKeywords.py
*** Test Case ***
Vietnamese
${date}= get date for locale vi_VN 2017 7
Should be equal ${date} tháng bảy 2017
Thailand
${date}= get date for locale th_TH 2017 7
Should be equal ${date} กรกฎาคม 2017
In the Robot Framework Datetime library the concept of changing the TimeZone is not present. The Robot Framework Custom Timestamp functions rely on the underlying Python datatime.strptime function. This function uses the python Locale for it's formatting.
As this has now become a more general Python problem, I've searched SO and found this particular SO answer to fulfill the criteria to create a custom Python Keyword for Robot Framework that would allow changing the Locale and thus determine the output.

Time Zone names in local language

Is there a method to retrieve time zone names in another language?
In Python, if I do something like this:
for tz in pytz.common_timezones_set :
print tz
The result is in English, but what if I would like to have it in Spanish or Arabic?
You can use babel package
import pytz
from babel.dates import get_timezone_location
for tz in pytz.common_timezones_set:
print(get_timezone_location(tz, locale='es'))
No, unfortunately there are no translations for the timezone names. The names are part of the Olson timezone database (not part of Python or pytz). New ones are added from time to time, so any potential translation project would have to stay in sync with that database.
pytz.common_timezones_set returns a set of timezone ids in the tz database. They are designed to be human readable but they are not translatable.
PyICU provides access to the localized timezone names:
>>> from datetime import datetime
>>> import icu
>>> df = icu.DateFormat.createDateTimeInstance(icu.DateFormat.SHORT, icu.DateFormat.FULL, icu.Locale.getFrance())
>>> df.format(datetime.now(icu.ICUtzinfo.getDefault()))
'27/01/2015 21:01:01 heure normale d’Europe centrale'
Coming quite late but I ran into a similar issue lately, and ended up creating my own package l18n for that purpose. It is available here : https://pypi.org/project/l18n/
It provides translations files for human-readable places and timezones used in pytz. Most of the translations are automatically fetched from the CLDR database, but there are always a few of them missing. For the moment only translation files for English and French are available. Feel free to contact me (create an issue on the packages's repo https://github.com/tkhyn/l18n) or follow the step-by-step procedure here if you want to add translations for your language.

Formatting date times provided as strings in Django

In my Django application I get times from a webservice, provided as a string, that I use in my templates:
{{date.string}}
This provides me with a date such as:
2009-06-11 17:02:09+0000
These are obviously a bit ugly, and I'd like to present them in a nice format to my users. Django has a great built in date formatter, which would do exactly what I wanted:
{{ value|date:"D d M Y" }}
However this expects the value to be provided as a date object, and not a string. So I can't format it using this. After searching here on StackOverflow pythons strptime seems to do what I want, but being fairly new to Python I was wondering if anyone could come up with an easier way of getting date formatting using strings, without having to resort to writing a whole new custom strptime template tag?
You're probably better off parsing the string received from the webservice in your view code, and then passing the datetime.date (or string) to the template for display. The spirit of Django templates is that very little coding work should be done there; they are for presentation only, and that's why they go out of their way to prevent you from writing Python code embedded in HTML.
Something like:
from datetime import datetime
from django.shortcuts import render_to_response
def my_view(request):
ws_date_as_string = ... get the webservice date
the_date = datetime.strptime(ws_date, "%Y-%m-%d %H:%M:%S+0000")
return render_to_response('my_template.html', {'date':the_date})
As Matthew points out, this drops the timezone. If you wish to preserve the offset from GMT, try using the excellent third-party dateutils library, which seamlessly handles parsing dates in multiple formats, with timezones, without having to provide a time format template like strptime.
This doesn't deal with the Django tag, but the strptime code is:
d = strptime("2009-06-11 17:02:09+0000", "%Y-%m-%d %H:%M:%S+0000")
Note that you're dropping the time zone info.

Categories