I'm working on some time related features and I opt to always use UTC times and store time stamps as integers for consistency.
However, I noticed that when I use mktime it seems that the currently set time zone has an influence of the return value of mktime. From the documentation I understand that mktime is supposed to return the number of seconds since epoch:
Returns the Unix timestamp corresponding to the arguments given. This
timestamp is a long integer containing the number of seconds between
the Unix Epoch (January 1 1970 00:00:00 GMT) and the time specified.
http://php.net/manual/en/function.mktime.php
However, it seems that mktime is including the time zone that is currently set. When using the following code:
date_default_timezone_set('UTC');
$time = mktime(0, 0, 0, 1, 1, 2016 );
echo "{$time}\n";
date_default_timezone_set('Australia/Sydney');
$time = mktime(0, 0, 0, 1, 1, 2016 );
echo "{$time}\n";
I would expect the two time vales to be same but apparently they are not:
1451606400
1451566800
Which seems to be exacly an 11 hour difference:
1451606400 - 1451566800 = 39600 / (60*60) = 11
What do I not understand correctly about mktime and/or why is the time zone taken into account when using mktime?
I can't tell you why it is the way it is (PHP has never made sense to me when it comes to date and time) but there is an alternative function gmmktime() which is
Identical to mktime() except the passed parameters represents a GMT date. gmmktime() internally uses mktime() so only times valid in derived local time can be used.
There is also a comment on the PHP documentation for this function which explains how mktime(), gmmktime() and time() work. Essentially, they assume that you always think in time zones even if a UNIX timestamp itself doesn't carry a timezone.
Resulting Unix timestamp are indeed encoded in a timezone agnostic way, but input arguments are interpreted relative to the timezone set for current process. And indeed, Sidneys 2016-01-01 00:00:00 (GMT+11) happened 11 hours before UTC 2016-01-01 00:00:00.
When some foreigner tells you a time, you have to know its time zone to correctly interpret it, and so does mktime().
If dates you want to pass to mktime() are UTC dates, then use gmmktime() which exists for that purpose.
Related
This question already has answers here:
Convert one date format into another in PHP
(17 answers)
Closed 4 years ago.
I have a DB that shows when the user made the last login but then it shows 1542575966120. I wanted it to show so 18/11/2018 19:00
I tried using this in php
$intDate = "20". $ infologado ["lastlogin"];
$newDate = date ("d-m-Y", strtotime ($ intDate));
but I could not.
sorry for English
So as #Taha Paksu had mentioned, these numbers are a timestamp (seconds since 1 January 1970). Try this code:
$intDate = 1542575966120;
$newDate = date('d/m/Y H:i', $intDate/1000);
It is in miliseconds, date function accepts seconds, thus the division by 1000. Also no need to put it into strtotime, because this function is meant to convert string dates to... said numeric timestamps.
In your case, you can put $intDate = $infologado['lastlogin']; instead of first line to get the result dynamically from the database.
First of all, you need to learn what a timestamp is. The timestamp is a number which shows the seconds passed (or milliseconds, some include the milliseconds too) since epoch (01/01/1970). A general definition can be found here:
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). Literally speaking the epoch is Unix time 0 (midnight 1/1/1970), but 'epoch' is often used as a synonym for 'Unix time'. Many Unix systems store epoch dates as a signed 32-bit integer, which might cause problems on January 19, 2038 (known as the Year 2038 problem or Y2038).
The converter on this page converts timestamps in seconds, milliseconds and microseconds to readable dates.
Taken from: https://www.epochconverter.com/ a tool which you can convert your dates to/from timestamps or vice versa.
Then to answer your question, the system saved the dates as a timestamp to the database to (probably) bypass the formatting errors on each different system that uses it.
Nevermind, TL;DR:
The number shows Sunday, 18 November 2018 21:19:26.120 when you give it to the timestamp converter I mentioned above. With PHP, you can use:
$unixTimestamp = 1542575966120;
$dt = DateTime::createFromFormat("U.u", $unixTimestamp / 1000);
var_dump($dt);
to convert to PHP DateTime class, then you can use it in your application.
This question already has answers here:
Dealing with timezones in PHP
(4 answers)
Closed 9 years ago.
I have some php scripts on a hosting, but hosting time is different from my local time (GMT+8)
How set the right time() script to be GMT+8 ?
When i use:
<?
echo time(); //it show me the hosting time;
?>
time() will always return the number of seconds since the epoch. The code below will print the same twice.
date_default_timezone_set('Europe/London');
echo time();
date_default_timezone_set('America/Cuiaba');
echo time();
The concept of Unix Timestamp does not carry time zone information by design. A given timestamp is always the same regardless of time zone. (The number of seconds since 1970-01-01 00:00:00 UTC) When you want to express a timestamp with time zone taken into account, you will adjust the resulting date with the current time zone's offset.
So when using the 'c' format option to PHP's date (which does reflect time zone information) you will see different representation of the same timestamp
date_default_timezone_set('Europe/London');
echo time();
echo date('c')
date_default_timezone_set('America/Cuiaba');
echo time();
echo date('c');
Will output:
1384259474
2013-11-12T12:31:14+00:00
1384259474
2013-11-12T09:31:14-03:00
Your assumption is not correct:
int time ( void )
Returns the current time measured in the number of seconds since the
Unix Epoch (January 1 1970 00:00:00 GMT).
The Unix Epoch is a fixed moment in time. If you really get an invalid timestamp, your hosting provider has not cared to set the server's clock.
If you want to do decent time zone aware date handling I suggest you learn about the DateTime class and friends and:
Use named time zones (Europe/Madrid) rather than UTC offsets (+01:00) since they take DST into account.
Set your app's time zone as default so you don't need to specify it every time:
date_default_timezone_set("Europe/Helsinki");
Never ever do date math yourself (e.g., don't add 86400 seconds manually to increase a day).
You must set the local time in php
function date_default_timezone_set
List of Supported Timezones
Example:
date_default_timezone_set("America/Fortaleza");
echo time(); // Local Time in America/Fortaleza
Add 28800 (8 hrs converted to seconds) to the output of time()
<?php echo (time()+28800); ?>
I am not sure but, time() returns timestamp which is equivalent to GMT thus, adding timestamp of 8 hours will give you GMT+8. Similarly, you can even subtract the time also
You can use date_default_timezone_set() function, For example
date_default_timezone_set('Asia/Dhaka');
I am working with php and mysql to develop my application. For this application, time plays an important role as I want to show data to my users according to their selected timezone. For this i am using strtotime to convert time into numeric form, but I just noticed that strtotime returns same value for all timezones. I wrote following code to test.
date_default_timezone_set("Asia/Kolkata");
echo date("Y-m-d H:i:s")." ------ ";
echo strtotime(date("Y-m-d H:i:s"))."<br/><br/>";
date_default_timezone_set("America/New_York");
echo date("Y-m-d H:i:s")." ------ ";
echo strtotime(date("Y-m-d H:i:s"));
But output is
2013-01-28 15:40:11 ------ 1359367811
2013-01-28 05:10:11 ------ 1359367811
Why is the return value identical?
strtotime() returns "the number of seconds since January 1 1970 00:00:00 UTC"
As #Bobby's comment states, "Unix Timestamps are always UTC". This means you're essentially making two equivalent conversions to the UTC timezone.
Consider that a t1 timestamp in a1 timezone and the same t1 timestamp in a2 would produce the same result when converted to timezone a3. In your example, the "same result" is in seconds, but the principle is the same.
In other words, in your code you are generating two UNIX timestamps from seemingly two different dates. But what you're actually doing is generating two different but equivalent representations (Asian and American timezones) of the same point in time. You then convert the two equivalent representations to the same third represntation (UTC timezone).
As per PHP manual for strtotime,
The function expects to be given a string containing an English date format and will try to parse that format into a Unix timestamp (the number of seconds since January 1 1970 00:00:00 UTC), relative to the timestamp given in now, or the current time if now is not supplied.
As stated above, strtotime converts a given date format into a Unix timestamp, which is calculated relative to the Unix epoch. The epoch is a fixed point whose definition is independent of the user's timezone, and the number of seconds since then is, relatively, the same in all time zones.
Setting the timezone merely affects the interpretation of the timestamp value.
I am not sure why strtotime() in PHP returns different result in different timezone even though same date is given as parameter, does anyone know the answer? I also want to know, can I do similar task (converting a datetime to an int to do calculations easily) with another function which gives same result across different timezone?
EDIT:
An example:
If I use strtotime('2011-09-19 00:00:00') shouldn't it just return the difference between 'January 1 1970 00:00:00' and '2011-09-19 00:00:00' in seconds ? Why timezone is an issue here? And can I get something which gives just difference without timezone issue?
In short: time zone is considered because the Unix Epoch value is considered in GMT.
In broader sense 2011-09-19 00:00:00 comes to Bangladesh almost after 6 hours it is 2011-09-19 00:00:00 in GMT zone. Because of this gap, another 21600 seconds have passed in the GMT zone when the same date appears in BD.
Since the calculation is done in respect to the GMT, you have to add these 21600 seconds to get the actual difference.
strtotime gives different results in different timezones because it takes timezones into account...
From strtotime's manual:
The function expects to be given a string containing an English date format and will try to parse that format into a Unix timestamp (the number of seconds since January 1 1970 00:00:00 UTC)
This function will use the TZ environment variable (if available) to calculate the timestamp. Since PHP 5.1.0 there are easier ways to define the timezone that is used across all date/time functions. That process is explained in the date_default_timezone_get() function page.
Have a look at mktime().
Since PHP 5.1, you can use date_default_timezone_set before calling mktime or strtotime.
From the PHP manual:
This function will use the TZ environment variable (if available) to calculate the timestamp. Since PHP 5.1.0 there are easier ways to define the timezone that is used across all date/time functions. That process is explained in the date_default_timezone_get() function page.
http://php.net/manual/en/function.strtotime.php
Use date_default_timezone_set before calling date/time functions to choose which time zone you want to work in.
http://www.php.net/manual/en/function.date-default-timezone-set.php
From PHP docs on strtotime:
This function will use the TZ environment variable (if available) to
calculate the timestamp. Since PHP 5.1.0 there are easier ways to
define the timezone that is used across all date/time functions. That
process is explained in the date_default_timezone_get() function page.
Try setting your own time zone.
i think probably there will be one time of each php programmer that this function will make him wants to really understand how actually php works with date and time functions.
funny this function when you try something like...err...for example, assume that today at this very moment is July 11th, 2012 at 13:00:00 (2012-07-11 13:00:00) and then you try strtotime to find exactly the same moment of the day but for tomorrow:
$x = strtotime('2012-07-12 13:00:00');
$y = strtotime('+1 Day');
$z = $x-$y;
$x and $y of the above first 2 lines will not return the same thing even you ignore the minute and second counts but $z will be around 25200 or around 7 hours in the difference between this 2 lines if your sever is in somewhere of the USA that the GMT is -5 hours but you browser calls this function from berlin in summer where the GMT is +2 hours... LOL now you can get the idea how php work with this function ;)
I need to format a UNIX timestamp in GMT format to a local date/time. I'm using gmstrftime to do this and I can get the correct result if I use an offset. I just so happen to know what my offset is for the pacific timezone but I don't want to have to get the correct time like this. I've used date_default_timezone_set so gmstrftime is reporting the correct timezone but the time is off by like a day.
I don't get it. If gmstrftime knows what timezone I'm in, why is the time off?
If you have the correct timezone set (such as with date_default_timezone_set) then you only need to use date() for the formatting, no extra coding. UNIX timestamps are in GMT by definition of a UNIX timestamp -- number of seconds since January 1, 1970 00:00:00 GMT.
gmstrftime will always return the time as UTC, seems like you want strftime.