Giter VIP home page Giter VIP logo

django-tz-detect's Introduction

django-tz-detect

https://coveralls.io/repos/adamcharnock/django-tz-detect/badge.svg?branch=develop

This app will auto-detect a user's timezone using JavaScript, then configure Django's timezone localization system accordingly. As a result, dates shown to users will be in their local timezones.

Authored by Adam Charnock, and some great contributors.

How it works

On the first page view you should find that tz_detect places a piece of asynchronous JavaScript code into your page using the template tag you inserted. The script will obtain the user's GMT offset using getTimezoneOffset, and post it back to Django. The offset is stored in the user's session and Django's timezone awareness is configured in the middleware.

The JavaScript will not be displayed in future requests.

Installation

  1. Either checkout tz_detect from GitHub, or install using pip:

    pip install django-tz-detect
  2. Add tz_detect to your INSTALLED_APPS:

    INSTALLED_APPS += (
        'tz_detect',
    )
  3. Be sure you have the django.template.context_processors.request processor

    TEMPLATES = [
        {
            ...
            'OPTIONS': {
                'context_processors': [
                    ...
                    'django.template.context_processors.request',
                ],
            },
        },
    ]
  4. Update your urls.py file:

    urlpatterns += [
        path('tz_detect/', include('tz_detect.urls')),
    ]
  5. Add the detection template tag to your site, ideally in your base layout just before the </body> tag:

    {% load tz_detect %}
    {% tz_detect %}
  6. Add TimezoneMiddleware to MIDDLEWARE:

    import django
    
    MIDDLEWARE += (
        'tz_detect.middleware.TimezoneMiddleware',
    )
    
    if django.VERSION < (1, 10):
        MIDDLEWARE_CLASSES += (
            'tz_detect.middleware.TimezoneMiddleware',
        )
  7. (Optional) Configure optional settings

    Set the countries in which your app will be most commonly used:

    # These countries will be prioritized in the search
    # for a matching timezone. Consider putting your
    # app's most popular countries first.
    # Defaults to the top Internet using countries.
    TZ_DETECT_COUNTRIES = ('CN', 'US', 'IN', 'JP', 'BR', 'RU', 'DE', 'FR', 'GB')

    Set the session key that will be used to store the detected timezone

    # Session key to use, defaults to "detected_tz"
    TZ_SESSOIN_KEY = "my-session-key"

Please see example application. This application is used to manually test the functionalities of this package. This also serves as a good example.

You need only Django 1.8 or above to run that. It might run on older versions but that is not tested.

Caveats

  • Django's timezone awareness will not be available on the first page view
  • This method requires JavaScript
  • Timezone detection is done entirely from the user's GMT offset, not from their location

Future expansion

  • A hook to allow the timezone to be stored against a user
  • Allow timezones to be manually specified
  • Improve timezone detection
  • Optionally using HTML5's location API for better timezone determination

django-tz-detect's People

Contributors

adamcharnock avatar bashu avatar blag avatar craiga avatar ericdwang avatar jurrian avatar mblayman avatar pidelport avatar pirandig avatar qnub avatar ron8mcr avatar sorrison avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-tz-detect's Issues

AmbiguousTimeError: 2013-11-03 01:59:50.145226

Hey,

Got this yesterday:

AmbiguousTimeError: 2013-11-03 01:59:50.145226

Stacktrace (most recent call last):

  File "django/core/handlers/base.py", line 111, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "newrelic/hooks/framework_django.py", line 485, in wrapper
    return wrapped(*args, **kwargs)
  File "django/views/generic/base.py", line 48, in view
    return self.dispatch(request, *args, **kwargs)
  File "newrelic/hooks/framework_django.py", line 831, in wrapper
    return wrapped(*args, **kwargs)
  File "django/views/generic/base.py", line 69, in dispatch
    return handler(request, *args, **kwargs)
  File "tz_detect/views.py", line 20, in post
    tz = offset_to_timezone(int(offset))
  File "tz_detect/utilities.py", line 30, in offset_to_timezone
    tz_offset = tz.utcoffset(datetime.now()).seconds / 60
  File "pytz/tzinfo.py", line 406, in utcoffset
    dt = self.localize(dt, is_dst)
  File "pytz/tzinfo.py", line 349, in localize
    raise AmbiguousTimeError(dt)

Context was:

'clostest_delta': 420
'clostest_tz': <DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>
'delta': 420
'offset': -60
'tz': <DstTzInfo 'America/New_York' EST-1 day, 19:00:00 STD>
'tz_name': u'America/New_York'
'tz_offset': 480
'user_offset': 60

Correctly handle NonExistentTimeError errors

During DST transitions, when this view is executed, at times it will 'pick' a timezone that does not have a valid time for the provided parameters.

In this case, it should actually pick another timezone, one for which the parameters are valid.

Empty template block. Bug or a feature?

I'm running django-tz-detect 0.2.8 on Django 1.9.13 . Attempting to include tz_detect in the template as follows...

{% extends "admin/base_site.html" %}
{% block extrahead %}
 <!-- BEGIN django_tz_detect -->
 {% load tz_detect %}
 {% tz_detect %}
 <!-- END django_tz_detect -->
{% endblock %}

...Chrome's view source shows an empty block (but no errors):

<!-- BEGIN django_tz_detect -->





<!-- END django_tz_detect -->

Why might this be? The odd thing is, timezone seems correct anyway.

getTimezoneOffset() produces incorrect value if TZ is wrong

Hi, thank you for a great module!

Right now django-tz-detect uses (new Date()).getTimezoneOffset()) to get current user offset and save to session. While in most cases it't quite accurate, there is a weird case, when user doesn't change timezone itself, but just sets up it's local time.

getTimezoneOffset() can't detect such cases and returns offset, based on actual browser timezone, which leads to incorrect user time offset. It's seems this behaviour is quite common especially for Windows users.

I guess, the following approach may give more accurate results:

  1. When user logs in, send it's local time to server instead of offset.
  2. In middleware, compare it with UTC (as Django stores datetime in UTC) and calculate actual offset, not based on user offset and store into session.
  3. Use this value to shift user time according to it's real offset.

Any ideas? Thank you.

Detect wrong timezone when we have daylight saving time.

Hi everyone,

I am located in Seattle. We have PST Pacific standard time, offset UTC - 8 hours. http://www.timeanddate.com/library/abbreviations/timezones/na/pst.html
However at this time of the year, we have PDT Pacific daylight time, offset UTC -7 hours.

My browser knows this, so your JS code post the correct offset integer 420. Tested in my browser as below

(new Date()).getTimezoneOffset()
420

However, after the post reach the server side, the timezone being detected is wrong.

from tz_detect.utilities import offset_to_timezone
tz = offset_to_timezone(int(420))
print tz
America/Phoenix

Phoenix Arizona does not have daylight saving and they are having the same offset.

test_time = datetime.strptime("2014/05/21 11:00", "%Y/%m/%d %H:%M")
test_time = test_time.replace(tzinfo=tz)
print test_time.strftime("%Y/%m/%d %H:%M %Z")
2014/05/21 11:00 MST

This shows that the America/Phoenix timezone is the MST Mountain standard time
http://www.timeanddate.com/library/abbreviations/timezones/na/mst.html

Any idea on how to solve this problem?

--Gordon

24-hours configuration.

Is there a way on how to restrict time rendering format on the templates to be in 24 hours?

Don't assume context has request

I got a KeyError('request') with the following traceback

/usr/lib/python2.7/site-packages/tz_detect/templatetags/tz_detect.py in tz_detect
    'show': not hasattr(context['request'], 'timezone_active'),

Maybe use context.get() instead?

New release?

Hi, I've been experiencing problems because of 'request' KeyErrors in context. I fixed that problem some time ago, and it's been merged into develop branch. Can you release a new version with the fix?

error w/ new version coercing to Unicode: need string or buffer, int found

I'm getting the following error w/ the 0.2.3 version of tz-detect. Has anyone else seen this?


/Users/dblado/virtenv_5_30_2014/lib/python2.7/site-packages/tz_detect/utils.py in offset_to_timezone
    user_offset = (user_offset + 1440) % 1440 ...

Variable            Value
clostest_delta      1440
clostest_tz         None
now                 datetime.datetime(2015, 6, 5, 19, 48, 41, 192243)
user_offset         u''
offset              u'America/Phoenix'
Environment:

Request Method: GET
Request URL: http://localhost:8000/

Django Version: 1.6.5
Python Version: 2.7.6
Installed Applications:
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.sitemaps',
 'users',
 'tz_detect',
 'simple_cms',
)
Installed Middleware:
(
 'django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'users.middleware.UserRoutingMiddleware',
 'users.middleware.UserLastSeenMiddleware',
 'users.middleware.UserAgent',
 'django.contrib.messages.middleware.MessageMiddleware',
 'tz_detect.middleware.TimezoneMiddleware',
)


Traceback:
File "/Users/dblado/virtenv_5_30_2014/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  88.                 response = middleware_method(request)
File "/Users/dblado/virtenv_5_30_2014/lib/python2.7/site-packages/tz_detect/middleware.py" in process_request
  22.                 timezone.activate(offset_to_timezone(tz))
File "/Users/dblado/virtenv_5_30_2014/lib/python2.7/site-packages/tz_detect/utils.py" in offset_to_timezone
  33.     user_offset = (user_offset + 1440) % 1440

Exception Type: TypeError at /
Exception Value: coercing to Unicode: need string or buffer, int found

Forbidden (CSFR token missions or incorrect): /tz_detect/set

When running this on a pretty clean django install I cannot get the POST to work.

I have it setup as below:-

djsite/djsite/Settings.py

INSTALLED_APPS = [
    'cals.apps.CalsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'tz_detect',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'tz_detect.middleware.TimezoneMiddleware',

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

]

djsite/djsite/urls.py

urlpatterns = [
    url(r'^cals/', include('cals.urls')),
    url(r'^admin/', admin.site.urls),
    url(r'^tz_detect/', include('tz_detect.urls')),
]

djsite/cals/views.py

def index(request):
    now = datetime.datetime.now()
    context = RequestContext(request, {})
    context["now"] = now
    template = loader.get_template('cals/cals_small.html')
    return HttpResponse(template.render(context))

djsite/cals/templates/cals/cals_small.html

<html>
    <head></head>
    {% load tz_detect %}
    <body>
        It is {% now "jS F Y H:i" %}
        {% tz_detect %}
    </body>
</html>

I get the below output from runserver

"GET /cals/ HTTP/1.1" 200 510
"GET /static/tz_detect/js/tzdetect.js HTTP/1.1" 200 2643
Forbidden (CSRF token missing or incorrect.): /tz_detect/set/
"POST /tz_detect/set/ HTTP/1.1" 403 2502

It's been a long day so I am likely doing something wrong but would appreciate it if you could take a look.

Python 3.6.0
Django version 1.10.5

Wrong TZ detected for sessions that cross DST change

As the TZ guessing is only based on offset, and the guessed TZ is never saved, the same offset will be used after the user moved into daylight saving. This causes existing sessions to change current timezone.

Check if the offset has changed

Currently the offset is refreshed for each new session, even though the offset might've changed within the session.

How to reproduce: Change the timezone in your OS and refresh the page.

What we could do is to provide the current offset here and modify the javascript to update the offset only if it's changed.

django-tz-detect doesn't work in production.

So I've tested it locally, and it works.
But when I moved it to production, it doesn't work.

All my times are shown in UTC (server time).

I've viewed source to make sure that the Javascript snippet is included during the initial session, but any datetime is still shown in UTC.

Any help would be appreciated.

Upload new release

Hey Adam,

Can you upload new release? Everything is ready, just run:

git co master
git pull origin master
python ./setup.py sdist upload --sign -r pypi

Thanks

Python 3 Support

There doesn't seem to be any Python3 support? I tried installed in my Python3 Django project and couldn't get it to work.

Force reload page on innitial load (opt-in)

First of all I would like to thank you for this wonderful package
2 projects I've worked on are used in multiple time-zones and both revolve around reservations so times and time-zones is very critical
Storing everything in UTC and using this project to display in the users local TZ is a game changer!

One of the projects often has one time visitors so the Initial load limitation has become an issue - and when thinking of a solution I thought Why not just force a reload if the tz_detect cookie is not set - seems like a reasonable tradeoff for me
I know not everyone would want such a behavior - so it should be opt-in (via a config setting)

Daylight savings time question

Hi,

I have a site running django-tz-detect, and it was working amazingly up until this weekend, when daylight savings hit in California. I am in USA PDT (UTC -7), but the times on the site are all UTC -8 (Which would be USA PST, or without daylight savings on).

Is there anyway to handle daylight savings time properly?

Cheers, and thanks in advance!

Detect time zone based on IP address

There's an API called ip-api.com which will give you the location and time zone based on the user's IP.

If we use this on the server side, we can get the time zone in the first request. This does come at a performance cost, because network requests take time, so this should definitely be a setting. Also, the free tier only allows you to make 150 requests/minute, which might be too few for high-traffic apps, although you'd need to have a lot of unique visitors per minute, since we're only making one api request per user session.

This would also solve the time zone change detection problem (#25). We could detect a change in the user's ip, and make another request to the time zone service.

If this sounds like a good idea, I'm willing to submit a pull request.

Give back the maintainer right

Hi,

This repository seems to lack maintenance, I propose myself as a new maintainer.

Could you give me the right to push in your repository or just transfer it on my account in github?

Thank you

Timezone awareness on first view

According to the readme:

Django's timezone awareness will not be available on the first page view

Is there a specific reason this library does not attempt this?

Where we're using this library, we're getting a specific issue where when we show the site in an iFrame, it will never show the correct time zone, because of aggressive browser policies against storing cookies.

Url patterns is deprecated

Hi guys, just got in mine project (django 1.9.1):
[WARNING:py.warnings]**[init.py:84]: site-packages\tz_detect\urls.py:8: RemovedInDjango110Warning: django.conf.urls.pat
terns() is deprecated and will be removed in Django 1.10. Update your urlpatterns to be a list of django.conf.urls.url() instances instead.
url(r'^set/$', SetOffsetView.as_view(), name="tz_detect__set"),

as I see in the code it's:
urlpatterns = patterns('',...)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.