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"
Related
If the user selects the date in the DateTimePicker, it only picks up the date, which is what I need. However, if the user doesn't select any date and leaves the DateTimePicker as today's date, it shows date + time. The data is stored in an Access database. I want to store the date only in the Access store when the user leaves the DateTimePicker to today's date (without changing any date).
Me.DateTimePicker1.CustomFormat = "dd-MM-yyyy"
Me.DateTimePicker1.DataBindings.Add(New System.Windows.Forms.Binding("Value", Me.OrderdetailsBindingSource, "OrderDate", True))
Me.DateTimePicker1.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.OrderdetailsBindingSource, "OrderDate", True))
Me.DateTimePicker1.Font = New System.Drawing.Font("Tahoma", 10.2!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.DateTimePicker1.Format = System.Windows.Forms.DateTimePickerFormat.Custom
Me.DateTimePicker1.Location = New System.Drawing.Point(158, 39)
Me.DateTimePicker1.Name = "DateTimePicker1"
Me.DateTimePicker1.Size = New System.Drawing.Size(294, 28)
Me.DateTimePicker1.TabIndex = 2
Me.DateTimePicker1.Value = New Date(2019, 6, 18, 0, 0, 0, 0)
Access does not have a short date format such as SQL Server. See this link for lists of data types.
Access:
Date/Time, Use for dates and times, 8 bytes
SQL Server:
datetime, From January 1, 1753 to December 31, 9999 with an accuracy of 3.33 milliseconds, 8 bytes
date, Store a date only. From January 1, 0001 to December 31, 9999, 3 bytes
So Access only has one date/time type which must be able to store time, which has the same number of bytes as SQL Server datetime. The date without a timestamp you see is actually 12 AM. This is what you are doing when you set the date/time on your DateTimePicker Me.DateTimePicker1.Value = New Date(2019, 6, 18, 0, 0, 0, 0). This is incidentally your best solution, to set the DateTimePicker to today's date (just the date portion using the DateTime.Date property I menioned).
To solve your problem, do this in Form_Load:
Me.DateTimePicker1.Value = Now.Date ' this makes it today at 12 AM
If you want to better understand what is going on, check out the value of your DateTimePicker at any time with this, to see that there is always a time in it, even if it's 12 AM:
MessageBox.Show($"{DateTimePicker1.Value:yyyy-MM-dd HH:mm:ss}")
And run this query on your database to see that there is also always a time in an Access Date/Time field, and that Access automatically hides the time when it is 12 AM:
select
orderdate
, format(orderdate, 'General Date') as GeneralDate
, format(orderdate, 'Short Time') as ShortTime
, format(orderdate, 'Medium Time') as MediumTime
, format(orderdate, 'Long Time') as LongTime
, format(orderdate, 'Short Date') as ShortDate
, format(orderdate, 'Medium Date') as MediumDate
, format(orderdate, 'Long Date') as LongDate
from orderdetails
Sorry, if I am not able to answer you perfectly in vb.net
i will give you an Answer in vb (how i mean it is correct)
and in correct c#
i understood that you want the code to save values in the database, if the date of the DateTimePicker is set today.
c#
if(dateTimePicker1.Value.Date == DateTime.Today)
{
//insert your code here
}
vb.net
if dateTimePicker1.Value.Date == DateTime.Today
//Code here
end if
this if asks, if the picket Date of the DateTime is the same Date as today
if you just want to save the whole value of the date in the DataBase if the picked date is today so like: "25.06.2019 17:25" then you will have a problem.
If you save it as String you could format it:
dateTimePicker1.Value.ToString("HH:mm dd.MM.yyyy")
or
dateTimePicker1.Value.ToString("HH:mm")
so put the second in the "else" braket.
if you only need Date or time, you can format it like the above.
(sorry i am not sure if i understood your question right, so if it doesn't help you, just comment. I will answer)
I am having two date time picker start time and end time.I have to calculate difference between time from this end time and start time.And also how to check am or pm for calculating time difference.
I have tried this by using timespan. It gives me right answer,but when I select time suppose as 12:58:02 in end time and 10:57:05 in start time, it gives me wrong answer like -599. I want to know how to convert this negative difference to positive.
I have tried with the following code:
Dim startTime As Date
Dim endTime As Date
startTime = Convert.ToDateTime(dtpOpStTime.Value)
endTime = Convert.ToDateTime(dtpOpETime.Value)
Dim diff As System.TimeSpan
diff = endTime - startTime
actualTime = Convert.ToString(Int32.Parse(diff.Hours.ToString()) * 60 + Int32.Parse(diff.Minutes.ToString()))
ucTime.TxtCode.Text = actualTime
my another issue is as follows:
I am having 4 date time picker,2 for showing start date and end date and 2 for start time and end time.so when i changed date timespan getting is wrong .so how to resolve this.
I have tey with the following code:
Dim span As TimeSpan = dtpOpEDate.Value - dtpOpStdate.Value
Dim span1 As TimeSpan = dtpOpETime.Value - dtpOpStTime.Value
Dim duration As TimeSpan = span.Duration()
Dim duration1 As TimeSpan = span1.Duration()
Dim durDay As Int32 = duration.Days
Dim durHr As Int32 = duration1.Hours
Dim durMin As Int32 = duration1.Minutes
Dim totalDur = durDay * 24 * 60 + durHr * 60 + durMin
actualTime = totalDur.ToString()
ucTime.TxtCode.Text = actualTime
Problem is through this I am getting wrong time difference ,when i change suppose start time 10:51:02 PM and end time to 3:51:04 AM and start date to 25-Mar-2014 and End date to 26-Mar-2014 then difference should be 5 hours though the day change but i am getting wrong difference
A difference between two DateTimes returns a TimeSpan object. You can either use the Subtract method of DateTime or even use -. You have to use the subtract the earlier date from the later date:
Dim span As TimeSpan = dtpEnd.Value - dtpStart.Value
You can use the Duration method to get an absolute timespan, then the order doesn't matter:
Dim duration As TimeSpan = (dtpStart.Value - dtpEnd.Value).Duration()
If you for example want the number of minutes between, use the TotalMinutes property:
Dim minutes As Int32 = CInt(duration.TotalMinutes)
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"
I want to get the date value for
Nov 1, 2010 00:00:00 GMT
expressed in my local time.
What is the best way? Currently, I am doing this:
Dim NovGmt As Date = New Date(2010, 11, 1, 0, 0, 0)
Dim Nov1AsLocal As Date = GetGmtExpressedAsLocal(NovGmt)
Private Function GetGmtExpressedAsLocal(ByVal gmtDate As Date) As Date
Return gmtDate.AddMinutes(GetMinuteOffsetFromGmt)
End Function
Private Function GetMinuteOffsetFromGmt() As Double
Dim NowTime As Date = Now
Dim NowAsGmt As Date = NowTime.ToUniversalTime
Return CType(DateDiff(DateInterval.Minute, NowAsGmt, NowTime), Double)
End Function
Also, can somebody tell me difference between the Date and DateTime datatypes? Is DateTime newer than Date or is it just a synonym for Date? If the latter, why have both?
You can use the ToLocalTime to convert a DateTime from UTC to the local timezone.
Date is an alias for DateTime. I presume this was done for backward compatibility reasons.
In vb.net I have two data values as shown below:
Dim startp as datetime
Dim endp as datetime
I have a function called ProcessData(soemdate) which processes dataporting.
In VB.net is there a way I can do something like
For each day between startp and endp
ProcessData(soemdate)
Next
Thanks
Here is another way to do this.
Dim startP As DateTime = New DateTime(2009, 1, 1)
Dim endP As DateTime = New DateTime(2009, 2, 1)
Dim CurrD As DateTime = startP
While (CurrD <= endP)
ProcessData(CurrD)
Console.WriteLine(CurrD.ToShortDateString)
CurrD = CurrD.AddDays(1)
End While
For Each Day As DateTime in Enumerable.Range(0, (endp - startp).Days) _
.Select(Function(i) startp.AddDays(i))
ProcessData(Day)
Next Day
Adding to Joel Coehoorn's answer which I personally think should be the accepted answer as I always try to avoid While loops no matter how safe they may appear. For...Each is a much safer approach although the enumerable isn't very pretty in-line. You can however move it to a function to keep things more readable, plus you can re-use as needed.
For Each Day As DateTime In DateRange(StartDate, EndDate)
ProcessData(Day)
Console.WriteLine(Day.ToShortDateString)
Next
Public Shared Function DateRange(Start As DateTime, Thru As DateTime) As IEnumerable(Of Date)
Return Enumerable.Range(0, (Thru.Date - Start.Date).Days + 1).Select(Function(i) Start.AddDays(i))
End Function
I also added 1 to Enumerable range since as Joel had it, it wouldn't return the end date and in my situation I needed it to return all dates in the range including the start and end days.
Enumerable.Range is a sort of loop in itself that adds i days to the startdate advancing i with each call from in this case 0 to the difference between start and end days + 1. So the first time it's called you get the result of Start.AddDays(0), next you'll get Start.AddDays(1) and so on until the range is complete.
You can easily loop through each day if you convert your dates to OLE Automation Date OADate where the left portion represents the day and the right portion represents the time.
For example #06/19/2018#.ToOADate converts to 43270.0
For loopDate As Double = #06/19/2018#.ToOADate To #07/01/2018#.ToOADate
Dim thisDate As Date = DateTime.FromOADate(loopDate)
' Do your stuff here e.g. ProcessData(thisDate)
Next
Yes, you can use an accumulator date:
Dim Accumulator as DateTime
Accumulator = startp
While (Accumulator <= endp)
Accumulator = Accumulator.AddDays(1)
End While
Not tested, and I'm a C# programmer, so be easy if my syntax is wrong.
For those that come looking later, I had to add a +1 to the Range endpoint to get this to work for when the start and end were the same. Here is the code I used.
For Each Day As DateTime in Enumerable.Range(0, (endp - startp).Days + 1) .Select(Function(i) startp.AddDays(i))
'Do work here
Next Day
Set a calendar table with all dates and query values from there.
SQL:
Select Date as MyDate from tblCalendar Where Date >= StartDt And Date <= EndDate
.NET:
While Reader.read
process(MyDate)
End While