Re: DateTime using DateTimeZone Timestamp problem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 4 April 2011 16:35, Ian <php_list@xxxxxxxxxxxxx> wrote:
> Hi,
>
> I have a problem using the php built in classes DateTime and DateTimeZone.
>
> The idea behind the following code is to return the timestamp for the
> current time in Singapore (or other places). ÂWhat it actually returns
> is the timestamp for the local system. Other formatted dates appear to
> return correctly, which is why I am puzzled.
>
> I am using the latest php 5.3.6 compiled from source on a OpenVZ CentOS
> container. All packages are up to date.
>
> Am I doing something wrong or is this a bug?
>
> I can workaround this problem my parsing the correctly formatted date
> using strtotime() but I would like to know what's going on.
>
>
>
> This is the output of the script:
>
> Â Â Â ÂCurrent time in Asia/Singapore is 2011-04-04 23:32:36
> Â Â Â ÂTimestamp for Asia/Singapore is 1301931156
> Â Â Â ÂDate created from previous timestamp is 2011-04-04 16:32:36
>
> The code is :
>
> <?php
>
> $timezone="Asia/Singapore";
>
> # Create Timezone object
> $remote_timezone    Â= new DateTimeZone($timezone);
>
> # Create datetime object
> $remote_time      Â= new DateTime("now" , $remote_timezone);
>
> # Print the date
> print "Current time in {$timezone} ";
> print "is {$remote_time->format("Y-m-d H:i:s")}<br/>";
>
> # Print the timestamp
> print "Timestamp for {$timezone} ";
> print "is {$remote_time->format("U")}<br />";
>
> # Get the timestamp and create a date from it
> $timestamp = (int)$remote_time->format("U");
>
> # Show the formatted date created from timestamp
> print "Date created from previous timestamp is ";
> print date("Y-m-d H:i:s",$timestamp)."<br/>";
>
> ?>

Timestamps (the integer value) do not hold the timezone data.
Internally, the value represents a number of milliseconds from a point
in time.

So saying "timestamp for Asia/Singapore" isn't right. It is just "Timestamp".

The following script (http://pastebin.com/0MQAaYUq) may show you in a
more concrete way ...

<?php
$a_Times = array(
	'now',
	'2011-03-27 00:59:59',
	'2011-03-27 02:00:00',
);

// Create Timezone objects
$a_Timezones = array(
	'Singapore' => new DateTimeZone('Asia/Singapore'),
	'NewYork  ' => new DateTimeZone('America/New_York'),
	'London   ' => new DateTimeZone('Europe/London'),
	'UTC      ' => new DateTimeZone('UTC'),
);

foreach($a_Times as $s_Time) {
	echo 'Time : ', $s_Time, PHP_EOL;

	// Create datetime objects
	$a_DateTimes = array();
	foreach($a_Timezones as $s_Timezone => $tz_Timezone) {
		$a_DateTimes[$s_Timezone] = new DateTime($s_Time , $tz_Timezone);
	}
	
	// Print the date
	foreach($a_DateTimes as $s_Timezone => $dt_DateTime) {
		echo
			'Current time in ', $s_Timezone, ' : ', $dt_DateTime->format(DateTime::RSS),
			'   Offset : ', str_pad($dt_DateTime->getOffset(), 6, ' ', STR_PAD_LEFT),
			'   Timestamp : ', ($i_Timestamp = $dt_DateTime->getTimestamp()),
			'   Local : ', date(DateTime::RSS, $i_Timestamp), PHP_EOL;
	}
	echo PHP_EOL;
}
?>

outputs (http://pastebin.com/mETSbR7h) ...

Time : now
Current time in Singapore : Tue, 05 Apr 2011 17:56:32 +0800   Offset :
 28800   Timestamp : 1301997392   Local : Tue, 05 Apr 2011 10:56:32
+0100
Current time in NewYork   : Tue, 05 Apr 2011 05:56:32 -0400   Offset :
-14400   Timestamp : 1301997392   Local : Tue, 05 Apr 2011 10:56:32
+0100
Current time in London    : Tue, 05 Apr 2011 10:56:32 +0100   Offset :
  3600   Timestamp : 1301997392   Local : Tue, 05 Apr 2011 10:56:32
+0100
Current time in UTC       : Tue, 05 Apr 2011 09:56:32 +0000   Offset :
     0   Timestamp : 1301997392   Local : Tue, 05 Apr 2011 10:56:32
+0100

Time : 2011-03-27 00:59:59
Current time in Singapore : Sun, 27 Mar 2011 00:59:59 +0800   Offset :
 28800   Timestamp : 1301158799   Local : Sat, 26 Mar 2011 16:59:59
+0000
Current time in NewYork   : Sun, 27 Mar 2011 00:59:59 -0400   Offset :
-14400   Timestamp : 1301201999   Local : Sun, 27 Mar 2011 05:59:59
+0100
Current time in London    : Sun, 27 Mar 2011 00:59:59 +0000   Offset :
     0   Timestamp : 1301187599   Local : Sun, 27 Mar 2011 00:59:59
+0000
Current time in UTC       : Sun, 27 Mar 2011 00:59:59 +0000   Offset :
     0   Timestamp : 1301187599   Local : Sun, 27 Mar 2011 00:59:59
+0000

Time : 2011-03-27 02:00:00
Current time in Singapore : Sun, 27 Mar 2011 02:00:00 +0800   Offset :
 28800   Timestamp : 1301162400   Local : Sat, 26 Mar 2011 18:00:00
+0000
Current time in NewYork   : Sun, 27 Mar 2011 02:00:00 -0400   Offset :
-14400   Timestamp : 1301205600   Local : Sun, 27 Mar 2011 07:00:00
+0100
Current time in London    : Sun, 27 Mar 2011 02:00:00 +0100   Offset :
  3600   Timestamp : 1301187600   Local : Sun, 27 Mar 2011 02:00:00
+0100
Current time in UTC       : Sun, 27 Mar 2011 02:00:00 +0000   Offset :
     0   Timestamp : 1301191200   Local : Sun, 27 Mar 2011 03:00:00
+0100


Getting the the timestamp for a DateTime object will return the
timestamp appropriately converted to the local timezone.

If you don't want to lose the timezone, then don't use the timestamp.

This, of course, is an issue if you want to use datetimes in a DB.

In these instances, converting the datetime to UTC and storing the
timezone separately is certainly one option.

If you are using SQL Server 2008, then there is a column type of
DATETIMEOFFSET which is a datetime column with Timezone and
100nanosecond accuracy, so you can store and use datetimes like ...

2007-05-08 12:35:29.1234567 +12:15

Which is a pretty accurate.

I guess there is some difference in logic between knowing the timezone
and the timezone offset.

I found the talk by Derick Rethans very useful : (looking for this but
can't find it any more. The link to it is
http://www.phparch.com/2009/08/dont-miss-todays-webcast-on-date-manipulation/

A book is also available :
http://www.phparch.com/books/phparchitects-guide-to-date-and-time-programming/

I

-- 
Richard Quadling
Twitter : EE : Zend
@RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php




[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux