3

The application I am working on has as target users USA. And (as you may know) in USA there's more than one time zone. So I have some doubts:

  • so how could I get the current time in server side based on the current user?
  • And how could I store DateTime data to show the correct time for every user?
  • How can I compare times (example: user.event.created > datetime.now())? What timezone will .now() use?
  • What TIME_ZONE should I set in settings.py file.

This is for an API, to grab user's timezone via JS is not an option. I get the current user via TokenAuthentication.

Gocht
  • 9,924
  • 3
  • 42
  • 81

4 Answers4

1

Use UTC for settings.py and grab their timezone offset from Javascript:

var utcOffset = -((new Date()).getTimezoneOffset()) / 60;

e.g. for Los Angeles right now utcOffset == -7

Unfortunately this doesn't account for Daylight Savings Time changes later (offset changes to -8), so you may have to figure that out at the time of retrieval in order to get Pacific/Los_Angeles. Otherwise you could always just ask the user in a signup form if it's important for your business.

EDIT: Since you're using an API, you could also try using the IPInfoDB API to geolocate based on client IP address. It's not always completely accurate, but almost always enough to get the correct timezone.

GRX'mike
  • 86
  • 2
  • Thanks for your answer, I may have to ask the user. I had to point in answer I am working in an API, so I can't use JS to get user's time zone. – Gocht Sep 03 '15 at 17:50
  • @Gocht I edited my answer with another possible solution since you're using an API. – GRX'mike Sep 03 '15 at 18:11
  • So you recommend store the user timezone? or get it everytime user access to the API. I edited the question with one more doubt. – Gocht Sep 03 '15 at 18:40
  • You need to figure that out yourself based on your business model. I've been on a project where we stored the timezone because we needed to create graphs and data tables and ensure they remained consistent. I could see use cases where you'd want to collect it every time (though I'd shy away from this), but I don't know your business. – GRX'mike Sep 03 '15 at 19:26
  • Let tell you a little please. I have user `type1` and `type2`, users `type1` create `events` and users `type2` must see events in their location area (based in a map). Currently I store automatic `created` using `auto_now`, but it store the server's ` now` but user can set the `event_date`, now I need to do some stuff with event passed its date, that's why I need compare times. User will set `event_date` according his timezone, which could be different from server timezone or even users `type2` users – Gocht Sep 03 '15 at 19:44
  • Yeah, it's too complex to go over completely in an SO comment thread. The two most annoying things to deal with in programming are language/encodings and time/timezones, so there's no avoiding critical thinking, sweat, and frustration. Good luck and thanks for the upvote! – GRX'mike Sep 03 '15 at 21:43
0

Don't use datetime.now(), use the now() function in the timezone module instead.

from django.utils import timezone

now = timezone.now()

Django will figure out which timezone you are in and compare them accordingly.

user.event.created > timezone.now()

https://docs.djangoproject.com/en/1.8/topics/i18n/timezones/

Du D.
  • 5,062
  • 2
  • 29
  • 34
  • I guess `timezone.now()` get the timezone in `settings.py` file. But in some cases, user will have a different timezone. – Gocht Sep 03 '15 at 19:35
  • by default it uses the timezone in the setting, but if you have user specific timezone you can activate timezone.activate(pytz.timezone(tzname)). Look at the TimezoneMiddleware in the link above. – Du D. Sep 03 '15 at 19:44
0

The solution is to always store unix timestamps in the database. You can generate with time.time() . That means your model should have a Floatfield (or even a BigIntegerField depending on the accuracy needed).

Your template should display the numeric value as it is. Then you need a tiny bit of javascript to convert that unix timestamp to a date time.

new Date(unix_timestamp);
e4c5
  • 52,766
  • 11
  • 101
  • 134
0

The users of your webapp may be in different time zones, so the conversion to an appropriate time zone is necessary. You can create a middleware and use activate function to set the appropriate time zone. You can get the client-side timezone by doing an ajax api call to Free IP Geolocation API in your landing page and the timezone value can be saved in a cookie variable which can be later accessed in the middleware.

landingpage.html

<script>
$.ajax({
        url: 'https://freegeoip.app/json/',
        dataType: 'json',
        success: function (data) {
            document.cookie = 'timezone=' + data['time_zone'] + '; path=/';
        }
      });
</script>

middleware.py

import pytz
import requests

from django.utils import timezone

class TimezoneMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

def __call__(self, request):
    
    tzname = request.COOKIES.get('timezone')
    if tzname:
        timezone.activate(pytz.timezone(tzname))
    else:
        timezone.deactivate()
    return self.get_response(request)

settings.py

MIDDLEWARE = [      ........
            'projectname.middleware.TimezoneMiddleware',

]

Arun Baby
  • 11
  • 1