Postgresql date format - django

I have a web application (written with python/django) that (due a bad specification) Web Forms expecting "YYYY-mm-dd" date format and others using "dd/mm/yy" date format.
Is there a way to tell postgresql to accept dates in both formats? for example, to try "dd/mm/yy" and, if it fails, then try "yyyy-mm-dd".
That would be awesome.

From the fine manual:
Date and time input is accepted in almost any reasonable format, including ISO 8601, SQL-compatible, traditional POSTGRES, and others. For some formats, ordering of day, month, and year in date input is ambiguous and there is support for specifying the expected ordering of these fields. Set the DateStyle parameter to MDY to select month-day-year interpretation, DMY to select day-month-year interpretation, or YMD to select year-month-day interpretation.
PostgreSQL is more flexible in handling date/time input than the SQL standard requires. See Appendix B for the exact parsing rules of date/time input and for the recognized text fields including months, days of the week, and time zones.
So PostgreSQL should be able to deal with just about any date format you throw at it. Your "dd/mm/yy" format is, however, ambiguous. But, there is the DateStyle configuration parameter to help with such ambiguity.
For example:
=> create table x (d date not null);
=> insert into x values ('2001-01-10');
=> insert into x values ('Feb 2 2980');
=> insert into x values ('01/02/03');
=> select * from x;
d
------------
2001-01-10
2980-02-02
2003-02-01
That said, I'd recommend moving everything to ISO 8601 (YYYY-MM-DD) internally and handle the conversions at the edges of the application. OTOH, there is reality to contend with so you should do whatever you have to do to make it go.

If those are the only two formats possible then it may be better to explicitly allow only those, rather than rely on postgres to interpret. For example:
with w as (select '2011-12-13' as input_date union select '13/12/2011')
select case when input_date~'^\d\d\d\d-\d\d-\d\d$'
then to_date(input_date, 'yyyy-mm-dd')
when input_date~'^\d\d/\d\d/\d\d\d\d$'
then to_date(input_date, 'dd/mm/yyyy')
end
from w;
case
------------
2011-12-13
2011-12-13
(2 rows)

Related

Cannot parse UTC date in Athena

I have the date string in the form: 2019-02-18 09:17:31.260000+00:00 and I am trying to convert it into date in Athena.
I have tried converting into timestamp as suggested in the SO answers but failed.
There is a discussion in https://github.com/prestodb/presto/issues/10567 but no answer to this particular date format.
I tried several format like 'YYYY-MM-dd HH:mm:ss.SSSSSSZ' but doesn't work and get error like INVALID_FUNCTION_ARGUMENT: Invalid format:..is malformed at "+00:00".
Been stuck for a while, any help is appreciated!
Athena is based on a very old version of Presto, and there is no straightforwad way of doing that with some string manipulation trick. For instance, you can use regexp_replace to extract the part of the string that's compatible with the built-in timestamp with timezone type and do:
SELECT cast(regexp_replace('2019-02-18 09:17:31.260000+00:00','(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3})\d{3}(.*)', '$1$2') AS timestamp with time zone)
Recent versions of Trino (formerly known as PrestoSQL) introduced support for variable-precision temporal types with up to nanosecond precision (12 decimals).
With that feature, you can just do:
trino> select cast('2019-02-18 09:17:31.260000+00:00' as timestamp(6) with time zone);
_col0
--------------------------------
2019-02-18 09:17:31.260000 UTC
(1 row)
A shorter version to Martin Traverso's answer is to sub string the extra characters:
select cast(substr('2019-02-18 09:17:31.260000+00:00',1,23) as timestamp);

How to correctly select date field using libpqxx?

I am trying to select date field from PostgreSQL database using libpqxx and C++.
I would use this code, but I don't know if it is legal. I have searched in the documentation but I haven't any documented way.
using time_point = std::chrono::steady_clock::time_point;
pqxx::work txn(c);
auto&& rst = txn.exec("SELECT date FROM table");
for(auto&& row : rst)
time_point date = row[0].as<time_point>();
Is this okey please? Do you know any better alternative?
I would like the same with date time and time field. Is there any difference please?
Thank you.
--
the documentation for field type: https://libpqxx.readthedocs.io/en/6.4/a01063.html#a3a55f6b44040b68e70382d9db7dea457
The answer on Github by JadeMatrix:
field.as<>() will work with any type for which a specialization of pqxx::string_traits<> exists. libpqxx comes with support for std::string, builtin numerics (int, etc.), and maybe a few others I don't remember.
Support for std::chrono:: types are missing by default, unfortunately. You can implement your own, but be warned that they will only work for TIMESTAMP WITHOUT TIME ZONE, DATE, TIME WITHOUT TIME ZONE, and INTERVAL. To correctly support … WITH TIME ZONE you will need Howard Hinnant's date library, which is what I use (there is talk of adding it to the standard library).
If you want, I can share my code, which relies on date functionality for parsing Postgres date/time strings (ISO 8601 format).

Server side Validation for DateTime Stamp

In my application, server side date validations were done through IsDate which is very inconsistent in behavior. I used isValid("USdate",DateVar), that works fine with incoming dates, but when DateVar is a date time stamp it fails. Values coming in DateVar could be anything, a date, a time, a date & time or even some invalid data. If I use Date mask with isValid, that behaves like isDate and of no use. How I can accomplish this.
All "dates" that will be arriving via a request - be they via a URL parameter, a form submission, a cookie, etc - will be strings, not dates.
What you need to do is to work out what string formats you will allow, and validate them accordingly.
EG: you might decide that yyyy-mm-dd is OK, but you won't accept m/d/yy. You might pass them as three separate components for y, m and d. But you really oughtn't try to accept any old format, as you will need to have a validator for each format, and there's a law of diminishing returns there: people won't expect to use any format they like; they'll be expecting you to guide them. You also need to be mindful that if you ask me to type in today's date, I'd give you 4/5/2015. But to you that might represent April 5.
Given various month-length and leap-year rules, really the easiest and most reliable way to see if and input string represents a date in an acceptable format do this:
Validate the format mask, eg: if you're accepting yyyy-mm-dd, then the input needs to be \d{4}-\d{2}-\d{2}. Then at least you know the string has been formed properly.
Then extract the components from the string, and attempt to create a date object with them. If it doesn't error: it's OK.
Last: check any date boundaries within / outwith which the date needs to fall.

Excel international date formatting

I am having problems formatting Excel datetimes, so that it works internationally. Our program is written in C++ and uses COM to export data from our database to Excel, and this includes datetime fields.
If we don't supply a formatting mask, some installations of Excel displays these dates as Serial numbers (days since 1900.01.01 followed by time as a 24-hour fraction). This is unreadable to a human, so we ha found out that we MUST supply a date formatting mask to be sure that it displays readable.
The problem - as I see it - is that Excel uses international formatting masks. For example; the UK datetime format mask might be "YYYY-MM-DD HH:MM".
But if the format mask is sent to an Excel that is installed in Sweden, it fails since the Swedish version of the Excel uses "ÅÅÅÅ-MM-DD tt:mm".
It's highly impractical to have 150 different national datetime formatting masks in our application to support different countries.
Is there a way to write formatting masks so that they include locale, such that we would be allowed to use ONE single mask?
Unless you are using the date functionality in Excel, the easiest way to handle this is to decide on a format and then create a string yourself in that format and set the cell accordingly.
This comic: http://xkcd.com/1179/ might help you choose a standard to go with. Otherwise, clients that open your file in different countries will have differently formatted data. Just pick a standard and force your data to that standard.
Edited to add: There are libraries that can make this really easy for your as well... http://www.libxl.com/read-write-excel-date-time.html
Edited to add part2: Basically what I'm trying to get at is to avoid asking for the asmk and just format the data yourself (if that makes sense).
I recommend doing the following: Create an excel with date formatting on a specific cell and save this for your program to use.
Now when the program runs it will open this use this excel file to retrieve the local date formatting from the excel and the specified cell.
When you have multiple formats to save just use different cells for them.
It is not a nice way but will work afaik.
Alteratively you could consider creating an xla(m) file that will use vba and a command to feed back the local formatting characters through a function like:
Public Function localChar(charIn As Range) As String
localChar = charIn.NumberFormatLocal
End Function
Also not a very clean method, but it might do the trick for you.

Parsing a date in ColdFusion

I have a date stored in the format dd-mm-yyyy. I want to store the day, date and year as individual variables, while getting rid of any leading zeros (e.g. "09-09-2010" is stored as 9, 9, 2010).
I attempted to use the code on this page to split the date by dashes, but it is throwing expression errors.
Some people, when confronted with a
problem, think "I know, I'll use
regular expressions." Now they have
two problems.
Coding Horror: Regular Expressions: Now You Have Two Problems
Investigate the ColdFusion functions month(date), day(date) and year(date).
Update: you can pass a string to these functions so long as CF can turn into a date.
When you say that you have a date
stored in the format dd-mm-yyyy
are you sure you aren't confusing this with the way that your database UI is presenting it to you or are you actually storing the date in this format (for example, by writing it this way to a text file or a varchar column rather than a DateTime column)?
The reason I ask is that if a date is stored in a database as a date then CF will represent it as a date irrespective of how it appears in, say, SQL Management Studio. If this is the case then you can simply split the parts out using DatePart("datepart", "date").
If you have a date in a text format (such as from a form submission or because it has been stored as plain text) then you should be able to parse it in to a DateTime object using LSParseDateTime() and then use the DatePart(...) method on it to split out the parts.
See http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=functions_c-d_30.html
(sorry, can't post the URL to the other function due to lack of SO points!)
for the documentation on this.
As an aside, if you are using SQL2005 (or later) then you can create computed columns on the date field in order to split out the day, year and month at the database level. I thought I'd mention this just in case it proves useful.
Steve
If you're working with a string in that format, there's no need for regular expressions.
myDate = "13-12-2010";
theDay = listGetAt(myDate,1,"-");
theMonth = listGetAt(myDate,2,"-");
theYear = listGetAt(myDate,3,"-");
Using the val() function will also drop leading zeroes, if any.