I've been mulling over a problem with dates and timezones using the Event module, and would like to put across some thoughts and ask where current thinking is on this issue.
It seems to me that, when a user creates an Event in Drupal, there are potentially a number of different times (and timezones) involved:
1) UTC time (this is the kind of zero baseline, and really the only thing that can be relied on)
2) Local timezone on the server.
3) The user's local timezone (as specified in Drupal user profile).
4) The timezone where the event is to take place.
5) The timezone of the anonymous user looking at the event.
Here is a scenario - somebody tell me if I have got my sums or assumptions wrong!
Suppose that I have enabled "Configurable time zones" in "Settings", and set the default time zone to +0200 (because most of my users are in Continental Europe - and we are on summer time)
Suppose now that my web site is hosted in the USA (New York: -0500).
A user in the UK (+0100 on British Summer Yime) now creates an event which is to take place at midday the next day, in Calcutta (India: +0530)
Let us suppose that the user has set his (UK) timezone profile, then the event will be timed at BST 1200 (ie UTC 1100)
Now a user from India logs in, and notices that there is an event in Calcutta. Since his profile has his timezone set to local time (UTC +0530), he sees the event advertised at UTC 1100 +0530, ie at 16:30, and turns up only to find that it has already finished.
An anonymous user from India is luckier: because he has not logged in, the server assumes that he is using the default time (UTC +0200), he therefore turns up only one hour late and before the event has finished!
This may sound an extreme example, but after all in Europe we already have three different time zones (at time of writing: UK - UTC +0100, Central Europe +0200, Baltic (Finland, Estonia, etc) +0300).
========================
In fact, the "event" in this case needed to display a time relative, not to the server or to any of the users, but to the locality of the event: the only solution that would make sense here, as far as I can see, would be to have the locality entered as a parameter of the event (with the timezone).
The only solution I can see with Drupal now is to disable configurable time zones, so that the time an event happens is displayed correctly (there is no time display conversion at all: I enter the time of the meeting at 12:00, it is displayed as being 12:00). However, the calculation of "time to event" is not correct, which is unfortunate (in fact the Event module should not show the countdown if configurable times are disabled).
In my example, this is a meeting where people will be physically present, so it does not matter to someone in London that the time of the meeting in Calcutta is not displayed in his local time - he won't be there anyway.
But on the Internet, there may be events on the net (a webinar), where multiple people from all around the world connect to the meeting at the same time. In this case, it is vital to know what time the meeting will be in your local time.
Then there is the problem of DST!
I've been looking in the PHP doc, and I can't find any way to get the time for a locale other than the server locale or UTC.
In addition, there is no guaranteed way to find the correct time on the user's system: that means relying on a PC which is by definition unreliable (though there is an interesting article here about combining Javascript and PHP to get local time)
Any suggestions would be welcome! In the meantime I will go on thinking about this....
Comments
Which hversion of
Which hversion of event.module have you been using? There is a completely rewritten version in cvs HEAD.
--
If you have troubles with a particular contrib project, please consider filing a support request. Thanks. And, by the way, Drupal 4.6 will support PHP 5.
--
Drupal services
My Drupal services
Event version 4.5.0
Still using 4.5.0 - prefer to stick to something stable that I know for the moment. Is there a list of new features being worked on for 4.6.0?
I hope Aaron and I will be
I hope Aaron and I will be able to create a release announcement when we branch for 4.6.
--
If you have troubles with a particular contrib project, please consider filing a support request. Thanks. And, by the way, Drupal 4.6 will support PHP 5.
--
Drupal services
My Drupal services
Can't create new Event
Hi,
I've installed the new CVS version of the Event module in 4.6.0rc but can't find any way to create a new event. There's no event item in the Create Content menu. Any ideas?
Marcus.
Event paradigm shift
An event is now an attribute of a node, ie. a story can be an event.
See topic: How do I add an event to the calendar?
P.S. I am just a newbie to Drupal, so that's all I can offer at the moment.
You get the problem
I posted a similar thread a couple of weeks ago. You can find it at http://drupal.org/node/19135.
Even with some patches I've seen for 4.6, Drupal handling of time zones is still a mess.
Having worked on exactly this problem while employed with A Large And Well Known Internet Company, there are several problems with the current time zone code, and there are also problems with the proposed patch. Here are the main issues:
This is a complete mess, and does not work well even if you are dealing with a single time zone. It is worse than useless if you are dealing with multiple time zones
For now, here's what looks to me worth doing:
The idea of doing the table in SQL just hit me; I may be able to come up with something to contribute, now that I think about it.
Cheers,
Rob
Rob Thorne
Torenware Networks
Agree with the basic way of handling this...
I agree that the only coherent way of handling this question is to store all times in GMT (or Universal Time Coordinates as people seem to say nowadays). Then convert on display.
In terms of knowing where the information on timezones etc is held (which is phenomenally complicated worldwide), I'm surprised nobody has mentioned the Olson database which as far as I can understand provides the basis for handling the question in Java, Linux... Rather than stocking this in SQL, why not a PHP module to extract the data from this database, plus a cron job to check regularly for updates...?
And at the risk of repeating myself, you need to be able to include the timezone in which the event is taking place with the event, so that the time will display correctly for both authenticated and anonymous users.
Arthur Olson -- The Time Lord Himself
Olson's data (and his C utilities) is indeed the source for most time zone utilities and code, and if PHP gets a module that does time zones right, it will almost certainly start out with Arthur's code and data.
But many of these libraries (including a C++ port of the Java libraries I used to work with) have a price attached: they can require a lot of disk i/o, and some of them are pretty slow: slow enough to measurably affect how long it takes to process a page. So a web library may need to have some kind of caching scheme built into it.
I'm not sure, however, that you need, or even want, to link the time zone with the event itself, except in those cases where you need to indicate what "local time" is where the event takes place. If you are talking about a web conference, for example, local time at the site of the event's irrelevant: you want to make sure that people know when the event is in their own time zones. Our Indian engineer in Bangalore (UTC/GMT +5:30 hours) doesn't need to know what the time is in San Jose, California -- he needs to know when the meeting is. So the right time to use for our engineer is local time where he is, and local time of "the event". That's not always the case ("I'm flying to San Jose for the conference -- when will the meeting be?"). So rather than say that the time zone is a characteristic of the event, it's probably better to think that time zones belong to the location.
What is more useful, I think, is a notion of default server time.
There is a PHP Pear module, but it's alpha quality right now. It may be the right place to start, though, perhaps using some of the same parsing logic as the equivalent perl library.
Rob Thorne
Torenware Networks
Event location time
I agree that in some cases it's not important what the "local time" of the actual event is - but the reality is a lot of other types of events, it's important. For example, I produce races - and I don't care where you live. My events are located in a specific timezone. Therefor, you need to get to my race in my timezone, at the time I specify it starts.
So ... the event would *definitely* need to handle timezone display as it would be defined as "local to the event".
FYI - I posted about this topic at http://drupal.org/node/20927 - which is essentially useless in light of this conversation.
event.module 4.6 does this
This is how the new event module works. All stored timestamps are GMT, with a seperate offset for 'local' or 'event' timezone. You can decide to display event times with the event's local timezone or the user's timezone if enabled. I agree that the timezone handling is weak in terms of DST (since its actually ignored), and that there is no built in PHP timezone utility that does not require changing environment variables on the fly (bad), but the timezone handling in this version is far from useless. Olson database I have not looked into, but I will. Thanks for the link.
A dst patch would be welcome, and the new timezone handling structure will make it easier to implement since all timestamps are GMT in the module until display, when an offset is applied (in one function) so it is easier to deal with.
More information on the event module here: http://civicspace.advomatic.com/
Uh serious TZ probs in new event.module
Uh ... except the TZ handling in the new event module (at least the CHANGELOG version dated 04/15/05) is seriously screwed up.
See: http://drupal.org/project/issues/event?categories=bug
For a list of several bugs filed against it. I personally have had serious issues with the TZ handling - so much so that I backed out fro 4.6.0 back to 4.5.2 and the at least stable issues with the event.module there. For example, when I set an event time, then save the event, the TZ setting gets added/subtracted. If I modify the event, it AGAIN gets added/subtracted. Constantly shifting the event time.
I wouldn't recommend the event.module until this issue is fixed.
I'll look at the new version
I'm starting to look at 4.6 seriously, and since I've hacked this part of the 4.5 code pretty much start to finish, I'll see if I can figure out what the problem is with the new version.
If I can come up with a reasonable solution, I'll post a patch.
One question for you: we list different usage scenarios in this thread. Which best applies to what you want to do?
Thanks,
Rob
Rob Thorne
Torenware Networks
usage scenario
Hey Rob - thanks for the reply. I do events that are local to the server. The time string I enter is the local time of the server and the event. I don't need, nor do I care if my events are displayed in the users selected TZ - since if they come to do the event, they will be in local TZ physically to attend the events.
All things considered, I would believe (maybe erroneously) that this is one of the simplest scenarious to deal with. Simply enter a timezone in the settings - set the system wide setting to NOT use configurable TZs. Enter an event start/end time, and that should be that...
Looking forward to seeing this get fixed - as the TZ and time stuff was so badly mangled that I had to disable it - which isn't a "real fix".
Time To Think About Time
I'm not sure how projects get started with the Drupal project, but I'd like to see time zone handling improved, and would like to work with other people who want to do the same.
As we've seen, this is a complex issue. Probably the best way to start is to define a set of use cases/test cases to define what correct code should do. This will help us design code that actually "works" from the standpoint of different usage scenarios.
Here's a few for starters:
This is just for starters. Some of these points may seem incredibly obvious, but since I've seen implementations that violate some (or even most) of these use cases, it's clear that we need to keep the obvious cases in mind.
Another question: where is the best place to discuss this kind of design question? Eventually, some of us are going to want to start posting and testing different patches. How do the old timers recommend doing that on this site?
Thanks,
Rob
Rob Thorne
Torenware Networks
I'm interested....
A couple of points. These are not use cases but design principles:
1) Stored times should always be in UTC, no matter what (otherwise, for example, it becomes next to impossible to change your configuration)
2) It should be possible to distinguish between events where it is important to know the time at the location of the event (eg rock concert in a field), and events where the absolute time is important (eg webinar, web concert).
Ah good, a volunteer :)
So how do projects get started? Well first I would suggest a general search through the drupal-devel archives to see if you can get any hits on timezone issues that were discussed before and approaches desired/tried/shot down.
Sign up for the drupal-devel list and ask what you just posted. Gather suggestions, comments, concerns and other interested parties and start coding. Produce code :). Open an feature requet (or find an already open issue) and attach your patch to it. Discuss and refine based on feedback. Features tend to survive if an interested party sticks around. There may also already be work or planning centered around the development of the event module.
At this point you are probably looking at implementation for 4.7. If this could be added as a module for 4.6 so that people could test it then all the better.
-sp
---------
Test site...always start with a test site.
Drupal Best Practices Guide
-Steven Peck
---------
Test site, always start with a test site.
Drupal Best Practices Guide
Are you aware of my
Are you aware of my patch?
http://drupal.org/node/11077
--
If you have troubles with a particular contrib project, please consider filing a support request. Thanks. And, by the way, Drupal 4.6 will support PHP 5.
--
Drupal services
My Drupal services
Yep. Just Disabled It On One Install ;-)
Yes, in fact, a problem with DST handling on a client's install -- which is what motivated me to do my last post -- turned out to be caused by that patch :-(
This is in spite of the many things I like about your patch: it's got a reasonable user interface in Settings, and it's pretty light weight: you solve the problem for a relatively small number of very important time zones. Since the number of small countries that observe summer time isn't that large (most keep a single offset during the year, with no DST), it's a good approach.
My problem, however, is in how your patch handles formatting into localtime, and how it interacts with 4.5's nasty Event module, which also attempts to do its own (really evil) conversion into local time. Your patch and Event do not play nice with each other.
On the whole, I think it's necessary to think about time formatting and storage in Drupal in a more systematic way. Java, IMHO, has the right paradigm -- store a date/time object in a time zone independent way, and bring the time zone object and the date/time object together only when you format time for display, or when you parse a time string. So there needs to be an API that does this, and currently, there isn't.
Rob Thorne
Torenware Networks
The patch clearly needed
The patch clearly needed more testing. I think it would have worked with event module if you had switched Drupal's global time zone handling off.
--
If you have troubles with a particular contrib project, please consider filing a support request. Thanks. And, by the way, Drupal 4.6 will support PHP 5.
--
Drupal services
My Drupal services
tz & zoneinfo
Unix has built-in time zone info, usually at /usr/share/zoneinfo. PHP can make use of this by setting the TZ environment variable.. e.g. putenv('TZ=America/Buenos_Aires'); to calculate dates in Buenos Aires. then putenv('TZ'); when you're done to go back to the server's default.
for both entering and displaying dates/times, there should be a site default TZ, optional user TZ (defaults to site TZ), and optional event TZ (defaults to user TZ or else site TZ; this would allow a user in New York to enter an event in local Los Angeles time without having to do a conversion).
Storing timezone as a standard zoneinfo entry (e.g. America/Buenos_Aires) is the only way to store timezone, since the numeric offset (like -25200) or acronym (like PDT or PST) both change throughout the year. the TZ would be set via a dropdown select field listing all valid values.
This has the advantage that it's much easier to set your timezone -- when u arrive in a foreign country with your laptop it's probably easier to know that simple fact than the (currently) correct offset. Also anyone who has set up a computer whether Mac or Linux should be familiar with setting their timezone based on a geographic name.
To avoid confusion, all dates and times on the site should be displayed with their timezone (the currently appropriate acronym or numeric offset), based on either the user's TZ or site default TZ.
example
By the way, here's an example of a php page which uses standard php functions to do date/time calculations in various timezones: http://contact.indymedia.org/timezone.php
For calculations and display of dates/times, it uses only putenv('TZ='), strftime() and strtotime(), so it always takes into account DST and any other issues known to the libraries..
Isn't that liable to mess up things for others?
I don't quite see the "putenv" etc - I may be missing something about how PHP works, but I would have thought that if you did a "putenv" on the server, then that would change the env value for everyone connecting to the server during that interval. In other words, if you want to find the time for Buenos Aires, then you do a putenv and for the brief period before you switch it back again, everybody thinks they are in Buenos Aires.
I believe it depends upon the OS and the Web Server
Some of the more experienced PHP developers (especially those that deploy on Win32) will need to add to this, but the answer is, "it depends".
On a server like Apache 1.3.x on a Unix system, each request runs as a separate process. So when you call putenv, it affects that request, and that request alone.
On a Unix server with a server that uses threads instead of separate processes (I believe this includes Apache 2.x), I believe that each thread sees its own copy of the environment, so each thread can set its own value of an environmental variable without affecting other threads. Since some servers create "pools" of threads and reuse them, you probably should not assume that you know what the value of the environmental variable is until you set it. But since only one request is running at a time in a thread, at least you don't have to worry about someone resetting its value behind your back. [Serious Unix hackers: am I right about this??? This may depend upon the implementation of the various C libraries for the OS].
Under Win32, all bets are off. Win32 has a "global" environment. How this works with Win32 threads I have no idea; someone who programs for that platform will have to tell you.
** ON UPDATE **
Maybe not on threaded Unix servers. I found a doc that describes the API for Digital Unix. On that system, the environment for the application is really a single global data structure. To code on that platform in a thread-safe fashion, you have to protect calls to putenv with a mutex (i.e., only one thread can safely play with it at a time). So using the putenv hack would be risky or complex at best on a threaded server, since you'd really need some mechanism to make sure that when a request needed to set the environment, that any other request thread that needed to the same gets blocked until the environment sensitive call (say, "date()") exits.
I believe this can be done in PHP, but it's not for sissies....
Rob
Rob Thorne
Torenware Networks
putenv('TZ')
I use putenv('TZ') to handle timezone calculations on a variety of different PHP applications and haven't had problems. Frankly, it's the only way to do it, although I believe recent versions of MySQL optionally support timezone conversions.
You simply need to putenv('TZ=') as desired to display a date/time from Unix UTC timestamp, or to accept input in a given timezone for conversion to Unix UTC timestamp. then putenv('TZ') when you're done to return the PHP script to the normal environment. Otherwise yes, that process will have the wrong environment variable and there would be unintended consequences.
I've Created A Time Zone Project
Assuming I can even do this, I've created a Time Zone project for Drupal. Since I'm hacking on the time zone code anyway for work I'm doing with the 4.6 Event module, I'll be posting patches. Since a number of you have already worked on this, I'm hoping to help people communicate with the rest of us on their own patches, as well as their requirements for date and time formatting and time zone support.
Cheers,
Rob
Rob Thorne
Torenware Networks