How to make an if else syntax with datetime (time only) - vb.net

Need your help guys, how can I make an if else with time? I just need to make the time and minutes to round off.
for example: I put 9:23 in a textbox
if textbox1.text >= 9:00 And textbox1.text <= 9:30
textbox1.text = 9:00
end if
It will round off to 9:00, I just need the syntax on how the time will round off. Thank you 3000

Try this.
Dim datetime As DateTime = Convert.ToDateTime(textbox1.text)
Dim timeininteger As Integer = CInt(datetime.ToString("mm"))
If timeininteger >= 0 And timeininteger <= 30 Then
textbox1.text = datetime.ToString("HH:" & "00")
End If

Ok, so you see, 9:30 isn't time. Not to a computer, at least. It's a string. So you'll need to format it until it's time.
I notice that you didn't specify AM or PM, so I'll assume that you're using a 24h time format. Here we go:
'Convert the text from the TextBox1 to DateTime
Dim time As DateTime = Convert.ToDateTime(textbox1.text)
'Here's the result:
MessageBox.Show(time.ToShortTimeString)
'You can get only one component of a DateTime:
MessageBox.Show(time.Hour.ToString)
'So, yeah, you can totally do math with time now! Look:
If time.Minute > 30 Then
MessageBox.Show((time.Hour + 1).ToString)
End If
Now that you master time, use your newfound powers for the greater good!

Related

Conver Time from UTC to PST/PDT/CET and CEST with VBA

I have a cloumn (Col. A) of the time and date for one years based on UTC time as the follow format (in fact i have 30 mins Intervals) from first of the year until end of the year:
01.01.2019 00:00
01.01.2019 00:30
.
.
.
31.12.2019 11:00
31.12.2019 11:30
Now I want to convert the time from UTC to CET when it's winter Time and CEST when is Summer time (I want to have the information in Col.B). I could do it with Excel Formula Easily but as my file is big enough I have to use VBA code.
Do have any suggetion How can I do it? My problem is on switching summer time to winter time via versa.
Regarding the time zone conversion itself, Wikipedia says (https://en.wikipedia.org/wiki/Central_European_Summer_Time#Period_of_observation):
Since 1996, European Summer Time has been observed between 01:00 UTC
(02:00 CET and 03:00 CEST) on the last Sunday of March, and 01:00 UTC
on the last Sunday of October
If I'm reading that correctly, a datetime can only be CET if it:
is before (<) the last Sunday of March at 01:00 UTC (i.e. when CEST begins)
or is on or after (>=) the last Sunday of October at 01:00 UTC (i.e. when CET begins)
It's not clear to me what your source data is like. (It looks like two datetimes delimited by a space, meaning each row actually contains a string. If this is true, you'll likely need to split the string into two strings along the delimiting space, then convert the two strings into two datetimes. This can probably be done with LEFT, RIGHT, DATEVALUE functions in VBA.)
To give you an example, I've filled range A1:A17520 of my worksheet "Sheet1" with datetimes at half-hour intervals (similar to what you've shown):
and I then use the code below to convert my values in column A (and put the converted values in column B of the same sheet):
Option Explicit
Private Sub ConvertUtcDatesInColumnAToCETorCEST()
Dim sourceSheet As Worksheet
Set sourceSheet = ThisWorkbook.Worksheets("Sheet1")
Dim lastSourceRow As Long
lastSourceRow = sourceSheet.Cells(sourceSheet.Rows.Count, "A").End(xlUp).Row
Dim datesFromSheet() As Variant
datesFromSheet = sourceSheet.Range("A1", sourceSheet.Cells(lastSourceRow, "A"))
Dim outputArray() As Date
ReDim outputArray(1 To UBound(datesFromSheet, 1), 1 To 1)
Dim rowIndex As Long
For rowIndex = LBound(datesFromSheet, 1) To UBound(datesFromSheet, 1)
outputArray(rowIndex, 1) = ConvertUtcDateTimeToCETorCEST(datesFromSheet(rowIndex, 1))
Next rowIndex
sourceSheet.Range("B1").Resize(UBound(outputArray, 1), UBound(outputArray, 2)).Value = outputArray
End Sub
Private Function LastSundayOfSomeMonthAndYear(ByVal someMonth As Long, ByVal someYear As Long) As Date
Dim lastDateInMonth As Date
lastDateInMonth = Application.EoMonth(DateSerial(someYear, someMonth, 1), 0)
Dim lastSundayInMonth As Date
LastSundayOfSomeMonthAndYear = lastDateInMonth - Weekday(lastDateInMonth, vbSunday) + 1
End Function
Private Function ConvertUtcDateTimeToCETorCEST(ByVal someUtcDateTime As Date) As Date
Dim startOfCESTinUTC As Date
startOfCESTinUTC = LastSundayOfSomeMonthAndYear(someMonth:=3, someYear:=Year(someUtcDateTime)) + TimeSerial(1, 0, 0)
Dim endOfCESTinUTC As Date
endOfCESTinUTC = LastSundayOfSomeMonthAndYear(someMonth:=10, someYear:=Year(someUtcDateTime)) + TimeSerial(1, 0, 0)
Dim isCET As Boolean
isCET = someUtcDateTime < startOfCESTinUTC Or someUtcDateTime >= endOfCESTinUTC ' Not sure if end is inclusive or exclusive
Dim hoursToAdd As Date
If isCET Then hoursToAdd = TimeSerial(2, 0, 0) Else hoursToAdd = TimeSerial(3, 0, 0)
ConvertUtcDateTimeToCETorCEST = someUtcDateTime + hoursToAdd
End Function
which gives me something like this:
Something to note is that this approach is quite inefficient for a few reasons:
The variables startOfCESTinUTC and endOfCESTinUTC are re-calculated every single time the function ConvertUtcDateTimeToCETorCEST is invoked (~17.5k times in my case). Since all of our datetimes are during the same year, the values of startOfCESTinUTC and endOfCESTinUTC will not change (so really the variables startOfCESTinUTC and endOfCESTinUTC should be determined just once, before the For loop).
If you know in advance and for sure that your data is sorted and is at half-hour intervals, you can do some maths and work out on which row CEST must begin on and end on. With that knowledge, you no longer need to check if the datetime is CET or CEST inside the For loop. If you use three For loops (loop 1: first row to row CET ends on, loop 2: row CEST starts on to row CEST ends on, loop 3: row CET starts on to last row), you can convert all values to CET (loop 1, loop 3) and CEST (loop 2) without actually checking what the value is. This makes the code more specialised (and faster), but also less reusable.
Modern computers are (relatively) fast. The code above converted 17.5k datetimes for me in <2 seconds on my machine. You may also want to check if the code handles the boundaries of CET and CEST correctly.

How to calculate positive difference between time from two DateTimes

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)

Comparing Times in vb.net

I have four different DateTime boxes. Two boxes just displays the Date and the other two just Displays the time
If the current time is between midnight and six am I want the Date in the date box to be the day before.
I have it all, I'm just missing the part that compares the two.
Dim currentTime As DateTime = Now
'default date
If deMaxDate.Value = Nothing Then
deMaxDate.Value = Now
End If
If deMinDate.Value = Nothing Then
If currentTime.Hour < TimeOfDay.Hour Then
'THIS IF STATMENT IS WRONG - HOW CAN I CHECK IF ITS BETWEEN 12AM AND 6 HERE
deMinDate.Value = (Now - TimeSpan.FromDays(1))
Else
deMinDate.Value = Now
End If
End If
'default time
If teMaxTime.Value = Nothing Then
teMaxTime.Value = Now
End If
If teMinTime.Value = Nothing Then
teMinTime.Value = (Now - TimeSpan.FromHours(6))
End If
My comment by the third if statment is where I'm stuck at.
DateTime is a double datatype? Something like
if currentTime.Hour < TimeOfDay.Hour.Equals(6)
?
Your rule, if I understand this, is that you want to look at the current time. If the current time is between 12AM(0000) and 6AM(0600), then you want to use yesterday as the active date.
Dim current as DateTime = now()
Dim activeDate as DateTime = current
if current.Hour < 6 then
activeDate = current.AddDays(-1)
end if
Although, if you're not really interested in the hours part of the date except for this business rule, you could always just do date.AddHours(-6).
I do this in a similar situation where I want to check the current time is prior to 4 AM.
If (DateTime.Now.Hour < 4) Then
'do something
End If
Just use
If currentTime.Hour <= 6 Then
deMinDate.Value = Now.AddDays(-1)
Else
deMinDate.Value = Now
End If
or indeed...
If currentTime.Hour <= 6 Then
deMinDate.Value = Now.Date.AddDays(-1)
Else
deMinDate.Value = Now.Date
End If
if you don't want the time bit because .Now contains a time element as well as a date element.
Have a look at http://msdn.microsoft.com/en-us/library/5ata5aya.aspx. It might apply to your case
currentTime.Hour < TimeOfDay.Hour.Equals(6)
ended up being the answer

VB DataView.RowFilter and Cast Before Compare

In the following DataView.Rowfilter filter, Request_Date is a smalldatetime:
dv.RowFilter = "Request_Date >= '01/01/2012' and Request_Date <= '12/31/2012'"
The problem with this is that smalldatetime is MM/dd/yyyy hh:mm:ss, but it is compared to a string with the format 'MM/dd/yyyy'. This means that the filter will automatically convert the strings to smalldatetime, so the comparison only shows date/times between 1/1/2012 at 12AM and 12/31/2012 at 12AM. Any rows with dates later in the day on 12/31/2012 will not get picked up by this filter. I know that I can add a day to the end date or concatenate, say, 12:59:59 to the end of the date to pick up the other times in the day, but I was hoping for somthing more elegant, along the lines of the sql equivalent ...CONVERT(smalldatetime, Request_Date, 101) <= '12/31/2012'. Is there any way that I can get a different date format for a DataView field or am I stuck massaging the end date prior to comparison?
FYI, current best option is this:
dv.RowFilter = "Request_Date >= #" & dtpStartDate.DateText & "# and Request_Date <= #" & DateAdd(DateInterval.Day, 1, dtpEndDate.DateValue) & "#"
Thanks for your help!
If you're using at least .NET 3.5, you can use Linq-To-DataSet which is more readable:
DataTable filtered = dv.Table
.AsEnumerable()
.Where(r => r.Field<DateTime>("Request_Date") >= dtpStartDate.Value
&& r.Field<DateTime>("Request_Date") < dtpEndDate.Value.AddDays(1))
.CopyToDataTable();
Add using.System.Linq; and a reference to System.Data.DataSetExtensions.dll.
Edit: I've only just seen that VB.NET is tagged:
Dim filtered = From row In dv.Table
Where row.Field(Of DateTime)("Request_Date") >= dtpStartDate.Value AndAlso _
row.Field(Of DateTime)("Request_Date") < dtpEndDate.Value.AddDays(1)
Dim tblFiltered = filtered.CopyToDataTable()
Instead of using "<= 12/31/2012", just use "< 1/1/2013" - that is the most elegant and gets exactly what you want.

Dates in For Loop in vb.net

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