We got a Rails 3 Server based on Ruby 1.9.2 running on a MYSQL DB and Problems with the time.now and time.zone.now setting.
For better explaination we assuse its 13:00 UTC right now.
Ubuntu Systemtime is set to 15:00 UTC +02:00 (Thats CEST (Central European Summertime) and is correct for our Timezone).
The Rails time (time.now) is set to 13:00 +0200
the time.zone.now is set to CEST
MYSQL Global time and Session time are both set to SYSTEM
now we create a new entry in the MYSQL DB (via activerecord) which has a timestamp.
but when we look at the timestemp its -2 hours offset to the current server time (in our example 11:00)
We tried setting the time.zone to a very different one for testing propose, it had absolutly no effect on a new mysql entry.
Also we tried to set the mysql global time and session time to UTC, no effect.
The only thing we can imagene right now what could be the problem is that the time.now is taking effect on the mysql entry and is set wrong. Problem here: we're unable to set the time.now setting. But even if that would be possible somehow (is it?), dunno if that fixes the problem.
Did anyone ever have such a problem or any ideas what could cause it?
There are two things to configure for rails.
The current timezone which you've done (used in Time.zone.now), this sets the timezone for timestamps in the instantiated records you load.
The timezone that those values are converted to when stored to the db. This should be set to the same timezone as your system/mysql.
I think this option is configured via: ActiveRecord::Base.default_timezone = :utc
Since your system time is set to CEST, you'll want to use the same value for that as well.
The reason there are two config options is incase you've got users in multiple timezones (international audience), then Time.zone can be set differently for each logged in user, and the db timezone will convert correctly to the Time.zone timezone.
Related
This question already has answers here:
How to store a datetime in MySQL with timezone info
(7 answers)
Closed 3 years ago.
This question is different from problem to store timestamp into datetime.
I have a timestamp, and so no tz info.
Also I cannot alter my db structure
I am using eloquent, but it worth to say that this problem happens also doing manually a MySQL query insert
What I am doing
My API received this timestamp:
1572864543
It's
Assuming that this timestamp is in seconds:
GMT: Monday 4 November 2019 10:49:03
Your time zone: lunedì 4 novembre 2019 11:49:03 GMT+01:00
When I save on the db, I have NO idea of what is the user's MySQL timezone configuration, but I need that MySQL absolutely do not alters my timestamp.
What I'm sure is that MySQL column is a timestamp
I know that storing a timestamp in Laravel requires a conversion in a sql-like string
I tried to used
Carbon::createFromTimestamp($claims["date"])->toDateTimeString();
Problem
It works, but MySQL gets my string, applies its timezone setting, shit to UTC and the save internally the new timestamp.
So when retrieving
UNIX_TIMESTAMP(received_ts)
I got the wrong result.
Question
I absolutely need to keep my timestamp UNALTERED into the db. How can I save a timestamp without altering it?
Mixed infos
The reason of this is that my product is installed in an unpredictable server timezone; I also cannot force the user to change db timezone to UTC.
Actually my app's timezone is already forced to 'UTC' via laravel config/app.php file
'timezone' => 'UTC',
I resolved forcing utc in the options of my MySQL connection configuration.
MySQL now do not alters any timestamps
After inserted record into database, created_at timestamp not display right time, it late 2h from server.... Also If i type into mysql SELECT NOW() it show right time, any idea what is problem?
Edit..
It take date from Carbon class... any idea how to change it?
The default timezone for laravel is UTC which is located in config/app.php file.
If you want to change the timezone to your preferred timezone, choose your preferred timezone from this list or from this list and replace the UTC with your chosen timezone.
A few notes. As per the comments here, to be precise, the last 3 comments: You should not change the default values.
Storing dates of different timezones in data source of a same
application (by changing the timezone in config for current user &
letting Laravel handle it from there on) is just asking for trouble &
is a bad design. You will lose data integrity. What will happen when a
user changes timezone? You'll update all the dates in the database for
that user?
Store dates for all users as UTC (or any other timezone of your
choosing, just select one & stick to it). Laravel already uses the
excellent Carbon library, use it to convert dates from your
timezone (in which they're stored in DB) to users' timezone (which
you would store with in every user's settings) when you display the
dates.
For the other people that also still have the wrong date/time after changing the config file:
My problem was in php in my vagrant box (Homestead).
To solve it I did:
First ssh into you vagrant box and then run this in the command line:
date
This should return something like "Mon Jul 3 13:48:52 CEST 2017". Check if this date/time is correct. If not do the following:
sudo ntpdate -b pool.ntp.org
This should update your system time. Check it again with the first command. If it is still not write you probably have to change your systems timezone. You can do this by running:
sudo rm -f /etc/localtime
sudo ln -sf /usr/share/zoneinfo/Europe/Amsterdam /etc/localtime
You can use any timezone you wish, I prefer "Europe/Amsterdam".
You can get other timezones here
So ... I inserted an entry into a table with time stamps. The entry got inserted perfectly.
But the time stamp that got inserted was :
'2015-06-22 10:32:47'
I checked the time on the server:
Tue Jun 23 01:35:41 IST 2015
And inside mysql :
select now();
2015-06-23 01:33:57
So I check the time in irb.
time = Time.now
=> 2015-06-23 01:36:41 +0530
time.zone
=> "IST"
The time zone is right .. but I dont know where is it picking up the time from? I cant figure out where is it picking up 10:32 from ? and how do I fix it ?
Appreciate all your help.
Rails by design converts a datetime into UTC before inserting the value into the database.
This is because, in general, it's not possible to easily represent timezones in the database. Moreover, this approach guarantees the date will be consistent and/or easy to query in the following cases:
if the server time zone changes or you change server with a different timezone
if you want to query the date using a different timezone
if you want to format the date with different time zones depending on the user or other configs
You can customize the default timezone for the app, so that Rails will properly compute the correct difference to UTC when the value is stored into the database. However, you cannot change this behavior: times will always be converted into UTC before being stored in the database.
Generally speaking, if you properly use the Rails date transformation helpers, this shouldn't cause any issue.
For instance, if you want to query all the records where the time is past, the following query
Record.where('some_date < ?', Time.current)
will properly convert Time.current from your app timezone into UTC, and query the database accordingly.
I'm having a bizarre issue with my local MySQL server. I have a table with a created_at timestamp column set to CURRENT_TIMESTAMP by default. Everything I've read indicates that this should store the time in UTC, then convert it back to local time for display. However, it's not working right. I'm not sure if it's screwing up on the display or what, but when I read the timestamps out, it's giving me the GMT times instead of adjusting for my local timezone. This wouldn't be as big of an issue, except that NOW() is giving me local time, so I can't compare them properly. I feel like I'm probably missing something stupid, but what's going on here?
If it matters, I'm running MySQL 5.5.24 under 64-bit Windows 8 (unfortunately).
Edit:
Poking at it some more has revealed that the timestamps are working fine when I add rows manually; it's just the rows coming from my PHP that are screwy. I guess the PHP connection must be overriding the default timezone for some reason.
Have you loaded time zone data?
http://www.geeksengine.com/article/populate-time-zone-data-for-mysql.html
Ah-hah! My PHP server and my MySQL server were using different timezones. Needed to go add date.timezone = America/New_York to my php.ini file.
I need to change the timezone of a single database is this possible?
I know we can change the timezone within our WHM (we are using a dedicated server from hostgator), however a large number of legacy software running on the server has a lot of +6 hours coding in it (i.e. server timezone is CST, we wanted the time in GMT so previous developers altered date/times manually within the code - bad!).
I am now working on a new software and would like to have it all in GMT, I know I can use date_default_timezone_set('GMT') however that will not solve MySQL inserts where the datetime column is set to CURRENT_TIMESTAMP as it will insert # CST timezone.
No, it's not possible to change the timezone for a single database within a MySQL instance.
We can retrieve the server and client time_zone settings with a query, like this:
SELECT ##global.time_zone, ##session.time_zone;
We can also change the client timezone for a session, or change the timezone for the entire MySQL instance.
But we need to be keenly aware of the implication that this change will have on existing client connections, and the how DATETIME and TIMESTAMP values already stored in the instance will be interpreted.
To have the server time_zone set at MySQL instance startup, we can modify the /etc/my.cnf file (or wherever the mysql instance initialization parameters are read from), under the [mysqld] section:
[mysqld]
default-time-zone='+00:00'
-- or --
It is also possible (less desirable) to add the --default_time_zone='+00:00' option to mysqld_safe
NOTE: Changing the timezone setting on the MySQL server does NOT change the values stored in existing DATETIME or TIMESTAMP columns, BUT since it does effectively change the context in which those stored values are interpreted, it will look like all of the values ARE shifted. (Where 08:00 was taken to mean 8AM CST, with the time_zone of the server changed from CST to GMT, that same '08:00' will now be taken to be 8AM GMT, which would effectively be 2AM CST.
Also keep in mind that TIMESTAMP columns are always stored in UTC, while DATETIME columns do not have a timezone.
http://dev.mysql.com/doc/refman/5.5/en/datetime.html
Each client session can change the timezone setting for their own session:
SET time_zone='-06:00';
But none of this really "solves" the timezone conversion problem, it just moves the conversion problem around.
There's nothing inherently "bad" with the application layer handling timezone conversions; sometimes, that's the best place to handle. It just has to be done correctly and consistently.
(What's odd about the setup you describe is that the app is storing DATETIME values as if the MySQL server time_zone is set to GMT, but the MySQL server time_zone is set to something else.)
If you can't change your current time zone you can change the result.
date 2015-01-05 12:06:16
Select date + Interval 2 Hour 'date' From ExampleTable
date 2015-01-05 14:06:16
You can modify the the default value instead of entering current_timestamp make it insert current_timestamp added to hours offset of your timezone. I just did it this way when didn't found any solution, had to invent my own.