Setting MySQL time zone at runtime with Perl DBIx - mysql

I have a Perl Catalyst app that store some times in a MySQL database. The times are of type TIMESTAMP and initialized with NOW().
When reading back the times they appear to be in the databases default time zone. However when using the mysql shell I can easily set the time zone by SET time_zone = '+03:00'; and get the correct local time for my time zone.
Is there a way to set the time one like this in Catalyst or DBIx at run time?
I want to be able to support different time zones, for different users, so just changing the default time zone for the database is not enough. I am also aware that I can format the time in Perl after I get the data from MySQL, but there is so much automation going on with Catalyst, DBIx and Template Toolkit so getting the data correctly from the database to start with would be so much more convenient.

My general advise is to set the datetime in your application, not rely on the datetime of the database server. If you don't need to know which timezone a datetime had when it was set you should store it in UTC. If you need to know the timezone later you need to use a database datatype which supports this like 'timestamp with timezone' in Oracle.
See my answer for Formatting timestamp field for output in TemplateToolkit which seems to be what you're asking.

Related

Node.js App Datetime stored in Mysql is ahead of UTC time

Columns definition :
`local_punched_at` timestamp NULL DEFAULT NULL,
`punched_at` datetime DEFAULT NULL,
We have an application that is used in multiple timezones, so we are storing UTC time in the punched_at column and the user local time in the local_punched_at column.
When we persist these dates in MySQL the local_punched_at is stored as the same value as punched_at(even we passed the user's local time which is always lower than UTC) or sometimes it is stored value as 1 hour ahead of punched_at value.
For example : For user in America/Chicago Timezone, we send local_punched_at as "2021-11-03 08:52:14" and punched_at : "2021-11-03 13:52:14" , but the DB stored it as
local_punched_at : "2021-11-03 14:52:14" and punched_at : "2021-11-03 13:52:14"
The problem is why the local_punched_at date is changed during saving in MySQL.
MySQL server timezone is UTC.
Node app is running on AWS EC2 and DB is Aurora MySQL.
Did anyone face such an issue?
The TIMESTAMP and DATETIME data types handle time zones differently in MySQL. You are running into that problem.
TIMESTAMP values, when stored, are always translated from the current timezone setting to UTC. And, when retrieved and sent to a client, they are always translated back to the current timezone setting. Functions like NOW() and CURDATE() also obey the current timezone setting.
You can set the timezone, for each connection, with SET time_zone='America/Chicago';. And you can retrieve the current setting with SELECT ##time_zone;
On the other hand, the DATETIME data type attempts no translation. It stores whatever you give it verbatim.
Many global applications ask users to set their preferred time zones, with values like 'America/Chicago' and 'Asia/Kolkata' and so forth. Then, when the application connects to the database on behalf of a user it does the SET time_zone operation. It's a cool feature, for timestamps that lie within the range of UNIX timestamps.
The global application stores timezone-sensitive data (like the scheduled time for a phone call) in TIMESTAMP columns. This allows each user to see times in their local time zone, even when daylight-time changeover days are different between jurisdictions. Like now: England has switched to standard time, but US has not yet. It's based on the Internet Assigned Numbers Authority's wonderful zoneinfo database.
Your confusion here? It's possible your database connection's time_zone setting defaults to 'America/New_York' or '-04:00'. It seems likely your server is located in the US-East region (in the suburbs of DC) of your cloud provider. The time_zone setting does not have to be the same as the server's clock.
If you want to always speak UTC to TIMESTAMP data, use SET time_zone='UTC'; immediately when you open each database connection.

How to configure Code Workbook's timezone for CURRENT_TIMESTAMP?

How can I configure Code Workbooks's timezone such that calling CURRENT_TIMESTAMP in SQL returns my local time instead of the default UTC?
Are there any reasons this would be advised against?
Timestamps in Spark have no concept of timezones since they represent the number of microseconds since Unix epoch. I'm not aware of any Code Workbook setting to change this, but Spark likely uses the system clock of whatever host it executes the function on to determine what the current timestamp should be, and it wouldn't be possible to fiddle with those settings.
Sounds like what you're looking for is some function like from_utc_timestamp, which takes your timestamp in UTC and shifts it to your timezone. Note that your timestamp would still be timezone-agnostic, but if you were to print the string representation of your timestamp, it would now look like the wall-clock date/time in your local timezone.

Can I make MYSQL automatically convert all datetime data to different timezone?

First, Thankyou for sparing your precious time to look upon my beginer question
So the thing is, I still can't fathom how datetime work on MySQL
"Can I, upon changing timezone, convert all datetime columns in all tables to match the new timezon?"
For example, my server local time is UTC +7
I have database with several tables which some contain column with datetime data type (eg. CreationTime, updatedTime, visitTime, etc)
Now supposed to, somehow, I plan to move my server to a different timezone, let say UTC +8.
Can I do one method to convert all the datetime columns in many tables automatically to the new timezone?
let say the old datetime is 22/2/20 18:00:00, after the conversion, become 22/2/20 19:00:00. All with a method or functions (preverabli native to mysql, but i can compromised using php), considering that manually writing a list of all tables or all columns name one by one is impossible?
Sorry if the question is superficial. I have exploring the web, and stackoverlow, but my meager knowledge in programming just can't graps most of the discussion.
Thank you very much.
The same question was here: Should MySQL have its timezone set to UTC?
Based on these answers you can change /etc/mysql/my.cnf file to change default database timezone:
default_time_zone='+00:00'
or
timezone='UTC'
Notice: The right way is to save all timestamp data in UTC+0 format (backend), and then fetch it with actual client timezone (frontend).

How do I store time in 12 hour format in mysql

I am developing an application in which user schedules his date, time and event.
I was wondering if there is any possible way that I can store time in hh:mm:ss AM/PM format rather than 24 hour.
I think my question wasn't clear enough , adding some stuff
Problem Definition : Migration from PHP-MSSQL (Windows) web service to PHP-MYSQL (Linux)
Back End was written before y2k its an old program launced as an single platform , prior to me developers ported this program on the web but did not ported the DMS (database management system aka utility for data entry guys) i am not sure about the reason behind this.
Old procedure to enter data , data entry guy used to log in on windows server start the application and enter data.
After migration we can no longer use old DMS program hence i have to write new DMS program.
I asked few question about migration from mssql to mysql before you all can have look here https://stackoverflow.com/questions/22603868/converting-porting-mssql-table-to-mysql-table
Biggest problem that i have facing is data entry guys want their dms just like before not a inch less or more (cant blame them for this).
old dms view
new dms
I am trying my level best to give them old look feel and functionality back as well as wanted to reduce their work since most of the times they have to update an old entry with new dates only , before that they used to do it by deleting whore record and recreation it again.
front end view of date added:
mssql db structure
mysql db structure
You are probably looking for DATE_FORMAT(date,format)
%r Time, 12-hour (hh:mm:ss followed by AM or PM)
You should store dates and times in a database as either a Date, Time or DateTime datatype (depending on what types your db provider supports (MySql reference)). Never store these as a string.
The way the user inputs the value should be determined by their culture settings on the machine:
dateTimePicker1.Format = DateTimePickerFormat.Custom
dateTimePicker1.CustomFormat = Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern
That way if they prefer 12h format, they just set that in control panel
You can get the inputted value like so:
Dim ts As TimeSpan = New TimeSpan(DateTimePicker1.Value.Hour, DateTimePicker1.Value.Minute, DateTimePicker1.Value.Second)
Storing dates and time in the database instead of string makes life a lot easier when you come to read them because you can just format the date or time in any way you wish.
You can then use the same code in your application to show that date or time in the users preferred culture. (Formatting Date and Time for a Specific Culture)
It also allows you to perform queries on the actual date or time which would not be possible (or at least very inefficient) on a string
.ToString("HH:mm") Solved all my problems for a while.

grails/mysql timezone change

Whats the best way to accomplish changing the timezone of an app? The way I see it the following must occur:
Server TZ is changed by sys admin
mysql must be restarted.
every time based column in the database must have all values updated, using convert_tz or equivalent. So either a mysql script must be written or a grails script that loads every row for each class, updating all the time fields.
Obviously the server should be taken down while this is happening, and backups must be in place incase of an error.
Is there a better/easier way to do this?
Java does not use time zones when using Dates; it stores everything as UTC and only uses time zones when displaying dates. see the following link for a discussion of java date/time.
http://www.odi.ch/prog/design/datetime.php
If you're using the Date, Time, or DateTime column types in MySQL, time zone does not matter.
If you’re using the TIMESTAMP column type, time zones may matter since the TIMESTAMP is stored as a UTC but has conversion done when both retrieving and storing the values. For a discussion of MySQL time zone behavior see
http://dev.mysql.com/doc/refman/5.1/en/time-zone-support.html .
If you’re worried about synchronizing objects across multiple servers in different time zones things get more complicated, see the following thread for a discussion of this.
http://www.pubbs.net/201006/grails/2500-grails-user-how-to-get-gorm-to-store-dates-as-timestamp-in-utc-by-default-without-a-custom-hibernate-mapping-or-joda-time-plu.html
I know this is an old question but I think it's also pretty timeless... at least, I have stumbled upon it a fair number of times recently... so I thought I would contribute my solution.
First, I am using Grails 2.5.1 and PostgreSQL 9.4 as the backend.
Second, Date fields in Groovy/Grails are stored as timestamp without time zone in PostgreSQL. So it seems to me the first answer above is not actually fully correct - the date is not stored in UTC. This observation got me thinking... along the lines of "well if the database doesn't know what the timezone is, who does"? And the first answer that came to mind was "maybe it's Spring".
Third, the specifics of my problem is that I have a lot of dates that I bootstrapped into the database via BootStrap.groovy and new ThisClass().save(). And because these were dates, not dates + times, they all look like 2005-11-03 00:00:00 as PostgreSQL timestamps (without timezones).
Fourth, what really made the penny drop was when I edited one of my GSPs to include the timezone in the date format string, which showed up as PST (where my server is); and when I included timeZone="Asia/Kolkata" in the g:formatDate of the field in question, the time advanced by 12h30. So pretty clearly my server was running in PST8PDT and since that wasn't PostgreSQL I came back to Spring as the potential place to change things.
Fifth, after reading a few comments about setting the locale in grails-app/conf/spring/resources.groovy I decided to try setting the locale and timezone there, as per:
// Place your Spring DSL code here
beans = {
// from http://stackoverflow.com/questions/1569446/grails-how-to-change-the-current-locale
localeResolver(org.springframework.web.servlet.i18n.SessionLocaleResolver) {
defaultLocale = new Locale("en","IN")
java.util.Locale.setDefault(defaultLocale)
println "configure spring/resources.groovy defaultLocale $defaultLocale"
defaultTimeZone = TimeZone.getTimeZone("Asia/Kolkata")
java.util.TimeZone.setDefault(defaultTimeZone)
println "configure spring/resources.groovy defaultTimeZone $defaultTimeZone"
}
}
I also used g:format timezone="Asia/Kolkata" format="dd MMM, yyyy a z" for all my date fields. And that seems to interpret all data in PostgreSQL timestamp fields in the correct timezone and at the anticipated hour (ie the hour that was entered), even though the dates were first entered "in the wrong time zone".
Sixth, g:datePicker - I read a number of posts about making this "time zone sensitive", but I found that its dates are interpreted as in the timezone used by Spring and so in my case, this is exactly what I need. Conversely, if someone wanted to enter dates in their locale and have Spring convert them on the fly to the server's time zone, I guess that would require some extra effort.
Personally I think it would be really cool if g:datePicker accepted timeZone as a parameter and used it in the same way g:formatDate does.
We had problems with time differences between using GORM and using groovy.sql.Sql (for quicker data import).
GORM was using the grails config timezone (UTC) that we set in the Bootstrap, but groovy sql was using the default system timezone (GMT).
The problem was solved by setting the timezone in the $JAVA_OPTS, although you could add the switch to grails opts or to the run-app command.
grails -Duser.timezone=UTC run-app