The problem in short: The same database returns dates in a different format on different servers and I'm having trouble to configure it to correct date format.
I have the following situation:
A PHP-based web application that gets it's data from Microsoft FoxPro 9 databases.
The database connection is made with OleDB. In PHP this utilises ADODB through COM objects:
$this->connection = new COM("ADODB.Connection");
$this->connection->Open($this->connectionString);
The connection string looks like this:
Provider=VFPOLEDB.1; Mode=Share Deny None; Window Handle=0;
Locale Identifier=1033; Prompt=4; Extended Properties=0;
User ID=; Password=; Mask Password=False; Cache Authentication=False;
Encrypt Password=False; OLE DB Services=0; Collating Sequence=MACHINE; DSN=;
DELETED=True; ENGINEBEHAVIOR=80; TABLEVALIDATE=0;
Data Source=\\path\to\file.DBC
The program is deployed on different servers throughout the world, running on different versions of Windows Server (2003-2008 R2). Query's are executed the following way:
$this->connection->Execute($query);
This returns a resultset with all values in plaintext. This is where the problem arises. The databases don't use the same formatting for dates, which makes it difficult to process the dates later on in PHP.
So far, the app can cope with the US format: mm/dd/yyyy and the dutch format: dd-mm-yyyy. The program just assumes that when the date contains slashes the US format is used and when there are hyphens the d-m-y format is used.
This has been going fine for a long time, but now we recently deployed the program to a server in Brazil, which returns dates in the Brazilian format dd/mm/yyyy. The program obviously now confuses this with the US format.
I've been trying to get the database to report in a different date format (US) to no avail.
On two different dev-environments, changing the Regional settings of windows to a different country immediately alters the date-format the database uses. These dev-environments are all Windows 7 systems.
However, this won't work on the servers with Windows Server. I have changed around all of the Regional settings (Formats, Location and System locale) on multiple servers without any results. Even after rebooting or reïnstalling FoxPro with the correct regional settings. The databases keep reporting in the date-format they seem stuck in.
Does anybody know how I can change the date-format used by FoxPro on a Windows Server environment?
Other options I have explored include putting regional information into the DSN, but couldn't I find any possible way. Also the FoxPro statement SET DATE TO ..... is not accepted through OleDB.
Altering the application to understand the Brazilian format or to add a bunch of if-else statements doesn't seem like a feasible solution.
The FoxPro date type is date-format-insensitive. That is, if you simply return the value as a date (datetime) rather than converting to character, you shouldn't have any problems.
Wrap your FoxPro date field the DTOC function, with the second optional parameter. This will return a standard YYYY-MM-DD style date, regardless of regional setting.
SELECT DTOC(dDate) as dDate FROM Alias
If that's not feasible, you'll need to investigate the functions to explicitly set a locale in FoxPro, such as the intuitively named SYS(3005).
And if even that's not feasible, you'll need to resort to requiring servers in foreign countries to have their regional settings standardized at the OS level.
Maybe be explicit in your query and handle reconstructing the date within the web application. So if you have a date-type field in VFP called MyDate then do:
select x, y, z, day(MyDate) as daynum, month(MyDate) as monthnum, ;
year(MyDate) as yearnum from mytable
OK, so it's more work on the other reconstructing a date from that but at least it should be location-agnostic.
Related
I am using Oracle SQL Developer.
My tutor has asked us to include Dynamic Queries into our SQL statement.
Part of my query is this:
where booking.date_event != to_date('20140309','yyyymmdd') and booking.occassion_id=2
I have modified the query one step at a time to include the dynamic aspect. So it now looks like this:
where booking.date_event != to_date('20140309','yyyymmdd') and booking.occassion_id='&occassion_id'
This gives me the pop-up box to enter the ID correctly and it works correctly.
However, i now want to do the same for the date. But obviously entering a date in the format 'yyyymmdd' is not very user friendly.
How can i change my query to either allow for various types of date format or to add a message to the pop up box to inform the user to use the correct format? At the moment the pop up box only says "Date_Event" and an input box.
try to_date function. Here is some tips for to_date function.
http://www.dba-oracle.com/f_to_date.htm
SQL Developer is no tool for users. So you don't really have to worry about '20140309' format not being user friendly. For real users you would write a real app that accepts a date (with a calendar popup for instance) and sends it to the database in appropriate format.
However to have it a bit more convenient in SQL Developer, you could use to_date without format. Having set your environment and the database to the same locale, you could simply enter a date in the format you are used to (e.g. 9.3.13 or 09.03.2013 or March 9, 2013) and it should all work.
When I Use the below code:
Dim cmd As New OdbcCommand("SELECT GETDATE()", oConn)
retVal = cmd.ExecuteScalar()
The resulting output is:
8/1/2013 10:10:39 AM
When I run the exact same query directly in Management Studio I get:
2013-08-01 10:10:39.317
When I check my computer settings versus the SQL Server settings they match.
Anyone know what I need to do to ensure it matches?
Specifically I am talking about the Date format difference.
If you want the date output with a specific string format, then you can use CONVERT() with a style number. For example:
SELECT CONVERT(CHAR(20), GETDATE(), 22),
CONVERT(CHAR(23), GETDATE(), 21);
Results:
-------------------- -----------------------
08/01/13 10:53:54 AM 2013-08-01 10:53:54.943
However, if you are using the date for things other than direct display, only apply that formatting when you are displaying it. For all other purposes it should remain a datetime type and should not be converted to a string.
As for the differences in the actual time value, it's not clear what problem you're talking about, but I suspect you simply ran these queries half an hour apart. If those were run at or around the same time, it looks like the server is half an hour fast - maybe it's in a different time zone or maybe it's just a lot of drift or someone not bothering to use a time service. Your application should never use the time / time zone of the client, especially if it's distributed - always use the time on the server.
Dates have no format. Format comes into play only when you convert dates to a string. The forma used depends on who does the conversion: the server or the client?
Your VB.NET query returns a date from the server and converts it to a string when you write it to the console, a form or whatever. VB.NET uses your programm's CurrentCulture, whose defaults come from the current user's regional settings.
When you display data in SSMS, an ISO format is used so there is no ambiguity when you edit the data.
When you compare date and string values in a query, either explicitly by converting a date to a string or implicitly because you just typed MyDate = '13/1/2013, a conversion is made using the column's collation. Collations are inheritted so the column's collation is the same as the database's collation.
Try this:
net time \\SERVER_NAME
Note: Obviously SERVER_NAME is the name of your SQL Server machine.
Do you see a 30 minute difference in the result of that call?
I looked deeper into the code and found that some enterprising fellow had added code to a line of SQL later in the process which forces DMY format on that query.
so the code in the VB is returning the proper Date on the app machine. Which means that there must be a difference between my computer and the app machine.
Another coder ran into the same issue and so there solution was to add the below code to the SQL that was pulling from the DB.
SET DATEFORMAT dmy
This forces the SQL to use DMY format... I removed this code Compiled and ran the EXE from the server machine and my issue dried up!
Thanks for everyone's help.
Having an issue with vb.net clients interpreting timestamps from my oracle 11g server differently. I am using VS2010, VB.NET, 11.2.0.30 driver, Win XP on the client machines.
the software is identical on both machines, and the users have the same permissions on the server.
When I login through toad with each users credentials and do a SELECT SYSDATE FROM DUAL; I get YYYY-MM-DD HH24:MI:SS format.
through my application when i do a SELECT SYSDATE FROM DUAL;
PC1: DD/MM/YYYY HH24:MI:SS
PC2: YYYY-MM-DD HH24:MI:SS
I did change my serverside settings to use the YYYY-MM-DD 24HH:MI:SS format
Why is the setting being overruled on only some of the pcs? and how can i get it consistent for all clients?
thanks in advance.
Each client has its own NLS_DATE_FORMAT setting, which might be set somewhere visible (e.g. in Toad), or might be defaulted by the platform or driver, and might be inherited indirectly through locale settings. Having NLS_TIMESTAMP_FORMAT overridden by default is less common I think, but I'm not sure if you're referring to Oracle TIMESTAMP or DATE, which also has a time component.
The client setting always overrides the server setting, so changing the server is unlikely to help, and you might just have some clients that are already set with a matching format. The client setting can itself be explicitly overridden after you connect at session level with an alter session command, or individually in SQL statements. The precedence is shown in the globalization support guide.
In general you should never rely on implicit data conversions. Other than in simple ad hoc queries, date are normally selected for display using an explicit date format mask, e.g. select to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') from dual. If you have an application that expects a date to be returned (as a string) in a particular format then it's safer to do that... though normally you'd pull a DATE back and let the client do the formatting anyway.
It's arguably even more important to always specify a format mask when inserting data from a string with a to_date() call, but again your client would normally handle that and pass a DATE.
My application is based on format: mm/dd/yyyy
After deploying the database to the customer's side, it is based on: dd/mm/yyyy
I dont want to change all of my queries, so how can I change all the datetime format for the whole database?
It is MSSQL Server 2005
Thanks in advance.
If you wanted to you could write a class which would interoperate the date() function (which produces a timestamp) into a real date, which you could then insert into the database.
But you should be more specific, ie, what languages are you using to code in, if you are, etc?
You'll need to change the default language for the database and then change the default language for all of your logins. I have a blog that explains this:
Setting a standard date format
look at :Change default date time format on a single database in SQL Server
If question is related with SQL server only, it should be closed. If no, it should be moved to C# topic.
At my company we store the information gathered from our site wide error template, into the database, but because of the format of the error.datetime it is making hard for me to do any sql queries for different date ranges.
Has anyone used some t-sql or coldfusion code to convert it to a mm/dd/yyyy format?
Here is an example of the format it currently is as.
Sun Jun 13 21:54:32 CDT 2010
But for any queries, I need to do, I have in a better format, I believe.
On the CF side, you should be able to user createOdbcDateTime() to correctly format it for the database or dateformat() to format it as text. If the date is coming back as text instead of a date object, you could use parseDateTime() to convert to a date object.
As an alternative, you could avoid having to convert dates at all if you just use the SQL Server built-in getDate() function to fill out your date column as the error is being inserted into the database.
It may not be exactly the same time (i.e. it might be out by a ms or 10) but it should be pretty close and perhaps good enough for your purposes.
Just make sure that your database server and application server are time synchronised!