Convert DateTime to Hex equivalent in VB.NET - vb.net

How do I achieve the same in VB.NET which is so easily done in SQL Server.
SELECT CAST(GETDATE() AS VARBINARY(8)) --GIVES THE CURRENT TIME IN HEX
Now my question is how can I create the same string in VB.NET so that I can compare in SQL Server as such -
SELECT CASE WHEN GETDATE()=CAST(0X00009F5E00D8DF7C AS DATETIME) THEN 'TRUE' ELSE 'FALSE' END -- 0X00009F5E00D8DF7C WILL BE THE VALUE I GET IN VB.NET WHEN I CONVERT IT DATE.NOW() TO HEX

This answer simply addresses conversion of .NET DateTimes to a binary format that is equivalent to SQL Server's datetime datatype, so I believe it is different enough that it warrants a separate answer (I checked here and here to be sure it was ok).
As #Martin Smith pointed out, the binary format of datetime is not simply a number of ticks since a specific point in time.
datetime is stored as 8 bytes, the first 4 bytes being the number of days since 01-01-1900 and the the second 4 bytes being the number of "ticks" since midnight of that day, where a tick is 10/3 milliseconds.
In order to convert a .NET DateTime to an equivalent binary representation, we need to determine the number of days since '01-01-1900', convert that to hex, and then the number of ticks since midnight, which is slightly complicated since a .NET tick is 100ns.
For example:
DateTime dt = DateTime.Now;
DateTime zero = new DateTime(1900, 1, 1);
TimeSpan ts = dt - zero;
TimeSpan ms = ts.Subtract(new TimeSpan(ts.Days, 0, 0, 0));
string hex = "0x" + ts.Days.ToString("X8") + ((int)(ms.TotalMilliseconds/3.33333333)).ToString("X8");
When I ran this code, dt was 9/14/2011 23:19:03.366, and it set hex to 0x00009F5E01804321, which converted to 2011-09-14 23:19:03.363 in SQL Server.
I believe you will always have a problem getting the exact date because of rounding, but if you can use a query where the datetime doesn't have to match exactly, down to the millisecond, this could be close enough.
Edit
In my comment under the first answer I posted, I asked about SQL Server 2008, because the datetime2 data type does store time with an accuracy of 100ns (at least, it does with the default precision), which matches up nicely with .NET. If you are interested in how that is stored at the binary level in SQL Server, see my answer to an older question.

I had to convert some dates in dbscript from SQL Server's hex format string to standard datetime string (for use with TSQL to MySQL script translation). I used some codes I looked up in here and came up with:
static string HexDateTimeToDateTimeString(string dateTimeHexString)
{
string datePartHexString = dateTimeHexString.Substring(0, 8);
int datePartInt = Convert.ToInt32(datePartHexString, 16);
DateTime dateTimeFinal = (new DateTime(1900, 1, 1)).AddDays(datePartInt);
string timePartHexString = dateTimeHexString.Substring(8, 8);
int timePartInt = Convert.ToInt32(timePartHexString, 16);
double timePart = timePartInt * 10 / 3;
dateTimeFinal = dateTimeFinal.AddMilliseconds(timePart);
return dateTimeFinal.ToString();
}
static string HexDateToDateString(string dateHexString)
{
int days = byte.Parse(dateHexString.Substring(0, 2), NumberStyles.HexNumber)
| byte.Parse(dateHexString.Substring(2, 2), NumberStyles.HexNumber) << 8
| byte.Parse(dateHexString.Substring(4, 2), NumberStyles.HexNumber) << 16;
DateTime dateFinal = new DateTime(1, 1, 1).AddDays(days);
return dateFinal.Date.ToString();
}
Maybe not optimized, but shows the idea.

My first inclination is that the clients should not be constructing sql statements to be executed by your data access layer, but assuming you must get something working soon, you might consider using a parameterized query instead.
If you are making method calls from the client(s) to your other application tiers, you can construct a SqlCommand on the client and pass that to the next tier where it would be executed.
VB.NET is not the language I normally use, so please forgive any syntax errors.
On the client:
Dim dateValue As Date = DateTime.Now
Dim queryText As String = "SELECT CASE WHEN GETDATE() = #Date THEN 'True' ELSE 'False' END"
Dim command As SqlCommand = New SqlCommand(queryText)
command.Parameters.AddWithValue("#Date", dateValue)
If you must send a string, you could convert the DateTime to a string on the client and then convert back to a DateTime on the data access tier, using a common format.
On the client:
Dim queryText As String = "SELECT CASE WHEN GETDATE() = #Date THEN 'True' ELSE 'False' END"
Dim dateValue As Date = DateTime.Now
Dim dateString = DateTime.Now.ToString("M/d/yyyy H:mm:ss.fff", DateTimeFormatInfo.InvariantInfo)
Then send both queryText and dateString to the next tier in your application, where it would convert back to Date and again use a parameterized query:
Dim dateValue As Date
Date.TryParseExact(dateString, "M/d/yyyy H:mm:ss.fff", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, dateValue)
Dim command As SqlCommand = New SqlCommand(queryText)
command.Parameters.AddWithValue("#Date", dateValue)
If your clients are in different time zones, you should (as #Martin Smith mentioned) consider using UTC time.
In .NET
Dim dateValue = DateTime.UtcNow
and also in your query, using GETUTCDATE():
Dim queryText As String = "SELECT CASE WHEN GETUTCDATE() = #Date THEN 'True' ELSE 'False' END"

Related

Convert string to datetime in cosmos db

In my cosmos db a date field is stored as string like this
{
"ValidationWeekStartDay": "27-Apr-2020"
}
I have to write a query to extract all documents whose ValidationWeekStartDay is greater than current date. How can I achieve this in cosmos db query?
Select * from c wher c.ValidationWeekStartDay > GetCurrentDateTime ()
this does not give me correct result.
This is the problem with date format, the documents you are storing is in format 'dd-MMM-yyyy' while GetCurrentDateTime() function gets the date in format 'yyyy-mm-dd....'. So when you run the above query, comparison like below happens:
'27-Apr-2020' > '2020-08-17'
It compares the characters one by one and first 2 characters of first value becomes greater than second value. For testing purpose, anything above date 20 will be returned by your query irrespective of any month.
There are 2 ways to resolve this.
Store the date in same format as GetCurrentDateTime() function.
Create a udf like below. You can create your own udf, this is just a sample one based on date format.(pardon the formatting, you can copy and run it as it is)
function formatdatetime(datetime){ datetime = datetime.substring(7,11) + '-' + datetime.substring(3,6) + '-' + datetime.substring(0,2); datetime = datetime.replace('Jan','01'); datetime = datetime.replace('Feb','02'); datetime = datetime.replace('Mar','03'); datetime = datetime.replace('Apr','04'); datetime = datetime.replace('May','05'); datetime = datetime.replace('Jun','06'); datetime = datetime.replace('Jul','07'); datetime = datetime.replace('Aug','08'); datetime = datetime.replace('Sep','09'); datetime = datetime.replace('Oct','10'); datetime = datetime.replace('Nov','11'); datetime = datetime.replace('Dec','12'); return datetime; }
And then use the below query:
select c.stdDates as stdDates from c Where udf.formatdatetime(c.stdDates) > GetCurrentDateTime ()

How to format a date store in varchar format

how can i format a date stored in varchar format.
I have saved date in varchar(255) in format dd:mm:yyyy hh:mm:ss. I need to convert or get in the format hh:mm:ss. I do not want to alter the database structure
I tried,
SELECT [FinishingTime] format(varchar(255), [FinishingTime], 120)
In addition to this question:
I would try to alter the database structure. In the Sql database if i use the datetime2(0). Then i have a problem in getting through my groovy code. I have in long i try to convert into dateformat and set in the string and later store in
database.
def time1= time / 1000; here time is in long
def time2 = time1 + 3600 + timeLeft;
LocalDateTime dateTime = LocalDateTime.ofEpochSecond(Finish2, 0, ZoneOffset.UTC);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss", Locale.ENGLISH);
String formattedDate = dateTime.format(formatter);
machine.setFinishingTime(formattedDate);
Now i use the getter and setter in a class.
public String getFinishingTime()
{
return getPropertyContainer().getString(FINISHING_TIME, "")
}
public void setFinishingTime(String finishingTime)
{
getPropertyContainer().setString(FINISHING_TIME, finishingTime)
}
Now the question is if i use date time instead of string it does not write in my database or i am not able to set through setter.
You don't need a conversations just use substring() function :
select substring([FinishingTime], charindex(' ', [FinishingTime]) + 1, len([FinishingTime]))
from table t;
However, your idea is really bad to store date-time in custom format, it will lead you lots of trouble while data querying.
I assume it is MS SQL
select convert(varchar, FinishingTime, 108)
or
select convert(varchar, FinishingTime, 8)

How to calculate time difference between two times in vb

I need to calculate time difference between two time
The shift Start time is 04:30:Pm to 12:30AM
The Employee IN time is 08:30 AM then it shows the error message time expired
What I have tried:
dtShifTime = Convert.ToDateTime("16:30").ToString("HH:mm")
Dim dtEntryTime As DateTime = Convert.ToDateTime("08:30").ToString("HH:mm")
If lblStartTime.Text <> "" And (dtLateTime < dtEntryTime) Then
MBox("Time Expired")
End IF
By calling ToString you convert the DateTime object into a String. And then you save it into a DateTime variable.
I don't know what you're trying to do, but to get the difference between two times you just subtract them.
Dim dtStart As DateTime = new DateTime(year:= 1, month := 1, day:= 1, hour:= 8, minute:= 30, second := 0)
Dim dtEnd As DateTime = new DateTime(year:= 1, month := 1, day:= 1, hour:= 20, minute:= 0, second := 0)
Dim tsDiff As TimeSpan = dtEnd - dtStart
Console.WriteLine(tsDiff.ToString())
I recommend you read the documentation for what you're trying to use.
DateTime and TimeSpan.
Instead of the constructor you can parse with DateTime.Parse(), ParseExact or TryParse if you definitely need to use a string as an input, which you should avoid if possible.
Aside from that you should do some basic searching and researching. For example this comes up as the first hit: Get time difference between two timespan in vb.net when searching "time difference vb.net"

Convert custom numeric datevalue to real date in sql query

I have an application that comes with its own database and there is nothing I can change on that configuration. However we do pull data from the database to generate reports on.
For some reason (which I don't quite grasp), the application stores dates as the following number:
numdate = (int) '1' & <last two digits of year> & <zero-leading month> & <zero-leading day>
eg:
08/10/2008 -> 1081008
01/01/2014 -> 1140101
27/02/2014 -> 1140227
For now I just pull in the number and convert it on the go to a real date.
Is it possible to do this conversion via the sql query somehow?
If it's SQL Server, the following should work:
DECLARE #dateInt INT = 1981008
SELECT CONVERT(DATETIME, SUBSTRING(CONVERT(VARCHAR, #dateInt), 2, 6), 12)
To save you reading the comments, Gunther improved the performance by removing the substring operation in favour of subtraction:
SELECT CONVERT(DATETIME, CONVERT(VARCHAR,#dateInt-1000000), 12)
You could use this if you are using C#.
string dateString = "1981008";
DateTime dt;
DateTime.TryParseExact(dateString.Remove(0,1), "yyMMdd", null, System.Globalization.DateTimeStyles.None, out dt);
In SQL (assuming it is MS SQL), try this:
convert(datetime,'981008',112)

How to set a DateTime variable in SQL Server 2008?

SQL Server 2008 is not doing what I expected with DateTime. It doesn't let me set DateTime variables, no matter what date format I use.
When I execute:
DECLARE #Test AS DATETIME
SET #Test = 2011-02-15
PRINT #Test
I get an output of:
Jun 18 1905 12:00AM
I've checked all of the regional settings that I can find & it all appears okay. I've also tried setting the DateTime to various literal alternatives, such as '15/02/2011', '2011-02-15 00:00:00', etc.
You need to enclose the date time value in quotes:
DECLARE #Test AS DATETIME
SET #Test = '2011-02-15'
PRINT #Test
First of all - use single quotes around your date literals!
Second of all, I would strongly recommend always using the ISO-8601 date format - this works regardless of what your locale, regional or language settings are on your SQL Server.
The ISO-8601 format is either:
YYYYMMDD for dates only (e.g. 20110825 for the 25th of August, 2011)
YYYY-MM-DDTHH:MM:SS for dates and time (e.g. 2011-08-25T14:15:00 for 25th of AUgust, 14:15/2:15pm in the afternoon)
Try using Select instead of Print
DECLARE #Test AS DATETIME
SET #Test = '2011-02-15'
Select #Test
2011-01-15 = 2011-16 = 1995. This is then being implicitly converted from an integer to a date, giving you the 1995th day, starting from 1st Jan 1900.
You need to use SET #test = '2011-02-15'
Just to explain:
2011-02-15 is being interpreted literally as a mathematical operation, to which the answer is 1994.
This, then, is being interpreted as 1994 days since the origin of date (Jan 1st 1900).
1994 days = 5 years, 6 months, 18 days = June 18th 1905
So, if you don't want to to the calculation each time you want compare a date to a particular value use the standard: Compare the value of the toString() function of date object to the string like this :
set #TEST ='2011-02-05'
You want to make the format/style explicit and don't rely on interpretation based on local settings (which may vary among your clients infrastructure).
DECLARE #Test AS DATETIME
SET #Test = CONVERT(DATETIME, '2011-02-15 00:00:00', 120) -- yyyy-MM-dd hh:mm:ss
SELECT #Test
While there is a plethora of styles, you may want to remember few
126 (ISO 8601): yyyy-MM-ddThh:mm:ss(.mmm)
120: yyyy-MM-dd hh:mm:ss
112: yyyyMMdd
Note that the T in the ISO 8601 is actually the letter T and not a variable.
You Should Try This Way :
DECLARE #TEST DATE
SET #TEST = '05/09/2013'
PRINT #TEST
1. I create new Date() and convert her in String .
2. This string I set in insert.
**Example:** insert into newDate(date_create) VALUES (?)";
...
PreparedStatement ps = con.prepareStatement(CREATE))
ps.setString(1, getData());
ps.executeUpdate();
...}
private String getData() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-dd hh:mm:ss");
return sdf.format(new java.util.Date());
}
**It is very important format** = "yyyy-M-dd hh:mm:ss"
The CONVERT function helps.Check this:
declare #erro_event_timestamp as Timestamp;
set #erro_event_timestamp = CONVERT(Timestamp, '2020-07-06 05:19:44.380', 121);
The magic number 121 I found here: https://www.w3schools.com/SQL/func_sqlserver_convert.asp