Postgresql date format error - ruby-on-rails

I'm having problems when changing the date format for the datepicker.
I want to have the 'dd/mm/yyyy/ date format but postgres throws me this error:
ActiveRecord::StatementInvalid - PG::DatetimeFieldOverflow: ERROR: date/time field value out of range: "16/07/2014"
Perhaps you need a different "datestyle" setting.
because of its american way of saving the date format.

Set datestyle in your postgreSQL database as below:
SET datestyle = "ISO, DMY";

The datestyle setting defines a default for your system. Consider #Ilesh's answer. The setting in postgresql.conf applies to all databases in the db cluster.
To make statements work without regard to the setting, use the to_date() function to form date values from string constants:
SELECT to_date('16/07/2014', 'DD/MM/YYYY');
Related:
Store date with optional month / day

Related

Changing timezone for a default timestamp column in Snowflake

I have a table defined in snowflake as follows;
CREATE OR REPLACE TABLE DATA_LAKE.CUSTOMER.ACT_PREDICTED_PROBABILITIES(
PREDICTED_PROBABILITY FLOAT,
TIME_PREDICTED TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
As expected default timezone is America/Los Angeles. I am trying to change it to UTC, but only for this column, not at account/session level.Here is the code I wrote;
ALTER TABLE DATA_LAKE.CUSTOMER.ACT_PREDICTED_PROBABILITIES ALTER TIME_PREDICTED SET timezone= 'UTC';
But it is giving an error,
SQL compilation error: syntax error line 1 at position 86 unexpected 'timezone'.
Can I please get help on how to do the change at column level?thanks in advance.
I recommend reviewing this documentation regarding timestamp data types:
https://docs.snowflake.com/en/sql-reference/data-types-datetime.html#timestamp
However, assuming that your TIMESTAMP_TYPE_MAPPING is still the default of TIMESTAMP_NTZ, then you've now got a bunch of data that is set to America/Los Angeles without a timezone offset in the values, and if you're not going to change any of your account timezone settings, then you either need to leave it that way and just change the timezone as you select the data using the CONVERT_TIMEZONE function, or you should change your table definition to a data type that includes a timezone offset. You could also update the column as it is by converting it with the same CONVERT_TIMEZONE function, but then future data would still be inserted using America/Los Angeles timezone.
My recommendation is to use TIMESTAMP_TZ as your column type and modify the current data accordingly.

Date in free format into db

I have a model with :birth_date of type date.
I've tried to put a string like 3 janvier 1968 (French language) into that field and somehow in database I saw that PostgreSQL or someone else converted it into a date!
I also tried some other dates like 3 février 1968 or like 3 fevrier 1968 which didn't work and turned out to be NULL in db.
I can't find information about this feature anywhere. How does this work?
Rails knows that attribute is a Date from the database definition, so it converts the string you give it to a Date. If you create a new instance of your model in the Rails console and assign to birth_date, you can show that it's already a Date even before you save it to the database:
m = Model.new # Use your model name
m.birth_date = "3 février 1968"
m.birth_date.class
The console should tell you that m.birth_date is a Date.
So the conversion to Date is done before you save the model to the database. Rails defines a String::to_date method that calls the Ruby ::Date.parse method, which converts various human-readable date strings into a Date (https://ruby-doc.org/stdlib-2.3.1/libdoc/date/rdoc/Date.html#method-c-parse). In the Rails source, you'll see that whatever you assign to a Date attribute is converted to a Date with the to_date method. So when you assign a String, it happens via String::to_date which calls Date.parse.
As you mentioned in your comment, Date.parse seems to take a fairly loose approach to the months when they're spelled out. I tried a variety of English, French, and Spanish months in Date.parse, and as long as the first three letters of the non-English month are the same as the English month, Date.parse will convert them. But if the first three letters are different, then Date.parse throws an error.
if you have a column in the database as type 'date', it will only save as a date. Rails does it's best to convert a string into a recognized date if possible. You should always pass the 'birth_date' data as a date (i.e. use a date_field). Otherwise, if you REALLY want to store it as a string, the birth_date column must be of type string in the database

conversion error from string, when using params in SQL

using Delphi 2010 (Firebird [testing], MS Sql Server, Oracle [production])
The following is my SQL
SELECT p.script_no, MIN(p.start_Time) as startTime, MAX(p.end_Time) as endTime,
SUM(p.duration) as TotalDuration
FROM phase_times p
WHERE (p.script_no=:scriptNo) AND (Trunc(p.start_time) >= :beginDateRange) AND (Trunc(p.start_time) <= :endDateRange)
GROUP BY p.script_no
ParamByName('beginDateRange').AsDate:= Date - 30;
ParamByName('endDateRange').AsDate:= Date;
I am getting a "conversion error from string - 10-25-2012" and i am not sure why, since my datetime fields are in the "10/25/2012 9:20:49 AM" format in the database.
If i change it to the following : ParamByName('beginDateRange').AsString := formatDateTime('mm/dd/yyyy',Date - 30).....i get the error "conversion error from string - 10/25/2012"
reserching this error has provided me no new avenues, do you have any ideas?
According to the Interbase 6.0 manual, Embedded SQL guide, chapter 7, Firebird supports conversion from YYYY-MM-DD and YYYY-MM-DD HH:MM:SS.qqq. I also believe it supports American style shorthand dates (eg 1-JAN-2012) for conversion.
It may be there are some locale dependent conversion supported, but in general: use an actual date/timestamp type instead of a string.
UPDATE
I initially did not spot the TRUNC in your query: it is the cause of the conversion error as this function only works on numbers, see the manual entry for TRUNC.
Given your comment (and the respons of ain) I assume you are only interested in the date part, and want to ignore the time. If so, rewrite your use of TRUNC to:
CAST(<your-timestamp-field> AS DATE)
And the condition (Trunc(p.start_time) >= :beginDateRange) AND (Trunc(p.start_time) <= :endDateRange) to:
CAST(p.start_time AS DATE) BETWEEN :beginDateRange AND :endDateRange
Firebird doesn't support conversion from string to date and time value if string is in 12 hour format. Use 'dd.mm.yyyy hh:mm:ss' or 'mm/dd/yyyy hh:mm:ss' formats.
String to date/time conversions usually use user's locale.
So if you feed a date/time conversion function with string that does not match your date part of the locale - you will get similar errors.
Also specifying date/time values like "10/25/2012" is Locale dependent. So if you execute your program on a computer with different than US Locale (like Mine) - it's likely to fail if using "10/25/2012".
To be Locale independent I suggest two options:
Use StrToDateTime, specifying TFormatSettings
Use ISO 8601 for specifying date/time strings (but I don't think Delphi supports that...)
BTW programs like MS Sql, Excel etc. accept dates in ISO 8601. But you have to check this for FB.
Regarding this:
...since my datetime fields are in the "10/25/2012 9:20:49 AM" format in the database...
The internal storage of date/time fields varies between different DB Engines. What you see in your DB Management Software ("10/25/2012 9:20:49 AM" in your case) is the string representation of the data field, usually formatted (again) according your user Locale
if you connected with DB from Firebird 1.0 under the server Firebird 2.1 (for example) you need todo backup and restore under Firebird 2.1

Delphi 7, Titan BTrieve Components

I am using Delphi 7, and Titan BTrieve to open a Pervasive Table.
It is a TtbTable component.
I am trying to apply the filter on a TimeStamp field with my code as follows:
Date:=InputDate;
DateString:=FormatDateTime('DD/MM/YYYY HH:NN:SS', InputDate);
Table1.Filter:='UPDATEDON > '+chr(39)+DAteString+chr(39);
Table1.Filtered:=True;
The problem is that the filter results are incorrect. It returns records that are before the do not match the filter criteria.
the Table1.Filter, filters the data in TDataSet not in btrieve/pervasive.
the problem is the date in string format... you must use the formar YYYY-MM-DD and not DD-MM-YYYY because the string compare.
in a string compare 17-06-2012 is grater than 16-07-2012, (17>16)
From the look of it, you are comparing strings, not dates.
What version of PSQL are you using? Is the UPDATEDON field defined as a Timestamp in the Btrieve database? If it's a timestamp, values are stored in 8-byte unsigned values representing septaseconds (10^-7 second) since January 1, 0001 in a Gregorian calendar, Coordinated Universal Time (UTC). It is not stored as a string.
Btrieve / PSQL stores dates in the 'YYYY-MM-DD' format.
WHat does a value from the UPDATEDON field look like? To use it as a filter, you need to make sure the filter value looks the same.

I'm getting "Invalid month in date" trying to run this?

I'm trying to run the following db command against Informix:
delete from table1
where u_id in (select u_id
from table2
where c_id in (select c_id
from ptable
where name = 'Smith'
and dob = '29-08-1946'));
I pass this in as a string to the db.ExecuteNonQuery method in the MS Data Application block and I get the above error?
To get the date format '29-08-1946' to work, you need your DBDATE environment variable set to a value such as "DMY4-" (or "DMY4/"). These are standard variations for the UK (I used them for years; I now use "Y4MD-" exclusively, which matches both ISO 8601:2004 (Date formats) and ISO 9075 (SQL), except when debugging someone else's environment). There are other environment variables that can affect date formatting - quite a lot of them, in fact - but DBDATE takes priority over the others, so it is the big sledgehammer that fixes the problem.
One of the problems is that your notation using a plain string is not portable between US and UK (and ISO) settings of DBDATE. If you have a choice, the neutral constructor for dates is the MDY() function:
WHERE dob = MDY(8,29,1946)
This works regardless of the setting of DBDATE. You can probably use TO_DATE() too:
SELECT TO_DATE('29-08-1946', '%d-%m-%Y') FROM dual;
This generated '1946-08-29 00:00:00.00000' for me - the function generates a DATETIME YEAR TO FRACTION(5) value, but those convert reliably to DATE values in Informix.
You can also use the DATE() function or an explicit cast to DATE (either CAST('29-08-1946' AS DATE) or '29-08-1946'::DATE), but both of those are subject to the whims of the locale of the users.
Your date field is improperly formatted. Since there is no 29th month in the year 1946 that is what is causing the error.
I'd try just swapping the month and day. 08-29-1946.
The way the day and month parts of a date string are read in can depend on your computer's culture settings.
It is always safer to pass date strings to a database in the form 'dd-MMM-yyyy' (i.e. '29-aug-1946')
It's even safer to pass them as YYYY-MM-DD, the dd-MMM-yyyy in that example will fail on a server with a (for example) French locale.

Resources