I'm having a problem with PHP's gmstrftime() function.
Please look:
<?
$ts[]=1348573985; // '2012-09-25 13:53:05' (date returned from mysql's from_unixtime() function)
$ts[]=1233958620; // '2009-02-06 23:17:00' (date returned from mysql's from_unixtime() function)
foreach($ts as $t) {
echo $t." => ".gmstrftime( "%d %B %Y - %H:%M", $t )."\n";
}
?>
Output will be:
1348573985 => 25 September 2012 - 11:53
1233958620 => 06 February 2009 - 22:17
As you can see, the first timestamp is 2 hours off (from mysql's output), which is normal because of timezone settings. But the second one is only 1 hour off but I did not change the timezone between the two gmstrftime() call's??
Is this a bug in PHP's gmstrftime() function, or anything else?
From the manual for gmstrftime:
Behaves the same as strftime() except that the time returned is Greenwich Mean Time (GMT).
Greenwich Mean Time is the same all year around. This is different from the local time in the UK, which is set as GMT in winter, but "British Summer Time" (GMT+1, i.e. one hour ahead of GMT) in the summer. The same happens in Western Europe, which is GMT+1 in winter, but GMT+2 in summer.
Your MySQL database is presumably configured for local European time, so when converting a Unix timestamp that occurs during the summer, it adds an extra hour to line up with the Summer Time adjustment.
In my opinion, the best policy is to set all your systems to use 'UTC' (basically the same as GMT) and then convert to a local timezone "at the last minute". You could standardise on some other timezone, but UTC acts as a good baseline for debugging.
Related
I just want to check if time() returns a UTC/GMT timestamp or do I need to use date_default_timezone_set()?
time returns a UNIX timestamp, which is timezone independent. Since a UNIX timestamp denotes the seconds since 1970 UTC you could say it's UTC, but it really has no timezone.
To be really clear, a UNIX timestamp is the same value all over the world at any given time. At the time of writing it's 1296096875 in Tokyo, London and New York. To convert this into a "human readable" time, you need to specify which timezone you want to display it in. 1296096875 in Tokyo is 2011-01-27 11:54:35, in London it's 2011-01-27 02:54:35 and in New York it's 2011-01-26 21:54:35.
In effect you're usually dealing with (a mix of) these concepts when handling times:
absolute points in time, which I like to refer to as points in human history
local time, which I like to refer to as wall clock time
complete timestamps in any format which express an absolute point in human history
incomplete local wall clock time
Visualise time like this:
-------+-------------------+-------+--------+----------------+------>
| | | | |
Dinosaurs died Jesus born Y2K Mars colonised ???
(not to scale)
An absolute point on this line can be expressed as:
1296096875
Jan. 27 2011 02:54:35 Europe/London
Both formats express the same absolute point in time in different notations. The former is a simple counter which started roughly here:
start of UNIX epoch
|
-------+-------------------+------++--------+----------------+------>
| | | | |
Dinosaurs died Jesus born Y2K Mars colonised ???
The latter is a much more complicated but equally valid and expressive counter which started roughly here:
start of Gregorian calendar
|
-------+-------------------+-------+--------+----------------+------>
| | | | |
Dinosaurs died Jesus born Y2K Mars colonised ???
UNIX timestamps are simple. They're a counter which started at one specific point in time and which keeps increasing by 1 every second (for the official definition of what a second is). Imagine someone in London started a stopwatch at midnight Jan 1st 1970, which is still running. That's more or less what a UNIX timestamp is. Everybody uses the same value of that one stopwatch.
Human readable wall clock time is more complicated, and it's even more complicated by the fact that it's abbreviated and parts of it omitted in daily use. 02:54:35 means almost nothing on the timeline pictured above. Jan. 27 2011 02:54:35 is already a lot more specific, but could still mean a variety of different points on this line. "When the clock struck 02:54:35 on Jan. 27 2011 in London, Europe" is now finally an unambiguous absolute point on this line, because there's only one point in time at which this was true.
So, timezones are a "modifier" of "wall clock times" which are necessary to express a unique, absolute point in time using a calendar and hour/minute/second notation. Without a timezone a timestamp in such a format is ambiguous, because the clock struck 02:54:35 on Jan. 27 2011 in every country around the globe at different times.
A UNIX timestamp inherently does not have this problem.
To convert from a UNIX timestamp to a human readable wall clock time, you need to specify which timezone you'd like the time displayed in. To convert from wall clock time to a UNIX timestamp, you need to know which timezone that wall clock time is supposed to be in. You either have to include the timezone every single time with each such conversion, or you set the default timezone to be used with date_default_timezone_set.
Since PHP 5.1.0 (when the date/time functions were rewritten), every
call to a date/time function will generate a E_NOTICE if the timezone
isn't valid, and/or a E_WARNING message if using the system settings
or the TZ environment variable.
So in order to get a UTC timestamp you should check what the current timezone is and work off of that or just use:
$utc_str = gmdate("M d Y H:i:s", time());
$utc = strtotime($utc_str);
http://us3.php.net/time
"Returns the current time measured in the number of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)."
So I believe the answer to your question is yes.
From the documentation
Returns the current time measured in the number of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT).
One of the comments claimed: "both time() and strtotime(gmdate("M d Y H:i:s", time())) return the same result"
Since I wasn't sure about that, I ran a test:
$now = strtotime(gmdate("Y-m-d H:i:s", time()));
$now2 = time();
echo ' now='.$now.' now2='.$now2.' diff='.($now - $now2);
Output was:
now=1536824036 now2=1536806036 diff=18000
Diff is 18000 seconds = 5 hours = the timezone offset for the server running the test.
I am using strtotime() to get a timestamp from a date and time string. I will be running strtotime() during the summer (daylight savings) to give me a timestamp of a winter date (non-daylight savings).
In the winter, I will need to convert my timestamp to a readable date using date() -- will it be the same date/time I put into strtotime() during the summer?
On each one of my pages, I am setting my timezone by date_default_timezone_set with my city.
So, running this during the summer (daylight savings):
date_default_timezone_set('America/Los_Angeles');
echo strtotime("Dec 1 2014 8:00 am");
Gives me a certain timestamp 1417449600.
Will running this during the winter (non-daylight savings) return 8:00am as I need it to do?
date_default_timezone_set('America/Los_Angeles');
echo date("g:ia",1417449600);
Yes. If the timezone you set is doesn't explicitly say whether it's standard or daylight-savings time, it automatically determines the state of DST from the time that you give it and the rules for when the timezone switches into and out of DST.
Yes. A UNIX timestamp such as 1417449600 represents a completely, globally, universally unique point in time, independent of fussy timezone notation. There's only one "December 1st 2014 8 am in Los Angeles", which is the same point in time as "December 1st 2014 17:00 CET" and a number of other local notations across the world. The UNIX timestamp 1417449600 expresses that point in time, regardless of whatever your wall clock says exactly.
When you format this unique point in time back to a more human readable format using date(), it figures out what exactly the time must be formatted at based on the set timezone. It won't change based on what the time or DST settings are now.
I am trying to convert a human-readable time of 7am into a timestamp in PHP for calculation and manipulation purposes. The timestamp gets created correctly as 25200, but the date() function strangely converts the timestamp back to 08:00 when I use London as the timezone, 08:00 (correctly) when using Berlin, but 09:00 when using Athens.
I cannot understand why it does not return 07:00 and why it should be the same as Berlin. My server is in Germany and I am in London, might that have something to do with it? Hardly, since I have the same problem on my XAMPP stack here in London on my laptop.
date_default_timezone_set('Europe/London');
$time_readable = 7;
$time_stamp = $time_readable * 60 * 60;
echo $time_stamp;
echo date('H\:i',$time_stamp);
I even preceded my code with
date_default_timezone_set('UTC');
date_default_timezone_set('Europe/London');
but the problem persists.
What have I overlooked?
My PHP version on the server is 5.2.12 on the German production machine and 5.3.1 on my UK laptop XAMPP stack.
You seem to have a fundamental misunderstanding of what a timestamp is and how they work. You are also not understanding DST properly as it is laced with political changes to how it is applied.
However, to answer your specific question
I cannot understand why it does not return 07:00 and why it should be the same as Berlin.
Your timestamp represents 07:00 UTC on 1st January 1970. The reason setting the timezone to 'Europe/London' changes the time to 08:00 is because the UK was running the British Standard Time experiment which kept the UK on UTC + 1 from 27 October 1968 to 31 October 1971. Therefore the local time in London at 07:00 UTC on 1st January 1970 was 08:00.
I would recomend that your timestamps should always be complete timestamps that represent the full date and time. Trying to represent times only is the road to pain.
I also recomend learning to use the DateTime classes as they will handle all of this for you transparently.
I am using strtotime to convert a date to a unixtime stamp.
Year, date and day comes as different values to code and I am using the below code to produce the timestamp.
$year = '1961';
$month = '2';
$day = '15';
$date = $year."-".$month."-".$day;
echo strtotime($date);
The above code prints : -27648000 for me. If the year is above 1970 it prints out positive results. I am still learning with the timestamp, if any one can help me out. The main aim is to convert a date to unix timestamp.
The questions is why it gives negative results, Am I coding it bad!? I am also tried mktime, but still the same result.
Thanks,
Tanmay
It's to do with the Unix Epoch.
See: date() and time()
The valid range of a timestamp is typically from Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT. (These are the dates that correspond to the minimum and maximum values for a 32-bit signed integer). However, before PHP 5.1.0 this range was limited from 01-01-1970 to 19-01-2038 on some systems
That's the expected behavior.
strtotime returns a UNIX timestamp, the number of seconds since Jan 1 1970 (not considering leap seconds). For dates before that, it will return a negative number.
Unix time starts at the Unix epoch which is Midnight on Jan 1, 1970. So any date before that will result in a negative value being returned.
This is a Unix timestamp. The Unix/PHP base date is January 1, 1970 at 00:00 UST, and the timestamp is measured in seconds. If negative, it is the number of seconds before the base date; if positive, the number of seconds after
I am still learning with the timestamp,
google unix timestamp -> http://en.wikipedia.org/wiki/Unix_time
defined as the number of seconds elapsed since midnight proleptic Coordinated Universal Time (UTC) of
January 1, 1970
http://en.wikipedia.org/wiki/Unix_time
Unix time, or POSIX time, is a system for describing points in time, defined as the number of seconds elapsed since midnight proleptic Coordinated Universal Time (UTC) of January 1, 1970, not counting leap seconds. It is used widely, not only in Unix-like operating systems, but also in many other computing systems and file formats. It is neither a linear representation of time nor a true representation of UTC (though it is frequently mistaken for both), as the times it represents are UTC but do not represent standard UTC leap seconds (e.g. December 31, 1998 23:59:60)...
Times before 1/1/1970 are negative values as they occured before the start of UTC.
Every time in PHP when I make a variable such as this one:
$date = strtotime($row['date']);
$date = date("M d Y \a\\t g:i A", $date); // Mmm dd YYYY at h:mm PM/AM
and somehow row['date'] happens to be 0, the date Dec 31 1969 at 7:00 PM is displayed on the screen? Google does not tell me much, I was wondering if this date had any significances.
The Unix epoch is the time 00:00:00 UTC on 1 January 1970. This is the reference point for all time stamps. When you use PHP's date/time functions, you're always working with the number of seconds since the epoch. Time 0 is the epoch, and you (or your web server) must be on the east coast of the US, which is 5 hours behind UTC time.
I find it funny that not a single response here attempted to answer your actual question, which was (if I can paraphrase) "What is the significance of the actual date of Unix epoch time"?
I'm not an expert on the subject but basically, as I understand it, the concept of epoch time was invented in 1971. The programmers chose the arbitrary date of January 1, 1971 GMT to be epoch time. This was partly due to the fact that older computers couldn't handle large numbers so the date had to be in the recent past. Afterwards, epoch time was adjusted to be Jan 1, 1970 so as to be a nice, round number.
So basically, nothing "happened" on that date. It was an arbitrary date chosen based on the original time of the work being done.
Unix timestamps are measured in "time since the Unix Epoch", which is Midnight GMT at the end of Dec. 31 1969 (a.k.a. 00:00 GMT Jan 1 1970). Since you appear to be on Eastern Standard Time, which is GMT-5, you get 7pm Dec. 31st 1969 for a unix timestamp value of 0.
Let me guess: you live on the east coast of the USA?
PHP, like many other systems uses the Unix epoch to measure time, i.e. a value of 0 represents January 1, 1970, midnight UTC - which is the same as Dec 31 1969 at 7:00 PM Eastern Standard Time.
One format in which date objects are stored is the time in seconds that have elapsed from an arbitrary start time. Asking for a formatted version of "0" is like asking for that arbitrary start time. I don't remember why that date was chosen, but I'm sure Wikipedia does. See the article on Unix time below.
Read about Unix Time