/    Sign up×
Community /Pin to ProfileBookmark

displaying date/time as local to a browser

I have the problem which I assume isnt that uncommon in php; I need to display a timestamp in a browser that is local to the browser’s timezone (i.e. not local to the server).

Lets say for example that the browser is using EST. The timezone of the server is irrelevent since I will just use the unix timestamp (seconds since Jan 1st 1970) which is independent of zone. I can get the timezone of the browser with javascript, that is not an issue.

What I need is a function that can take a unix timestamp and a specific timezone and output it as a local time to that timezone. The date() function does this, except it assumes that the timezone to use is the timezone that the server is using. There is the option to use putenv(“TZ=EST”) to “temporarily” set the environment timezone variable to the timezone of the server before calling date() and it “should” only affect it for that script, but I really doesn’t seem safe to mess with environment variables.

I cant just add/substract a fixed number of seconds offset from the unix timestamp to correct this since that number is not really constant (ie EST is 5 hours off in the winter and 4 hours off in the summer) and I need to display past times from any part of the year in reports, which need to be correct and not an hour off if you skip over a daylight savings hump.

If anyone has a solution I would be very grateful.

to post a comment
PHP

14 Comments(s)

Copy linkTweet thisAlerts:
@NogDogNov 14.2007 — Well, first you need to know what the client's local timezone is. Your three basic choices are to guess from the IP address (requires an appropriate IP-to-location database and will probably never be 100% correct), have the user manually select his local timezone (perhaps as part of a registration process), or using JavaScript (or any other client-side technology that can get the client's local time data).
Copy linkTweet thisAlerts:
@dave17authorNov 14.2007 —  I can get the timezone of the browser with javascript, that is not an issue.

...

What I need is a function that can take a unix timestamp and a specific timezone and output it as a local time to that timezone. The date() function does this, except it assumes that the timezone to use is the timezone that the server is using. [/QUOTE]


I already specified that getting the user's timezone is not the issue and what my exact problem is.
Copy linkTweet thisAlerts:
@TJ111Nov 14.2007 — Like this?
[code=php]
date_default_timezone_set('US/Eastern');
//rest of script
[/code]
Copy linkTweet thisAlerts:
@dave17authorNov 14.2007 — Well it works, but it seems to be a wrapper for putenv("TZ=*") in which case I am not sure how safe it is to use.
Copy linkTweet thisAlerts:
@bokehNov 14.2007 — [code=php]// Javascript
var $user_offset = (new Date().getTimezoneOffset()/60)*(-1);
[/code]

You need to grab the user offset at the time of the transaction and store it in the DB along with the record. Then to recreate the date do this:
[code=php]// PHP (server config irrelevant)
$date = gmdate("d/m/Y H:i:s", $unix_timestamp + $user_offset * 3600);[/code]
Copy linkTweet thisAlerts:
@TJ111Nov 14.2007 — I would think it's safer, as its only changing the timezone in the script that is currently running, where petenv is changing an environment variable. I'm not a good source on that though.
Copy linkTweet thisAlerts:
@dave17authorNov 14.2007 — [code=php]// Javascript
var $user_offset = (new Date().getTimezoneOffset()/60)*(-1);
[/code]

You need to grab the user offset at the time of the transaction and store it in the DB along with the record. Then to recreate the date do this:
[code=php]// PHP (server config irrelevant)
$date = gmdate("d/m/Y H:i:s", $unix_timestamp + $user_offset * 3600);[/code]
[/QUOTE]

This is a completely different solution than the one I am asking for and doesnt have any use for me, changing the whole database structure isnt an option. Even so, the user offset at the time of the transaction has no significance to my application since the transaction isnt made by the user, it is made through something else that could be in an arbitrary timezone to the user.
Copy linkTweet thisAlerts:
@dave17authorNov 14.2007 — I would think it's safer, as its only changing the timezone in the script that is currently running, where petenv is changing an environment variable. I'm not a good source on that though.[/QUOTE]

Thanks, I'm trying to google the function the best I can. I'm getting some funny results when testing my conversion function though lol. One main thing is that I need the conversion to be fast since it will need to do thousands+ at a time. For some reason, I dont know why, date_default_timezone_set() is actually SPEEDING UP my results:

[CODE]
$start = time() + microtime();

for ($i = 0; $i < 10000; $i++)
{
}

$end = time() + microtime();
echo $end - $start;
[/CODE]


^^ result is 0.00139307975769 seconds

[CODE]$start = time() + microtime();

for ($i = 0; $i < 10000; $i++)
{
$tz = date_default_timezone_get();
}

$end = time() + microtime();
echo $end - $start;
[/CODE]


^^ result is 0.209137916565 seconds

[CODE]
$start = time() + microtime();

for ($i = 0; $i < 10000; $i++)
{
$tz = date_default_timezone_get();
date_default_timezone_set("US/Eastern");
}

$end = time() + microtime();
echo $end - $start;
[/CODE]


^^ result is 0.0125279426575 seconds

So the empty loop takes next to no time as expected. Getting the default timezone takes 0.2 seconds. But getting the default timezone and then setting it takes 0.012 seconds.

(... well the results are interesting, but I think I figured out why it is doing this. The first time date_default_timezone_get() is called it has to look it up somewhere outside of the script which takes a bit of time, but once date_default_timezone_set() has been called, it can then look it up in the script which is why it goes so much faster after it is called.)
Copy linkTweet thisAlerts:
@TJ111Nov 14.2007 — You should set it before the function call, that is if each loop is using the same timezone. Once it is set once, as long as the script is being executed, it will act like that is its current timezone.

date_default_timezone_get() get's the default timezone set in the php.ini (or maybe httpd.conf, I don't remember), so thats what is taking so long.
Copy linkTweet thisAlerts:
@dave17authorNov 14.2007 — Yea, I just need to call date_default_timezone_get() in the function so I can reset it back to what it should be for the rest of the script. After the function is called once though, it doesnt need to look it up in php.ini again the next time.
Copy linkTweet thisAlerts:
@bokehNov 14.2007 — How is getting the current offset for a timezone going to tell what the offset was last week or 6 months ago?
Copy linkTweet thisAlerts:
@dave17authorNov 14.2007 — The current offset (i.e. in seconds) doesnt tell you what the offset was 6 months ago, which is why I get the timezone identifier (i.e. UTC, EST, PST) from the javascript and use that since php can look up the daylight savings rules for that timezone. Anyways, all times are stored as UTC so my only concern was to display it in a way that makes sense to the user.
Copy linkTweet thisAlerts:
@bokehNov 14.2007 — I know this is not answering your question but: Why not just output the timestamp to the client and have javascript on the client format it. That way your script doesn't need to know anything about the client?
Copy linkTweet thisAlerts:
@dave17authorNov 14.2007 — Because I also use php to write reports as excel files which the client can then download, so Javascript cant be used there.
×

Success!

Help @dave17 spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.26,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...