I have a table with a field of type date within a MySQL database. My user places a date into a field (format dd-mm-yyyy) which I convert into yyyy-mm-dd for insertion into the database. This works fine. I can see the date in there as (for example) 2012-04-04.
My issue is that I then select this record, convert the date to the format I wish to display (dd-mm-yyyy) and get 03-04-2012. I understand why, in that my database is set to UTC, however the user is on Berlin time, therefore 04-04-2012 00:00 in Berlin is 03-04-2012 23:00 UTC.
The issue means that if I then save the displayed date (03-04-2012), the next time I see it, it displays as 02-04-2012 because I saved only the date and therefore the system is assuming a 00:00 time again.
I cannot see a way around this other than setting this as a datetime type rather than a date type, however I would rather not do that as time (for various reasons) is stored in a separate field. Any suggestions?
When you inserting a record you add as datetime current UTC time, after that every user in their profile may want to/or set his timezone.
If you know the timezone of the user u can easy convert the datetime to user locale time. Because you know the differences in hours/minutes between the time.
P.S. You can store the datetime as varchar and save the unix timestamp in this field. Unix timestamp is based on current timezone I think.
UPDATE:
I think that might help
$date = time();
dump(date('d-m-Y H:i:s', $date)); // 03-04-2012 08:43:38
date_default_timezone_set('Europe/London');
dump('London: '. date('d-m-Y H:i:s', $date)); // London: 03-04-2012 11:43:38
date_default_timezone_set('Europe/Berlin');
dump('Berlin: '. date('d-m-Y H:i:s', $date)); // Berlin: 03-04-2012 12:43:38
date_default_timezone_set('Europe/Sofia');
dump('Sofia: '. date('d-m-Y H:i:s', $date)); // Sofia: 03-04-2012 13:43:38
dump function returns '<pre>'. $something .'</pre>';
UTC is the international time standard. It is similar to Greenwich Mean Time (GMT), except that UTC observes no daylight saving time (DST) and is based on a 24-hour clock. Zero (0) hours UTC is midnight GMT. The local 24-hour time convention is converted to UTC by adding or subtracting hours based on location in relation to the prime meridian, as well as local daylight saving time considerations.
First, make sure both time zones are same. Then, don't store in datatime format, use integer. Convert the date to timestamps and then store. Like
$time = time(); //get the current time stamp
//Now insert $time
Now, both places are in common ground, You may do as you like. Changing date among different timezone is rather easy.
echo gmdate("M d Y H:i:s", $time);
Related
I have a table in database named USERSHIFTS and it has two TIME type columns along with other columns first one is it start_time and second one is end_time and both have TIME datatype . i am not allowed to change these columns types to datetime or timestamp. And also not allowed to create another column in table. Now my task is to display time that has been stored in start_time and end_time column according to user timezone for example UTC timezone user should be able to time according to UTC timezone and Other timezone user should also be able to see this time according to his timezone .
Now question is how should i store time in database and in which timezone i should store time. And Final question is how should i display time according to different timezones.
i tried following code but you can see i have to deal with date in order to do this. And i dont want date .
$s_time=date('Y-m-d '.$shift->start_time.'');
$start_time = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $s_time, 'UTC');
$e_time=date('Y-m-d '.$shift->end_time.'');
$end_time = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $e_time, 'UTC');
This convert directly the date from the database to this what you want. In this function you convert time to the timezone time you want
$start_time = \Carbon\Carbon::createFromFormat('H:i:s', $shift->start_time, 'UTC')->format('H:i:s');
$end_time = \Carbon\Carbon::createFromFormat('H:i:s', $shift->end_time, 'UTC')->format('H:i:s');
I currently have a date formated like this:
2017-11-02 11:44:24
However; I need it in this format: 2014-03-11T14:49:52
This is due to the use of a RESTful API based on oData. How can I achieve this date format?
This looks like a job for: DateTime:createFromFormat
$date = DateTime::createFromFormat('Y-m-d H:i:s', '2017-11-02 11:44:24');
echo $date->format('Y-m-d\TH:i:s');
Once you've got the DateTime object then you can format it as needed with ->format()
The date and time can be tricky, but what you want to be sure of is the date and time for your region or Greenwich Mean Time (GMT) or Universal Time Coordinate (UTC). Both GMT and UTC refer to the same time, but your server/database/publish date is likely in your local time. Here's an example of what you can use for local time:
date_default_timezone_set("America/New_York");
$date = date('Y-m-d\TG:i:s');
echo $date;
This will echo 2017-11-02T01:02:58. The capital G represents a 24 hour time stamp, and a small g will represent a 12 hour time stamp.
Depending on how your server is setup, without the date_default_timezone_set you will get the UTC time.
The date I store in mysql looks fine when viewing the database, but when I am viewing the date it is always behind a day.
The mysql data type is "date".
I am getting the date column from mysql using UNIX_TIMESTAMP.
I am displaying the date using php's date() function.
I am using bluehost and configured php.ini to use Los Angeles time zone.
Example: I create a new article and key in 2013-05-08. It gets stored as a date type in mysql showing 2013-05-18. But when I go to view it later it shows 2013-05-07.
The timestamp is 1367992800, which is Wed, 08 May 2013 06:00:00 GMT in GMT, but in my timezone Tuesday, May 07, 2013 11:00:00 PM.
How do I display the originally intended date of 2013-05-18? I do not want to change my timezone to another since Los Angeles is my correct time zone and for all my other methods where we need to record a timestamp, it is accurate.
If you want your date to be independent on timezone you should store it in a column that does not transform the value. So the date column type you've chosen is quite appropriate.
The problem comes when you try get that date in UNIX TIMESTAMP. UNIX TIMESTAMP is an amount of seconds since 01.01.1970 in GMT. It means that mysql converts your date into timestamp in GMT using it's timezone settings.
PHP date function also depends on php timezone settings and converts timestamp into date in the current timezone.
To get date from MySQL without converting it into current timezone just do not fetch it using UNIX_TIEMSTAMP function. Get it as is or using DATE_FORMAT function.
You should use the DateTime object.
$timezone = new DateTimeZone('Europe/London');
$date = new DateTime();
$date->setTimestamp($timestamp);
$date->setTimezone($timezone);
echo $date->format('Y-m-d H:i:s');
I wanted to ask if this was going to work, before I went on a full fledged refactor of how i handle dates and times.
To frame my question, here's my problem...
I store "actions" taken by the user in a history table. These actions have a timestamp on them. Users can be from all over the world, and hence have different timezones. I want to display the items in the history and show the timestamps in one's local timezone.
Also, I know I can use datetime fields and simply store UTC time formats, but I'm opting to use timestamp so i can set a default to current time.
Will this work for my problem?
My server time zone will be Los Angeles
Store timestamps as a timestamp in MySQL. My understanding is that timestamp is always stored as UTC. Records will be stored by default as creation_date OR i will explicitly set UTC_TIMESTAMP(). Effictively, all records in the db will be UTC.
When a user logs in I will grab their timezone (I store this in the db as a user setting).
For this example, lets say this person is in New York.
Here's where my question is. Will either of these work?
a) Grab the history data. All timestamps will automatically be converted from UTC to Los Angeles time. Foreach history item, convert the Los Angeles timestamp to New York timestamp and echo.
OR
b) Set the php timezone "date_default_timezone_set" to New York. Grab the history data. All timestamps are STILL in Los Angeles time by server is still Los Angeles time. Foreach history item, just echo the timestamp because the "date_default_timezone_set" will automatically convert the Los Angeles timestamp to New York.
Will option 4b work? Is there a better way to convert from the Los Angeles time to the New York time?
Is there a better way to do this in general?
You are correct, Unix timestamps are always in UTC. If you store the timestamps in your database in UTC, all you need to do to output it in local time is change the timezone in PHP to the timezone local to the user. You don't need to do any conversion on the timestamps.
<?php
$timeStampFromDatabase = 1325448000; // 01 Jan 2012 20:00:00 GMT
date_default_timezone_set('America/Los_Angeles');
echo date('r', $timeStampFromDatabase); // Sun, 01 Jan 2012 12:00:00 -0800
date_default_timezone_set('Asia/Hong_Kong');
echo date('r', $timeStampFromDatabase); // Mon, 02 Jan 2012 04:00:00 +0800
You can change your timezone on the fly and continue to output timestamps in a date format and they will be "converted" based on the set timezone in PHP. It is very easy, you don't need to do any special handling, and it doesn't matter where you set the timezone, as long as you do it before you output dates, but you can read them prior to setting the timezone.
Unfortunately, "date_default_timezone_set" was not working the way I thought it would. As per the previous example, it would work if the dates I was working with were already in unix timestamp format. However, they were formatted in "Y-m-d H:i:s" and the only thing that would change was the GMT offset, which obviously doesnt work.
After a few hours of fidgeting, here's how I was able to handle time conversions.
$datetime = new DateTime($date_to_convert);
$usertimezone = new DateTimeZone($_SESSION['timezone']); //each user has their own timezone i store in a session (i.e. - "Americas/Los_Angeles")
$datetime->setTimezone($usertimezone);
echo $datetime->format("Y-m-d H:i:s");
I suppose that I could have done the following as well:
Pseudo code
strtotime($datetime)
date_default_timezone_set($user_timezone)
echo date(format, $datetime)
the above, i think, would force the date function to handle it's logic in the given $user_timezone. in hindsight, i would have to translate every $datetime -> unix_timestamp -> $datetime_converted, which doesnt sound to be much better than what i chose to do.
Always store your timestamps in the database as UTC. This is a timezone and daylight savings independent point in time time. To display this back to the user in their timezone, simply do:
$users_timezone = 'Europe/London'; // See PHP documentation for names that can be used.
$date = new DateTime();
$date->setTimestamp($timestamp_from_database);
$date->setTimezone(new DateTimeZone($users_timezone));
echo $date->format("H:ia jS F Y");
By default, Unix timestamps are always in UTC. If we store the timestamps in our database in UTC, we just need to use the following PHP script:
<?php
$TZ_UTC = new DateTimeZone('UTC'); //-->Database Timezone;
$TZ_LOCAL = new DateTimeZone('America/New_York'); //-->Expected Local Timezone from user settings;
//--Example Database Query--
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
//---If we want to show UTC timezone directy----
echo $row['action_timestamp'];
//---If we want to show LOCAL timezone from user settings----
$dateObj = new DateTime($row['action_timestamp'], $TZ_UTC);
$dateObj->setTimezone($TZ_LOCAL); //--> Here is the conversion!
echo $dateObj->format("Y-m-d H:i:s T");
}
?>
date_default_timezone_set("Asia/Singapore"); // UTC +8
$dt = new DateTime();
$dt->setTimestamp(DateTime::createFromFormat('u', gmdate('u'))->getTimestamp());
echo $dt->getTimezone()->getName(); // Asia/Singapore
echo $dt->format('d M Y H:i:s'); // Correct local time
$dt->setTimezone(new DateTimeZone('UTC'));
echo $dt->format('d M Y H:i:s'); // Correct UTC Time
die;
I am wondering if timestamps contain timezone data. On line 3 you see that I used gmdate() which should give me UTC/GMT time. But when I get the timezone & formatted datetime, they are in localtime. I didn't set timezones in my DateTime object yet, gave it a UTC timestamp. It somehow knew to convert to localtime. Which makes me wonder if Timezone data are included in timestamps
setTimestamp accepts the timestamp in GMT 0 and you passed it in GMT, because of gmdate('u'). DateTime object takes your current timezone by default.
After that - you have properly set timestamp and current timezone, that is why DateTime object formats the date for Singapore.
Which makes me wonder if Timezone data are included in timestamps
No. Timestamp stores just amount of seconds since unix-epoch.
Timestamps are interpreted according to the interpreters timezone.
So no, they are standard and do not contain timezone data within themselves.
your example proves it, as you change the timezone, so does your result.
If the timezone data was embedded, the result would not change.