Rails localtime returns wrong time zone - mysql

I have a problem where when saving a datetime attribute, the form returns -04:00 instead of -05:00
Using Rails 3.2.3
In application.rb:
config.time_zone = 'Eastern Time (US & Canada)'
Using MySQL with mysql2 adapter
Running #wine.released_at.localtime returns 2008-05-15 00:00:00.000000000 -04:00
Running #wine.released_at returns 2008-05-15 04:00:00.000000000 Z
Running Time.now.zone returns Eastern Standard Time
Running #wine.released_at.zone returns EDT
I'm fairly confused. I though setting config.time_zone should make it such that Rails automatically converts all database datetime values to the set time_zone...why isn't this happening?

It looks to me as if the zone property returns the name of the "zone interval" which is applicable for the specified time. So for a summer time it will return "EDT" but for a winter time it will return "Easter Standard Time". (It's odd that it uses an abbreviation for one but not the other, but hey...)
So it is using the same time zone for both - those are just different aspects within the same time zone: sometimes it's standard time, sometimes it's daylight saving time.
If you print Time.now.localtime it should show you a -05:00 to show that the current offset from UTC in Eastern Time is -5 hours (i.e. Eastern Time is currently 5 hours behind UTC).

Have you tried using in_time_zone?

Related

How to deal with the time zone difference

Using mysql, in a post table I use CURRENT_TIMESTAMP to store the date_time of publication.
Everything was ok when I was working on wampserver on local.
But I hosted my site yesterday on a server located in France, 2 hours away from the time zone of my country.
I'm using a timeago plug-in which processes the date and displays the elapsed time (there is .. sec ago, there is .. min ago, there is .. h ago, there is .. year ago) since the publication of a content.
After posting, I see "2 hours ago" when I just published 30 seconds ago.
How can I take into account the time zone of my users compared to the date and time of the server of my host?
Sample: If I post a content, 30 seconds later Me and the user who is at china or anywhere must see "30 seconds ago".
I tried that:
$d ="2020-02-28T13:09:33Z";
<time class='timeago' datetime='<?= $d ?>'> </time>
But instead of giving me "30 seconds ago", It gives me "2 hours ago".
Thank you.
I suspect you are calculating the relative time on the client side. For example, by timego plugin.
Neither MySQL, nor PHP know user's location and timezone. So, it's better to inform JS about server timezone and let it calculate the offset right.
Use ISO 8601 date time format to let timeago pligin know about server timezone. All the rest is up to JS plugin:
<?php
$ts = strtotime($row['date_time']);
?>
<time class="timeago" datetime="<?= date(DATE_ISO8601, $ts) ?>">
<?= date('Y-m-d H:i:s', $ts) ?>
</time>
<script type="text/javascript">
jQuery(function($) {
$("time.DateTime").timeago();
});
</script>
MySQL stores DATETIME without timezone information, but datetime values that are not timezone-aware are semi-useless.
So you have different options.
First option: continue to store datetime values in your current timezone, but add a second column with the proper 'offset' versus UTC, for example +1 if you are in France. Then you can perform calculation on the fly to another timezone but it is tricky because of daylight saving settings. During a certain period of the year the offset will be +1, at other times it could be +2.
So I don't recommend this approach. It's not going to scale well over time.
Other option: you can store all datetime values as UTC in your database and
then in your application you recalculate them by applying the correct offset according to your own timezone (or that of your web visitors).
This is a better option.
Whatever you do, it is important to know the timezone that applies to a given datetime value. So choose one and stick to it.
PHP has functions to handle time zone conversions, see for example: https://www.php.net/manual/en/class.datetimezone.php
Note that TIMESTAMP is limited to 1970-2038... Year 2038 problem

Linking to OWA Calendar - Passing a Time Zone

I am trying to prefill a create event link to Microsoft OWA.
This works:
https://outlook.live.com/owa/
?path=/calendar/action/compose
&subject=TestEvent
&location=testlocation
&startdt=2018-02-29T19:00:00
&enddt=2018-02-29T20:00:00
&body=Testtext+my+test+text
Test it here
But I did not find a way to set a timezone, since for some reason that is not documented.
Is there a way to set the timezone of startdt and enddt?
I already tried appending a Z to the date, as this works in Yahoo and Google Calendar links (it tells the application that the timezone is UTC).
I have also been unable to discover how to set a timezone for the OWA calendar event link. However, I have discovered that you can specify a UTC offset value within the link. There are two drawbacks to this method though. The first drawback is that you have to account for daylight savings time on your end, because the UTC offset changes. The second is that the end user needs to have their timezone set correctly for them to see the correct time.
How you specify the UTC offset within the link is by adding the offset to the end of the startdt and enddt parameters in the format of + or - hh:mm. For example, let's say the event was set for March 27, 3pm, in the Eastern standard time zone. In the US, daylight savings is active on March 27, so the UTC offset would be -4 for the eastern US. The startdt parameter should then be 2018-03-27T15:00:00-04:00. Same goes for the enddt parameter.

How to display datetime form mysql using CakePHP 3.0

I would like to ask how to add datetime ('Y-m-d h:i:s') format field for the SQL.
The name of my table is groups, the name of the field is date_add
i am using cake PHP 3, i want to use the timezone Australia/Perth but i don't know how to begin.
I successfully displayed added my date using
$group->date_add = date("Y-m-d h:i:s");
However, the result for the time is not correct with the timezone.
Datetime in PHP in general
Per the documentation of DateTime you can use all options available for the date() functions for formatting. Your main mistake in the formatting is the difference betweetn a y and a Y being the difference between a year in two and a year in four numbers.
Secondly you say you want to add the correct time zone. This is a bit odd however since you always want to add the same time zone. If you want to convey the fact that all your dates are Australia/Perth as information why do you not simply add that text after it?
If you mean this is a problem since you store the information in a different time zone to begin with and thus have a conversion problem you can set the correct time zone on the DateTime object itself. But you need to be sure the DateTime object is constructed with the correct original time zone to begin with. Observe the following code for an explanation:
<?php
$DateTime = new DateTime(); // This is now Europe/Amsterdam for my laptop
var_dump($DateTime->format('dmY h:i e'));
// result of var_dump is: string(31) "13102015 12:00 Europe/Amsterdam"
$DateTime->setTimeZone(new DateTimeZone('Europe/London'));
var_dump($DateTime->format('dmY h:i e'));
// result of var_dump is: string(28) "13102015 11:00 Europe/London"
Take aways:
e is the format modifier for the time zone
Conversion of time zones is possible with PHP's DateTime object. Find out what your default time zone is on your current PHP installation to see if you need to convert or not. See information on the date.timezone setting here: http://php.net/manual/en/datetime.configuration.php
Cake 3.0 specific
As Oops D'oh pointed out in the comments there are a lot of CakePHP specific things to know as well. Since he added an excellent part concerning that I suggest you read that as well.

data type to use in mysql for timezones

I store a date/time in my database that is UTC. I'm working to add conversion of this once a user selects a timezone so it shows local time for them. Basically the user selects from a form:
<select name="DropDownTimezone" id="DropDownTimezone">
<option value="-12.0">(GMT -12:00) Eniwetok, Kwajalein</option>
<option value="-11.0">(GMT -11:00) Midway Island, Samoa</option>
<option value="-10.0">(GMT -10:00) Hawaii</option>
...
I can make the option value anything I want but an easy to remember one is as above. What data type would I use for mysql? Does it really matter in this case? Would TINYINT do? Maybe using an ENUM would be a good idea?
Any suggestions would be appreciated.
The scheme you're proposing (storing time zones as an integer offset from GMT) may fail for the following cases:
India, which is on UTC + 05:30 (not an integer number of hours).
Kiribati, which is on UTC + 14:00 (over 12 hours).
Distinguishing British Time and GMT. (The former uses Daylight Saving Time; the latter is not.)
Distinguishing between some pairs of countries which use the same GMT offset, but which switch at different times of the year.
For full time zone support, I'd recommend using the zoneinfo database and storing time zones as strings (e.g, "America/New_York").
Although this is very old. But for anybody still looking for the solution. I used
date-fns with time zones. I am using reactjs with node.js . Only had to add one extra column to the table - and always store time in UTC format only - and the corresponding zone in the additional column.
https://date-fns.org/v2.23.0/docs/Time-Zones
import { zonedTimeToUtc } from 'date-fns-tz'
const date = getDatePickerValue() // e.g. 2014-06-25 10:00:00 (picked in any time zone)
const timeZone = getTimeZoneValue() // e.g. America/Los_Angeles
const utcDate = zonedTimeToUtc(date, timeZone) // In June 10am in Los Angeles is 5pm UTC
postToServer(utcDate.toISOString(), timeZone) // post 2014-06-25T17:00:00.000Z, America/Los_Angeles
And for the scenario of timezones - list. https://www.npmjs.com/package/countries-and-timezones

Php-how to change timezone with daylight savings?

hey !
I'm working on a php web app , and i'm trying to change the time zone for each user according to his location ,
i was using this SQL statement : SET time_zone every time i'm about to display date and time ,
but when it comes to day light savings time , it does not work at all (ex : before daylight savings , timezone offset for Us&Canada Mountain time is -7 hours but now it's -8 hours and the code i'm using does not help at all ) ;
Thank you for you help
http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html,
The value can be given as a named time zone, such as 'Europe/Helsinki', 'US/Eastern', or 'MET'. Named time zones can be used only if the time zone information tables in the mysql database have been created and populated.
Seems to me that means you can use entries from the tz database such as America/Denver.
Note: Mountian is currently -6, not -8.