1

I have an API which looks like

/summary/yyyy/mm
  • Which returns the summary of their data for the year and month requested.
  • One of the things it returns the number of days left if this is current year and month. For example: days_left: 9 for 2013 and 10 and current date on server is 21 Oct 2013

How I calculate remaining days?
This is implemented in python as

def current_financial_month_details(self):
        time_from, time_to = self \
            .get_start_end_time_current_financial_month()

        today = datetime.today()
        from_time = datetime(year=today.year, month=today.month,
                             day=today.day)
        return {
            'time_from': time_from,
            'time_to': time_to,
            'remaining_days': (time_to - from_time).days
        }

The problem?

  • The server is in east coast and the client(me with browser) is on pacific time zone
  • When its 9PM PST the time changes in east coast, so if I run hit /summary/2013/10 and if it is Oct 21 2013 for me on PST, the date has already changed on EST, so days_left: 8 which is incorrect on client end. right?

How do I handle this situation?

daydreamer
  • 87,243
  • 191
  • 450
  • 722
  • 1
    Add a timezone parameter to your API? – basher Oct 21 '13 at 15:55
  • Heavily depends on what you are going to do. If it's some kind of space-time distributed data consumed by distributed users - you'd better work in UTC and demand all clients to do conversions / require timezone parameter and convert to UTC on server right away (before hitting business logic) – J0HN Oct 21 '13 at 15:59

2 Answers2

4

Most people consider best practice to keep storage of dates and times in a timezone independent from geographical location - most commonly UTC. The same applies if you have a service that is going to be accessed (or could eventually be accessed) from locations with different timezones.

As J0HN mentioned, clients should be tasked with converting from/to UTC when they interact with the server. In your case, this means days_left should be defined as the number of days between the current UTC date and the end of the month (in UTC).

For python in particular, there's two types of datetime.datetime objects: naive and timezone-aware. Naive datetimes don't attach any timezone information, so a good practice (in a networked program) is to only use naive datetimes for times in the UTC timezone. To make calculations (subtracting two dates, for instance), consider using datetime.utcnow instead of datetime.now, so you avoid any timezone-associated problems, including (but not limited to) wrong time deltas caused by DST.

If you really need to process other timezones (for displaying to the user, for example), you may need to use a external library, since python, by itself, does not provide a timezone database. This question has more information about that.

Community
  • 1
  • 1
loopbackbee
  • 21,962
  • 10
  • 62
  • 97
1

You have a few choices.

First is to specify the time zone that the results are delivered in and expect the clients to live with the discrepancy. Obvious choices are the server timezone or UTC.

Second is to have the API also return the current date as well as the number of days. It won't change the result but at least you'll be able to detect that the date is different than the one you were expecting.

Third is to have the API take a time zone input so that the server can adjust its processing.

Fourth is to make the date change at some time other than midnight, 5 AM for example. This only works if your clients are all in similar timezones and your activity isn't round-the-clock; if you have a client in China you're probably going to regret this option.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • I don't like the fact that the `API` should include this information. Instead I was thinking to extract time from HTTP request, change in UTC on server and get the difference with server's datetime.utcnow() in number of days. That ways the API would still be in tact and client will not have to worry about sending TZ information. How does this sounds to you? – daydreamer Oct 21 '13 at 16:54
  • My database however is saving the time in UTC format only. something like `2013-10-13 18:05:05.779-07` – daydreamer Oct 21 '13 at 16:55