Welcome Guest, Not a member yet? Register   Sign In
Timezone Confussion -> convert_to_gmt -> daylight saving zones / Am I right ? Or wrong

Hello guys, I'm pretty new in PhP and the question I'm asking is discussed in some other post
as well. Maybe the solution is quite simple but this timezone stuff drives me crazy, and I don't know what is right or wrong anymore. First of all I explain what i want to have and then what I got. The idea:

User (EVENTCREATORS) in a Timezone (mostly UM5) can add events and user (EVENTVIWERS) in an other Timezone (mostly UP1) should see these Events in their own time (Timezone).

Example: User adds an Event at 1 PM in New York (UM5) and the user in Berlin (UP1) should see this Event at 7 PM in his calendar. (NewYork-Berlin 6 hours at the moment)

My solution approach:

1)Every user can set his own Timezone
2)Store Event dates in Database in UTC (GMT) and in unix format.
3) If an Event is created in UM5 Timezone, I take this Eventdate, make it to GMT and save it to data base.
4) If an User in UP1 Timezone views this Event i take the GMT Date out of the database and convert the date in UP1, so that the EVENTVIEWER see the Eventdate in his right time.

Here is what i got so far.

Somebody creats an Event in New York (UM5) which is saved in the variable $xy in sql format.
I make $xy to unix. I set the timezone UM5 and use the convert_to_gmt Funktion (http://codeigniter.com/wiki/convert_to_gmt) to convert it to GMT time (I dont save it in databse so far).
Then i take this GMT converted date $gmt_conversion and use the gmt_to_local function with the UP1 timezone to bring it in the right format for the Eventviewers in Berlin.
In my example below I don't use any daylight settings. So far everything works perfect.

For my introducing example: 1PM in New York - 7 PM in Berlin I get the right result(6 hours between New York and Berlin), but when i now use the Daylight_Saving Settings -> TRUE, my result turns into wrong (8 hours between New York and Berlin) !!!!!

But thinking about it daylight_saving settings can't be neglected, or can they ????.
Maybe i miss sth. here. Is my approach right or totally wrong ? Can sb. give me a kick ?

My servers (local) timezone is set Europe/Berlin but also changing this to in the php.ini to GMT didn't have any effects (I think it shouldnt because my solution doesnt need the servers time !?) I also set the config.php to $config['time_reference'] = 'GMT';

Here my code:

// $xy => the Event Date sth. like this : $xy='2009061123000'
            $xy = $mydatum.$this->input->post('stunde').$this->input->post('minute').'00';
            echo'----> Input Event time for Timezone UM5 :  ';
            echo $xy.'<br />';
            // make $xy to unix format
            $xy_unix = mysql_to_unix($xy);          
            // define timezone for $xy
            $event_timezone = 'UM5';
            // define daylight for $xy (isnt used in this example)
            $daylight_saving = TRUE;
            // use convert_to_gmt() function --&gt; http://codeigniter.com/wiki/convert_to_gmt
            // convert $xy to gmt Time
            $gmt_conversion = convert_to_gmt($xy_unix, $event_timezone);

            // define Users Timezone UP1
            $user_timezone = 'UP1';
            // define daylight(isnt used in this example)
            $daylight_saving = TRUE;
            // convert Event in GMT Time to timezone UP1
            $xu = gmt_to_local($gmt_conversion, $user_timezone);
            echo'----&gt; Output Time in Users Timezone UP1:  ';
            echo unix_to_human($xu);

Hi brototyp,

I ws gng t gv my ntr rspns n sndx frmt, jst s y knw hw nyng t s .. but thought better of it, and hope that you stop abbreviating somebody as sb and something as south. Err, sth.

Anyhoo ..

I think you are on the right track with this approach:
Quote:2)Store Event dates in Database in UTC (GMT) and in unix format.

GMT is effectively the same as UT and UTC for the purposes of this discussion (unless you require something finer than 1s accuracy). You are unlikely to, however, unless you are quite particular. The Berlin reference suggests this is a possibility Wink

In any case, let us proceed blissfully ...

The description of the process you are aiming at is spot on, insofar as how I'd approach it. The DB records everything in GMT, and the application translates information back to the local timezone on the fly.

Timezone management is a bit problematic, though, as evinced by rapid changes (by which I mean < 2 months advanced warning for DST changes) over the past few years - the first biggy for me was 2k, with the advancement of DST by about 2 months for the Olympics in Sydney, but it happened again about 18 months ago where a timezone (well, DS) change occured with only a few months notice. How you acquire the TZ information is a bigger question, and depends to some degree on what OS you're on.

I digress.

The rest of your approach - users set their own TZ (presumably with the option to incorporate daylight savings in there - as some timezones argue about DS policy) - and so on, all makes good sense.

When you talk about 'sql format', are you talking about MySQL format for DATETIME or TIMESTAMP? Perhaps you should just consolidate on ISO 8601 - a quite fine format now the bugs have been ironed out.

Quote:For my introducing example: 1PM in New York - 7 PM in Berlin I get the right result(6 hours between New York and Berlin), but when i now use the Daylight_Saving Settings -> TRUE, my result turns into wrong (8 hours between New York and Berlin) !!!!!

I haven't cranked up the source you've provided, but will try to get to that tomorrow - to test on my system. It seems particularly odd - as you've observed - that it would screw up somehow, looking as though it's double-dipping on the DST affect.

Can you do a DB dump of the information going in, and the information taken (from a CLI) from the DB for those date fields, to give a hint on where the DST is getting added the second time?

Quote:But thinking about it daylight_saving settings can't be neglected, or can they ????.

Don't neglect DST. Novell did about 18 months ago, and pissed off several million people. Small-fry compared to the people they've annoyed in the previous decade, of course ...

I'm sure whatever problems you're seeing are reproducible and resolvable.

Quote:My servers (local) timezone is set Europe/Berlin but also changing this to in the php.ini to GMT didn't have any effects (I think it shouldnt because my solution doesnt need the servers time !?) I also set the config.php to $config['time_reference'] = 'GMT';

The server should be set to GMT in its hardware clock, but will have its own local timezone understanding (if it's a real OS, of course).

Hi jedd,
first i want to say thank you for your fast reply. I appreciate that :exclaim:
I'm very happy to here that the idea of my approach is correct, so all these days reading and banging my head against a wall wasn't useless ;-P

Before I tell you about my database construction I have to make some adaption to my description about the problem, that I want to solve. I mean the problem is the same but my description wasn't quite correct.

What i want to do is to build a memorization tool for users (Europe Timezone UP1). European users can add events (online events, for example: Multiplayer Games) from a other timezone which are mostly in ET (Eastern Time, which I think is UM5 Timezone). The European user add the event in UM5, and my tool should display this event in the Eurpean Time --&gt; UP1.

Example: There is an online event in UM5 timezone. The Eurpean user adds the event and my tool should give him the correct time in his timezone, so he knows exactly when to meet up online.

I uploaded a version to my server, where you can log in, add an event and see the result.
(I think this way is more easy to explain ......... :coolsmile: ) That's the link
username: dude2 password: dude2

Everything works perfectly so far. The user adds the event date which is in UM5 and the date displayed for him is in UP1. (Eventdate UM5 which is saved in DB in GMT and which is converted to users timezone .....) If there weren't any Day Saving Times on globe, this post here would be unnecessary :lol: , I come to that part later.

The table for a user look like this:

userid[bigint(20)]<- Primary key <- auto increment, username[varchar(50)], password[varchar(50)], email[varchar(50)], key[varchar(50)], timezone[varchar(5)]

The table for the events look like this:

eventid[bigint(20)]<- Primary key <- auto increment, userid[bigint(20)], name[varchar(50)], desc[varchar(50)], date[datetime], client[varchar(50)];

There is also an client table. By adding an event the user chooses a client in which the information about the timezone is saved (in my case usually UM5). The client table looks like this:

clientid[bigint(20)]<- Primary key <- auto increment, name[varchar(50)], timezone[varchar(50)]

I also give you acces to my database, that you can log in and see how I build it:

Here is the link to my database

Username: sql7940_990243
Password: afterglow

Here is what I do in my controller, when a user adds an event the date and the event information is added to the database. Please don't laugh about my code, I'm still new in PHP (programming) and I have a feeling that what I do can be made much more elegant, but it works.... :coolsmirk:

$xy = $mydatum.$stunde.$minute.'00'; //
            $xy_unix = mysql_to_unix($xy); // here I make the date unix
            // know I need to know what timezone this date is in
            //I pull this information out of the client table in database
            $client = $this->input->post('client');      
            $this->db->where('name', $client);
            $query = $this->db->get('client')->row();
            // here i got the timezone information from the event
            $event_timezone = $query->timezone;
            // now I convert my date to GMT
            $gmt_conversion = convert_to_gmt($xy_unix, $event_timezone);
            // I make this unix timestamp in SQL format again
            // that I can save it in SQL datetime
            $date = unix_to_human($gmt_conversion, TRUE, 'eu');
            // other varibles from the form input
            $eventname = $this->input->post('eventname');
            $client = $this->input->post('client');
            $desc = $this->input->post('desc');
            $data = array(
               'userid' => $this->session->userdata['userid'] ,
               'name' => $eventname ,
               'desc' => $desc,
               'date' => $date,
               'client' => $client
            // I update event table in database with the event information
            $this->db->insert('event', $data);
            redirect ('home');


Here is what I do in my controller when the users shows the events.

function index()
        $uid = $this->session->userdata['userid'];
        $this->db->where('userid', $uid);
        $this->db->order_by("date", "asc");
        $data['eventdata'] = $this->db->get('event');
        $this->load->view('home', $data);

Here is my view to show the events. I do a little controller stuff here (Take the GMT date and make it to UP1). I know I shouldn't do this in the view but I don't know better at the moment. :roll:

&lt;?php foreach($eventdata->result() as $row):
// get all Eventdates from table Event from the User and make them unix
$date_unix = human_to_unix($row->date);
// Timezone From the User from session
$timezone = $this->session->userdata['timezone'];
// make the GMT Eventdates from Database to users Timezone
$date_timezone = gmt_to_local($date_unix, $timezone);
// make the Eventdate Human again
$date = unix_to_human($date_timezone, TRUE, 'eu');

// ----&gt; View the date
<div class="event">
<div class="event_dmy">
<div class="event_m">&lt;?php echo date("M",strtotime($date));?&gt;</div>
<div class="event_d">&lt;?php echo date("d",strtotime($date));?&gt;</div>
<div class="event_y">&lt;?php echo date("Y",strtotime($date));?&gt;</div>
<div class="event_time">&lt;?php echo date("H:i",strtotime($date));?&gt;</div>
<div class="event_details">
<div class="event_name">&lt;?=$date?&gt;</div>
<div class="event_name">&lt;?=$row->name?&gt;</div>
<div class="event_client">&lt;?=$row->client?&gt;</div>
<div class="event_desc">&lt;?=$row->desc?&gt;</div>
&lt;?php endforeach; ?&gt;

I was running out of characters, so I had to do a new post.

Now to my DST problem. It's confusing me.

In my code I din't worry about any DST. I added an event with the current UM5 time.
The date was displayed correctly in UP1 in my current time.

When I use the DST option in my controller when I convert my date to GMT time
$gmt_conversion = convert_to_gmt($xy_unix, $event_timezone, TRUE);
and use it in the view to make the date UP1 then I get a false return.
$date_timezone = gmt_to_local($date_unix, $timezone, True);

I insert the current UM5 time then the UP1 is 1 hour later the it should be.

Here is a link to a website where you get the current times of different timezones.

In both timezones there is DST at the moment --&gt; Daylight saving time: +1 hour
although I didn't use DST it worked. ??? I mean I understand that the difference (6 hours) between both timezones is correct, because both timezones got DST at the moment.

I ask myself what would happen if the DST changes in one timezone. (I think UM5 changes two or three weeks earlier then UP1) Would my result be the same when somebody would add an event in this gap ???

Maybe I get anything wrong with setting the DST time option ..... I don't know.

I'm confused Greetings brototyp

Wow .. lengthy. Not that I don't write lengthy posts, just I get confused when other people do Smile

Okay, I'm still digesting this, as I'm about to have a similar problem, and hadn't really cleared up in my mind how I'd approach it (I was still grasping with the best way to record this data and tie it back to my user table). So at the moment I'm a bit in the dark on the best way forward ...

What I do have are a couple of suggestions - one on point, and one not. The latter first. Nothing to worry about with your code - I used to write code like this, and probably still do. I can give you a couple of words of advice there to make your life easier.

Put a blank line above every comment or comment block. It'll make your code look as neat and spacious as everyone else's. Wink

Don't comment things like this, your function name tells you everything you need to know. Just leave a blank line above and beneath it if you want to highlight the profoundly important nature of the command (as opposed to an $x += 5 line Wink .

// now I convert my date to GMT
$gmt_conversion = convert_to_gmt($xy_unix, $event_timezone);

Now, the on point bit. I did start to look into this for my own app a while ago, and then got side-lined by country code (alpha-2) stuff, and hunting down similar sets of data to your timezone web page (I found another of those myself somewhere .. pointed off wikipedia perhaps). Anyhoo, I decided the best thing to do was to pilfer someone else's code, and so I looked around at how others do it. I think the best one (read: most easily comprehensible by me) I found was the approach Moodle uses.

Happily Moodle is GPL (from memory - or at least a close approximation of same).

I'd suggest you have a squizz at how they've done it. Grab the tarball, and specifically check out:
/lib/timezones.txt     // this has its formatting listed at the top, and is 1940 lines long!  example follows:

Their /lang/en_utf8/timezones.php seems to be a much shorter version of similar information, but haven't looked into that. The interesting files for you and me are going to be /admin/timezoneimport.php and /admin/timezone.php

Anyhoo, have a look through those to see if they're of any help while I ponder, albeit apparently quite sedately, on the greater issue of resolving bugs with DST handling.

brototyp = knauber

Theme © iAndrew 2016 - Forum software by © MyBB