Dates aren't adjusting for timezone - sql-server-2012

INSPDATE is a datetime field in an MS SQL database. Normally when we pull in a date, the browser automatically corrects it to our EST, but it doesn't work on this inspection report I'm creating. I've tried
echo date('m/d/Y g:i a ', strtotime($row['INSPDATE']));
But that returns the date from 1970 (12/31/1969 7:00 pm) and isn't pulling in the value from the database.
Below is what I was using that returns the date just as it's saved in the db. I know there's a way to subtract 18000 to this to adjust to EST (-5 hrs), but I'm not sure where to put it. I get error messages about mixing up datetimes and non-numeric values.
<?php
require_once ('connection.php');
$sql = "SELECT INSPDATE, FACILID FROM dbo.SWFACILITYINSPECTION WHERE FACILID = 'E667'";
$query = sqlsrv_query( $conn, $sql );
while ($row=sqlsrv_fetch_array( $query )) {
//This will show dates, but it's database time (UTC, so +5 hours)
echo date_format($row['INSPDATE'], 'm/d/Y g:i a ');
}
?>

You should always do this conversion in application logic, since your sql is inline, I suppose you could embed the calculation in your sql. If I knew PHP better, I would be more inclined to learn the date math using the language of the application, that way you could build a time zone library to use on dates elsewhere and free your queries,store procedures up to be, just queries and stored procedures that return data.
DECLARE #Offset INT = -5
SELECT INSPDATE_UTC=INSPDATE, INSPDATE_LOCAL = DATEADD(HOUR, #Offset,INSPDATE)

Related

How to get time from Date & time field in SQL? [duplicate]

In my table I have a datetime field that stores dates in this format:
YYYY/mm/dd HH:MM:SS
Now I need to retrieve via query only the time.
I have tried this
SELECT time(start_date)
FROM table
LIMIT 100
but no luck, it gives me "not an error" but no records return
Any idea?
EDIT
I solved it! The problem is that SQLite needs Times to be in a format in which if hours, minutes and seconds are less than 10 they must be represented with the zero.
For example:
H:M:S
WRONG --> 12:1:30
RIGHT --> 12:01:30
Moreover, the correct format for dates is YYYY-mm-dd and not YYYY/mm/dd.
There is a built-in function in SQLite called strftime(format,datetime) which can be used to get whatever piece of information you require from the given datetime. In your case you can use in this way:
SELECT strftime('%H:%M:%S',start_date) FROM table LIMIT 100;

sql coding to_date meaning

I have a sql code and couldn't understand the meaning
proc sql; create table tito as
select distinct j.perjobs_pidm,
, to_date(to_char(t.pertito_time_entry_date,'YYYYMMDD') ||t.pertito_time_in,'YYYYMMDDHH24MI') tmi
from stg.pertito t
, stg.perjobs j
where t.pertito_jobs_seqno = j.perjobs_seqno
;quit;
the part I didn't understand is to_date part. How can I change this to SAS language. What is that code means? Thanks!
This is the SQL equivalent of input(put(var,DATE9.)||':'||put(var2,TIME8.),DATETIME.), one way to combine date and time into datetime. A superior SAS method would be
dtvar = dhms(datevar,0,0,timevar);
which uses the date for 'days' and the time for 'seconds' in the DHMS (days hours minutes seconds) function.
This works because a time variable is the number of seconds since midnight; so DHMS(date,0,0,time) creates a datetime variable. IE, if it is 8am sharp, you could either do:
dhms(date,8,0,0) -> 8:00am on date
or
dhms(date,0,0,480) -> 8:00am on date
since 480 = 60*8.
That code is taking two columns pertito_time_entry_date and pertito_time_in, and formatting then concatenating them in the code:
to_char(t.pertito_time_entry_date,'YYYYMMDD') ||t.pertito_time_in
That whole block is then wrapped in to_date() which formats the entire expression to YYYYMMDDHH24MI. This will then be stored as a date value that SAS can understand in the column tito.tmi.

Create a date, insert it into database, compare, it's different

The goal
I've got a really strange problem. My goal is to compare a dynamic date in database using dbunit (the database is an Oracle one). This dynamic date is the today date (comparing static date works...)
The experimentation
To compare date, I use this very simple code :
#Test
public void simpleDateTest() throws DatabaseUnitException, SQLException {
// create a date corresponding to today
Date today = new Date();
// load a dataset
IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(getClass()
.getResource("/dataset.xml"));
// replace [TODAY] by the today date
ReplacementDataSet rDataSet = new ReplacementDataSet(expectedDataSet);
rDataSet.addReplacementObject("[TODAY]", today);
// insert the dataset
DatabaseConnection connection = getConnection();
DatabaseOperation.CLEAN_INSERT.execute(connection, rDataSet);
// do a simple query to get some fields, em is the entity manager which uses the same connection as above
Query q = em
.createNativeQuery("SELECT ID, MY_DATE FROM MY_TABLE");
List<Object[]> result = q.getResultList();
// compare the date with today date
assertEquals(today.getTime(), ((Date) result.get(0)[1]).getTime());
}
With the following dataset :
<?xml version='1.0' encoding='UTF-8'?>
<dataset>
<MY_TABLE ID="1" MY_DATE="[TODAY]" />
</dataset>
The problem
I don't know why, but the assert failed ! When comparing the two dates, there is a very few milliseconds difference. The error is something like that :
java.lang.AssertionError: expected:<1358262234801> but was:<1358262234000>
I don't understand how is it possible to have different dates because they are quite normally the same !
Any clue to understand the problem and how to solve it ?
The Oracle Date type doesn't have a resolution of milliseconds, it only has a resolution of seconds.
When saving a time to the database the milliseconds are simply stripped off. When you look at the actual value you see that the last three digits are all zero.
Assuming that today is a java.util.Date, the Java Date has millisecond precision. An Oracle date, on the other hand, does not have millisecond precision. So you would expect to lose some precision when you store a java.util.Date in Oracle and retrieve it back.
You could store the data in an Oracle timestamp column-- that will have millisecond precision. Or you could strip off the milliseconds from the Java Date before writing it to the database.

Working with Time zones in SQL

I need to get a SQL query to output the date from a datetime field in the format Mmm dd yyyy hh:mm AM/PM. The best aproach I've been able to come up with so far is:
SELECT Left(
Convert(
nvarchar(30),
SWITCHOFFSET(
CAST(datetime1 as datetimeoffset),
'-05:00'
),
0
),
LEN(
Convert(
nvarchar(30),
SWITCHOFFSET(
CAST(datetime1 as datetimeoffset),
'-05:00'
)
)
)-11
)
However, a) it's ugly! I feel like this should be simpler than that; and b) I think going to have to change my query when Daylight savings time comes back.
The source data is a sharepoint calendar, so I can't simply change the datatype to datetimeoffset.
Any ideas?
Thanks,
Steve
As a general principal you should not be using SQL to format data into something presentable for the front end. You should be getting a DateTime type back, and using code on the format to change it. What if a future requirement comes in to support DD/MM/YYY? You'll need a separate query. It's better to let the front end format it for that.
With that in mind, store 2 pieces of data in the database. 1) DateTime as a UTC value 2) The current user's timezone (not offset)
The reason you store timezone and not offset is because of all the rule involved with DST. For example, the days that DST starts end aren't fixed in stone. They are set for a country each year, but that schedule can change, and that's a bad reason to need to update your code (unless you're writing a timezone library.)
Then once you have these two pieces of data, you retrieve the date, and the timezone, and construct a new object in the server that allows you to convert the time in the DB to the local time.
Am I missing something, or is it simply:
Convert(nvarchar(30), DATEADD(Hour, -5, datetime1), 100)
That should add -5 hours to datetime1, then convert it into the format you were specifying.
I do agree that you should try to deal with timezones instead of offsets whenever possible.

How to convert timezones in SQL Server 2005?

All my times are in UTC timezone now I need to somehow convert it to the users timezone(I have it stored in the db as well and uses the ids of the windows timezones).
How can I do this in SQL Server 2005?
Edit
So I tried to do that extended stored procedure but with Timezoneinfo I get this error
Deploy error SQL01268: .Net SqlClient
Data Provider: Msg 6503, Level 16,
State 12, Line 1 Assembly
'system.core, version=3.5.0.0,
culture=neutral,
publickeytoken=b77a5c561934e089.' was
not found in the SQL catalog. An
error occurred while the batch was
being executed.
if I take that line out I can deploy it. Any ideas how to get around this?
Since SQL Server doesn't provide out of the box support for this, you might consider writing a .Net dll stored procedure, that makes use of the .Net TimeZoneInfo object , this object takes all rules including DST into consideration. This class allows you to convert time from one zone to another too. I hope this helps.
DateTime hwTime = new DateTime(2007, 02, 01, 08, 00, 00);
try
{
TimeZoneInfo hwZone = TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time");
Console.WriteLine("{0} {1} is {2} local time.",
hwTime,
hwZone.IsDaylightSavingTime(hwTime) ? hwZone.DaylightName : hwZone.StandardName,
TimeZoneInfo.ConvertTime(hwTime, hwZone, TimeZoneInfo.Local));
}
catch (TimeZoneNotFoundException)
{
Console.WriteLine("The registry does not define the Hawaiian Standard Time zone.");
}
catch (InvalidTimeZoneException)
{
Console.WriteLine("Registry data on the Hawaiian STandard Time zone has been corrupted.");
}
[Edit]
Tutorial Creating Simple .Net DLL stored procedure.
Another useful tutorial, has more detail on deployment.
SQL Server does not provide a simple
way to convert a UTC datetime value to
a local time value.
However, the page that is from includes:
A table (tbTimeZoneInfo) with
data to provide the Time Zone
information and two functions to
convert a UTC datetime value to any
Local Time Zone.
Wrote this just for you:
DECLARE #UTCDate DateTime /* Replace with the UTC datetime stored in your table */
DECLARE #LocalDate DateTime
DECLARE #TimeZoneOffset int /* Replace with the offset stored in your table */
SET #TimeZoneOffset = -8 /* PST */
SET #UTCDate = GETUTCDATE()
SET #LocalDate = DATEADD(Hour, #TimeZoneOffset, #UTCDate)
SELECT #UTCDate
SELECT #LocalDate
Let me know if it doesn't work.
SQL Server 2008 would have the DATETIMEOFFSET data type (which includes the time zone) plus functions like SWITCHOFFSET to switch from one timezone offset to another.
But on the 2005 version, there's not much support for timezones.
Any chance you could upgrade any time soon??
I use this function:
CREATE FUNCTION fnConvertGMTToLocalTime
(
#GMTValue Datetime,
#TimeZoneOffset int
)
RETURNS DateTime
AS
BEGIN
DECLARE #LocalTime dateTime
SELECT #LocalTime = DateAdd(Hour, #TimeZoneOffset, #GMTvalue)
RETURN #LocalTime
END
It doesn't consider daylight savings time...but i don't need that anyway.