VB.NET - DateValue("0:0:0") - vb.net

Please see the variable declaration below:
dim DateTest As Date = DateValue("0:0:0")
What is DateTest actually initialised with. If I step through the code, then it says: #12:00:00 AM#. If I try to enter this into the database (datetime field) then an SQLTypeException is thrown, which says: "SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM."
Does DateValue("0:0:0") initialise the date variable with a date value?

Obviously it returns Date.MinValue which is the smallest possible value of Date. The value of this constant is equivalent to 00:00:00.0000000, January 1, 0001. Since the year 0001 is smaller than 1753, the database throws the exception.
I didn't know DateValue, but instead of old VB functions i would use .NET methods like Date.Parse. For example:
Dim DateTest As Date = Date.Parse("2008-05-01")

Ah, the min of a datetime field in .net is much smaller than the min date of a datetime field in Sql Server. If you would like to store a value that matches, I suggest using the DateTime2(7) datatype in sql server.
Please see the following articles about min date times:
tsql min datetime
http://technet.microsoft.com/en-us/library/ms187819.aspx
.net min datetime
http://msdn.microsoft.com/en-us/library/system.datetime.minvalue.aspx
tsql datetime2 description:
http://technet.microsoft.com/en-us/library/bb677335.aspx

Related

CAST vs ssis data flow implicit conversion difference

I have a SSIS package which transfers some data from Oracle to SQL Server.
In Oracle dates are stored as float, e.g. 42824 == '2017-04-01' - application which uses the database is written in Delphi.
While select CAST(42824 as datetime)
in Management Studio results in '2017-04-01 00:00:00.000', the same value (42824) inserted by package into datetime column in SQL Server table shows 2017-03-30 00:00:00.000.
Note: Source data type for this number is DT_R8, changing the type to DT_UI4 in Data Conversion component changes nothing
Can anyone explain this?
About date serials
The value stored in Oracle (42824) is known as date serial , it is also used in Microsoft Excel.
Date Serial represents the number of Days between the date value and the initial value that is 1899-12-30
You can Read more about Date Serials at:
Why is 1899-12-30 the zero date in Access / SQL Server instead of 12/31?
convert Excel Date Serial Number to Regular Date
CAST method
From Microsoft Docs - CAST and CONVERT (Transact-SQL):
Only supported when casting from character data to datetime or smalldatetime. When character data that represents only date or only time components is cast to the datetime or smalldatetime data types, the unspecified time component is set to 00:00:00.000, and the unspecified date component is set to 1900-01-01
So CAST function consider the value 1900-01-01 as an initial value when casting dates. So we need to subtract 2 days when using it to convert Date Serials
There are 2 ways to convert it to date using SQL Server:
select DATEADD(d,42824,'1899-12-30')
select CAST(36464 - 2 as SmallDateTime)
SSIS Implicit conversion
Also according to this Microsoft docs article
DBTYPE_DATE (This is an automation DATE type. It is internally represented as a double.. The whole part is the number of days since December 30, 1899 and the fractional part is the fraction of a day. This type has an accuracy of 1 second, so has an effective scale of 0.)
So implicit conversion in SSIS consider the value 1899-12-30 as an initial value when casting dates. So there is no need to subtract 2 days when using it to convert Date Serials

Date instead of DateTime?

From what I can tell Date and DateTime have the same functionality. Is there a reason why I would want to use one instead of the other?
In VB.NET Date is an alias to System.DateTime, so yes, they're the same thing. You can see all the aliases in this chart on MSDN.
C# has no Date type, but DateTimes do have a Date property which returns a DateTime with all of the time-related fields cleared out.
Specifically it returns:
A new object with the same date as this instance, and the time value set to 12:00:00 midnight (00:00:00).
VB.NET does have a Date type but it is equivalent to a CLR DateTime

How to set default value or binding for datetime to 1/1/0001 12:00:00 AM in SQL Server 2005?

I am trying to put a default value of "1/1/0001 12:00:00 AM" in but first it does not allow me.
So I then tried to put "1/1/0001" but when I test it. It gets changed to (((1)/(1))/(1)) and when I try out the default value it gives back "01/02/1900 12:00:00 AM" I am not sure why.
The range of datetime in SQL Server is January 1, 1753, through December 31, 9999. If you want 1/1/0001 as a value, you must use datetime2 in SQL Server 2008.
Try this
CREATE TABLE MyTable (Id INT, aDate DATETIME NOT NULL DEFAULT('1753-01-01'))
Or, if you want to get "fancy", you could try this:
CREATE DEFAULT [dbo].[DefaultDate] AS '1753-01-01'
GO
CREATE TYPE [dbo].[MyDate] FROM [datetime] NOT NULL
GO
EXEC sys.sp_bindefault
#defname=N'[dbo].[DefaultDate]',
#objname=N'[dbo].[MyDate]'
GO
CREATE TABLE MyTable (Id INT, aDate [MyDate] NOT NULL)
GO
INSERT INTO MyTable (ID) SELECT 1
SELECT * FROM MyTable
[EDIT]
Like Martin Smith very well noticed, sp_bindefault is going to be deleted in a future version (see this ). So, use the first solution to have less headaches with the future upgrades.
First, DateTime data types can only store a minimum date of '1753-01-01'. For SmallDateTime, the minimum date is '1900-01-01'. It is not an accident that they chose this value. The calendar itself changed in 1752 and thus trying to compare the number of days from say '1701-01-01' to now is problematic using standard date math.
However, in SQL Server 2008, there a new DateTime2 or Date either of which can store a value of 0001-01-01 but it would be mistake to do so for the reason I just mentioned.
Third, trying to use an arbitrary date to represent the absence of a date value is a mistake IMO. This is what I call the "magic value" approach to avoiding nulls. IMO, it greatly complicates the calling code as the calling code now has to know about and check for the magic value instead of a null to know whether to display a blank. Instead, you should return nullable DateTime values (DateTime?) from your LINQ code and pass that null all the way to the presentation tier so that the presentation code can deal with absent values.or

How do I strip the date off of a datetime string in SQL SSIS?

I'm working on a data warehouse project and would like to know how to (preferably in a Derived Column component in a Data flow) strip the date piece off of a SQL datetime record.
Once I have the datetime converted to just a time I am going to do a lookup on the time to find the related time record in a time dimension table.
Can someone give me a simple function to accomplish this inside a derived column transform?
Example: Transform a datetime such as "12/02/2008 11:32:21 AM" into simply "11:32:21 AM".
I would just do a cast to DT_DBTIME type (using Derived Column transform, or Convert type transform). DT_DBTIME contains just (hours, minutes, seconds) part of the date/time, so you'll get rid of the date part.
If you need to do this in a variable expression Michael's solution won't work, but you can use the following expression:
(DT_DATE)(DT_DBDATE)GETDATE()
(DT_DBDATE) converts the current date and time to a date only. But the new datatype is not compatiple with SSIS's datetime. Therefore you'll have to use (DT_DATE) for converting to a compatible type.
Courtesy of this solution belongs to Russel Loski who has posted it in his blog:
http://www.bidn.com/blogs/RussLoski/ssas/1458/converting-datetime-to-date-in-ssis
Actually if you reverse the first 2 expressions like this: (DT_DBDATE)(DT_DATE)GETDATE()
instead of (DT_DATE)(DT_DBDATE)GETDATE(), then you will TRUNCATE the time off the date field.
If the DT_DATE expression is before the DT_DBDATE expression, you will still have the time portion in your output, but it will be reset to all zeroes.
Ran into this with writing a report for a scheduling app, needed the time that was stored as part of a datetime data type. I formated the datetime as 0 which gives you this mon dd yyyy hh:miAM (or PM), and just did a substring of that which returned the time only in an AM/PM format.
Example below.
DECLARE #S DATETIME = GETDATE()
SELECT SUBSTRING(CONVERT(NVARCHAR(30), #S , 0) , 13 , 10) AS ApptTime
, CONVERT(NVARCHAR(30), #S , 0) AS ApptDate
I personally use a series of functions for this. E.g.:
ALTER FUNCTION [dbo].[TIMEVALUE]
(
#Datetime datetime
)
RETURNS datetime
AS
BEGIN
RETURN (#Datetime - CAST(ROUND(CAST(#Datetime AS float), 0, 1) AS datetime))
END
I'd love to claim all the credit but it should really go to this guy.

How do I store just a date in MS SQL from VB?

My project requires I use VB (5 or 6)* to store a date in an SQL Server database. The SQL datetime type includes the time, which I don't want. I'm also aware that VB's representation of a date doesn't mirror that of SQL Server.
So, how can I store a date held in VB's date type in the SQL database, as the datetime at midnight on that date, for example?
Edit: I need to use the date to select rows further down the line, so I can't get away with just truncating it on read.
*I know, I you were me, you wouldn't start from here. But given the constraints, any VB6/MS SQL fiends out there?
VB6 has a DateValue() function which returns the date portion of a Date/Time value, with the time portion "zeroed out". (Note: When the time portion of a date/time variable is "zeroed out", the time would be interpreted as 12:00 AM.)
SQL Server 2008 has new date and time data types. There is the "Date" data type if you don't want to store the time component.
Use the DateTime column and just truncate the time at the presentation level.
Try inserting and updating the date like this:
CAST(FLOOR(CAST(#DateTime AS float)) AS datetime)
We have this in a UDF and it basically strips the time part from a datetime.
In VB you can use the Date() function to return the current date with no time element.
If you an use an ADO Parameter object with a Command object then the OLE DB provider should handle the conversion of a VB Date type to the SQL Server DATETIME value.
In SQL Server (pre SQL 2008 DATE type) you should create a CHECK constraint on the column to ensure it is not possible to add a date with a time element (note I've used an unambiguous language 'safe' format for my DATETIME literals) e.g.
ALTER TABLE MyTable ADD
vb_date DATETIME NOT NULL
CONSTRAINT vb_date__no_time_element
CHECK ((vb_date = DATEADD(DAY, DATEDIFF(DAY, '1990-01-01T00:00:00.000', vb_date), '1990-01-01T00:00:00.000')));
I would just use DateSerial to create the date you need. You pass it a year, month and day and it gives you a date with midnight as the time. You can then use it to pass as a parameter to an ADO command or similar. When you read it, it will have midnight so that isn't a problem. I like it better than DateValue as there is no string conversion. If you really want you can create your own function like DateValue that uses DateSerial.
Function JustTheDatePlease(ByVal dtSource As Date) As Date
JustTheDatePlease = DateSerial(Year(dtSource), Month(dtSource), Day(dtSource))
End Function
If for some reason you aren't using parameterized queries, and you really should have a good excuse for this, you can use the ODBC canonical form of a date in your queries. You just format the date as {d 'yyyy-mm-dd'} for example {d '2009-04-06'}.