How to Convert Date, Time and UTC Offset to Local DateTime - vb.net

I need to get a local timezone datetime from the following XML elements:
<TransactionDate>20191202</TransactionDate>
<TransactionTime>234026</TransactionTime>
<TransactionTimezone>UTC-06:00:00</TransactionTimezone>
My local UTC offset is -05:00:00. After getting TransactionDate and TransactionTime into td and tt Date variables, I can build a Datetime like this:
Dim ldDate As New Date(td.Year, td.Month, td.Day, tt.Hour, tt.Minute, tt.Second)
I could parse out the '-06' from TransactionTimeZone and determine that I need to add 1 hour to ldDate, but there must be a more elegant way. Any ideas?

I wrote a small procedure that returns a DateTime in the local TimeZone from a DateTime in an originating TimeZone:
Public Function P_ConvertToLocalDatetime(ByVal aOriginDateTime As Date,
ByVal aOriginTimeZone As String,
ByRef aLocalDateTime As Date) As Boolean
Try
Dim liHour As Integer = CInt(Strings.Mid(aOriginTimeZone, 4, 3))
Dim liMinute As Integer = CInt(Strings.Mid(aOriginTimeZone, 8, 2))
Dim liSecond As Integer = CInt(Strings.Right(aOriginTimeZone, 2))
With aOriginDateTime
Dim offset As New DateTimeOffset(.Year, .Month, .Day, .Hour, .Minute, .Second, New TimeSpan(liHour, liMinute, liSecond))
aLocalDateTime = offset.LocalDateTime
End With
Return True
Catch ex As Exception
Return False
End Try
End Function
I'm calling it with this:
Dim lLocalDateTime as Date
If Not P_ConvertToLocalDatetime(aTransactionDatetime,
aTransactionTimezone,
aLocalDateTime) Then
Throw New Exception("Unable to convert TransactionDatetime to local time")
End If
... where aTransactionTimezone is of type String with a value like "UTC-6:00:00".

If you have transactions from all the world this might help you to use as a base and working on to improve.
Private Function FromWorldTimeToMyLocalTime(noSpacesDateTimeTransaction As String, transactionZoneString As String) As Date
Dim transactionDtTime As Date = Date.ParseExact(noSpacesDateTimeTransaction, "yyyyMMddHHmmss", Globalization.CultureInfo.InvariantCulture)
Return DateAndTime.DateAdd(DateInterval.Hour, TimeZoneInfo.FindSystemTimeZoneById(transactionZoneString).BaseUtcOffset.TotalHours, transactionDtTime)
End Function
Usage (Here the example shows a transaction is done by Hawai):
‘Here is your complete string as you have in your xml tags (date + time) it’s presumed the transaction is come by Hawai
Dim myDateTimeFromTransactionTime As String = FromWorldTimeToMyLocalTime("20191202234026", "Hawaiian Standard Time").ToString
Console.WriteLine("MyTime from transaction is " & myDateTimeFromTransactionTime)
To get all timezone infos you can use this to have an idea.
Dim timeZones As ReadOnlyCollection(Of TimeZoneInfo) = TimeZoneInfo.GetSystemTimeZones()
For Each timeZoneInfo As TimeZoneInfo In timeZones
Console.WriteLine(CStr(timeZoneInfo.Id) & " " & CStr(timeZoneInfo.BaseUtcOffset.TotalHours))
Next

Related

Convert Time stored as integer to datetime

I have time stored as integer in a database
Example: 11325 means 01:13:25
i am trying to make a function to do this work
i used the following code:
Public Function GetTimeFromInt(ByVal intTime As Integer) As DateTime
Dim strTemp As String = intTime.ToString("D6")
strTemp = strTemp.Insert(4, ":").Insert(2, ":")
Dim dtResult As DateTime = Date.ParseExact(strTemp, "HH:mm:ss", New System.Globalization.CultureInfo("en-GB"), Globalization.DateTimeStyles.None)
Return dtResult
End Function
And it is working fine. But i want to now if there is a way to do this using string formatting maybe like int.ToString("nn:nn:nn")
Yes:
123456.ToString("00:00:00")
This will give 12:34:56.

AM/PM designatior special case for noon and midnight

VB2012: I am reading data from a legacy system. One of the fields is a time and I am reading that into a DateTime variable. I use the "hhmmt" format to parse out the date with DateTime.ParseExact. The only issue I have is that the legacy system displays A for AM and P for PM with a special case for N for noon. Well .NET doesn't like the N designator so I detect it and change it to P. Works great.
003 0300 AAABBB 845A 1200N
005 1400 CCCDDD 1055A 240P
007 7000 EEEFFF 306P 531P
Now I do some processing and print out the data to a file. I want to print out the times in the format that they are printed in the legacy system. My first thought was to use a custom DateTimeFormatInfo
Dim info As New DateTimeFormatInfo
info.PMDesignator = "N"
and feed that to my string formatter as the IFormatProvider
trip.ArriveTime.ToString("hmmt", info)
But I realize that setting the DateTimeFormatInfo is static and will not be of any use when the time is 12:00P or noon. Is there any way to create a format that will account for this unique scenario and use the N suffix when it is noon but keep the standard A for AM and P for PM for other times?
Update with possible solution:
Imports System.Text.RegularExpressions
Imports System.Globalization
Module mdlExtensions
Private rgxTimePeriod As New Regex("t+")
<System.Runtime.CompilerServices.Extension()> _
Public Function LegacyFormat(dt As DateTime, fmt As String, Optional provider As IFormatProvider = Nothing) As String
Dim formatted As String
If dt.TimeOfDay = New TimeSpan(12, 0, 0) Then
fmt = rgxTimePeriod.Replace(fmt, "N")
End If
If provider Is Nothing Then
formatted = dt.ToString(fmt)
Else
formatted = dt.ToString(fmt, provider)
End If
Return formatted
End Function
<System.Runtime.CompilerServices.Extension()> _
Public Function ToLegacy(dt As DateTime, fmt As String, Optional provider As IFormatProvider = Nothing) As String
'setup the master DateTimeFormatInfo
Dim ci As CultureInfo = CType(provider, CultureInfo)
Dim mstrDtfi As DateTimeFormatInfo
If provider Is Nothing Then
'designate a new DateTimeFormatInfo class if Nothing was passed in
mstrDtfi = New DateTimeFormatInfo
Else
'get a reference to the DateTimeFormatInfo class of the FormatProvider that was passed in
mstrDtfi = ci.DateTimeFormat
End If
'check to see if the time is noon and set a new PMDesignator if it is
If dt.TimeOfDay = New TimeSpan(12, 0, 0) Then
mstrDtfi.PMDesignator = "NN"
End If
'check to see if the time is midnight and set a new AMDesignator if it is
If dt.TimeOfDay = New TimeSpan(0, 0, 0) Then
mstrDtfi.AMDesignator = "MM"
End If
'now format the date string with the proper provider
Dim formattedDate As String
If provider Is Nothing Then
formattedDate = dt.ToString(fmt, mstrDtfi)
Else
formattedDate = dt.ToString(fmt, ci)
End If
Return formattedDate
End Function
End Module
I was aiming for something of a generic solution where the format could change like ddmm hhmmt or hmtt and the overload would take care of the various formats except for the special case of the "t" specifier.
A simple Function can still handle this. Here is an example as an extension method.
Module Extensions
Private rgxTimePeriod As New Regex("t+")
<System.Runtime.CompilerServices.Extension()> _
Public Function LegacyFmt(dt As DateTime, fmt As String, Optional provider As IFormatProvider = Nothing) As String
Dim formatted As String
If dt.TimeOfDay = New TimeSpan(12, 0, 0) Then
fmt = rgxTimePeriod.Replace(fmt, "N")
End If
If provider Is Nothing Then
formatted = dt.ToString(fmt)
Else
formatted = dt.ToString(fmt, provider)
End If
Return formatted
End Function
End Module
?#12:00#.LegacyFmt("hmmt", Globalization.CultureInfo.InvariantCulture)
"1200N"
?now.LegacyFmt("ddmm")
"2551"
?#2:01#.LegacyFmt("hmmt")
?#12:00#.LegacyFmt("hmtt")
"120N"
"201A"
?#2:01#.LegacyFmt("hmtt")
"21AM"

IsDate is returning unexpected results

When I am doing in immediate window
? IsDate("09/01/14")
True
? IsDate("10/23/14")
False
I am not sure why IsDate("10/23/14") is returning false.
any suggestions?
This is my entire function. When I pass 09/01/14 then it doesn't return any error, but when I pass 10/23/14 then it returns error.
Public Shared Sub CheckForDate(ByVal ChkText As String, ByRef ErrorCount As Integer)
Try
ChkText = ChkText.Replace(" ", "").Trim()
Dim dt As DateTime = DateTime.ParseExact(ChkText, "MM/dd/yyyy", Globalization.CultureInfo.InvariantCulture)
If Not IsDate(dt) Then
ErrorCount += 1
End If
Catch
If Len(ChkText) > 0 Then
If Not IsDate(ChkText) Then
ErrorCount += 1
End If
End If
End Try
End Sub
I tried this
? DateTime.TryParse("09/01/14", dt)
True
? DateTime.TryParse("10/23/14", dt)
False
It might be possible that dates in isDate are being processed as dd/mm/yy instead of mm/dd/yy.
Try this code in your application, or be sure your system is processing dates as mm/dd/yy:
Imports System.Globalization
Dim ciNewFormat As New CultureInfo(CultureInfo.CurrentCulture.ToString())
ciNewFormat.DateTimeFormat.ShortDatePattern = "MM/dd/yy"
System.Threading.Thread.CurrentThread.CurrentCulture = ciNewFormat
Use TryParseExact(). This will force you include information indicating the expected format.
As somewhat indicated in comments on this question, the likely problem is that the machine where you are running assumes a DD/MM/YY format instead of your expected MM/DD/YY format.
You must specify a culture that corresponds to date format used:
Public Shared Function IsUSDate(input As String) As Boolean
Dim culture = CultureInfo.CreateSpecificCulture("en-US")
Dim d As DateTime
Return DateTime.TryParse(input, culture, DateTimeStyles.None, d)
End Function

Validate the date format in vb.net

I have the grid cell value to validate for a correct format as below
Date value should be in DD-MON-YYYY format and for this i am using below validation
Public Function ValidateDateForError(ByVal checkInputValue As String) As Boolean
Dim returnError As Boolean
Dim dateVal As DateTime
If Date.TryParseExact(checkInputValue, "DD-MON-YYYY",
System.Globalization.CultureInfo.CurrentCulture,
DateTimeStyles.None, dateVal) Then
returnError = True
Else
MessageBox.Show("not converted")
End If
Return returnError
End Function`
DateTime value should be in DD-MON-YYYY HH:MI:SS format and for this i am using below validation
Public Function ValidateDateTimeForError(ByVal checkInputValue As String) As Boolean
Dim returnError As Boolean
Dim dateVal As DateTime
If DateTime.TryParseExact(checkInputValue, "DD-MON-YYYY HH:MI:SS",
System.Globalization.CultureInfo.CurrentCulture,
DateTimeStyles.None, dateVal) Then
returnError = True
End If
Return returnError
End Function`
EDate (valid European date) value should be in DD/MM/YY format and for this i am using below validation
Public Function ValidateEDateForError(ByVal checkInputValue As String) As Boolean
Dim returnError As Boolean
Dim dateVal As Date
If Date.TryParseExact(checkInputValue, "DD/MM/YY",
System.Globalization.CultureInfo.CurrentCulture,
DateTimeStyles.None, dateVal) Then
returnError = True
End If
Return returnError
End Function`
JDate (valid Julian date) value should be in MM/DD/YY format and for this i am using below validation
Public Function ValidateJDateForError(ByVal checkInputValue As String) As Boolean
Dim returnError As Boolean
Dim dateVal As Date
If Date.TryParseExact(checkInputValue, "MM/DD/YY",
System.Globalization.CultureInfo.CurrentCulture,
DateTimeStyles.None, dateVal) Then
returnError = True
End If
Return returnError
End Function`
but none of above is working. could anyone tell me where i am making mistake?
Thanks in Advance.
Using ParseExact means that you will be telling it the precise format the string will be in. These are case sensitive to allow things like H vs h for 12/24 clock and MM vs mm to distinguish Month from Minutes. So, "DD-MON-YYYY" is invalid, "dd-MM-yyyy" may be what you are after.
But, this means the user would always have to enter 2 digits for the day and month as in "19-07-2014" or "04-07-2014" which they are often not inclined to do, and seems harsh to impose. TryParseExact will take an array of formats so you can be flexible:
Dim strFoo As String = "19-7-2014" ' d-MM-yyyy
Dim strBar As String = "19-07-2014" ' dd-MM-yyyy
Dim strJuly4 As String = "4-7-2014" ' d-M-yyyy
' several possible format styles
Dim formats() As String = {"d-MM-yyyy", "dd-MM-yyyy",
"dd-M-yyyy", "d-M-yyyy"}
Dim thisDt As DateTime
' this should work with all 3 strings above
If DateTime.TryParseExact(strFoo, formats,
Globalization.CultureInfo.InvariantCulture,
DateTimeStyles.None, thisDt) Then
Console.WriteLine("Success! {0}", thisDt.ToString)
End If
Most of the time there it is silly to force them to enter "04" for a month or day and d/M/yyyy will work with strings with the leading "0" (but not the reverse!). Its is added here mainly to show how to pass an array of format patterns.
DO consult MSDN for the proper Standard Date and Time Format Strings
As for Julian Dates, one form of them is to use the form yyDDD to denote the 2 digit year and day of year for the last 3 digits. I dont know if the convention for this changed after 1/1/2000 when all Julian for this Century would sort below those for the 1990s. Still, here is how it is done:
Dim jdt As DateTime = #2/11/2010#
Dim jdate As String = xdt.Year.ToString & xdt.DayOfYear.ToString("000")
' ===> '2010042 or 42nd day of 2010
jdate = (xdt.Year - 2000).ToString("00") & xdt.DayOfYear.ToString("000")
' ===> '10042 or 42nd day of 2010

How can I convert two strings to DateTimes and compare them in VB.NET?

String comes back from the database with a format: '00/00/0000' I need to then compare it to a date that the user has entered in the same format. How do I make the conversion and compare the two dates?
Use the static ParseExact method on the DateTime structure to convert the string. You will also pass the format you want, either dd/MM/yyyy or MM/dd/yyyy depending on what format you want (the example of 00/00/0000 doesn't give any indication of what format applies for you).
You can use
Dim dateA = DateTime.ParseExact(firstDateString, #"dd\/MM\/yyyy", Null)
Dim dateB = DateTime.ParseExact(secondDateString, #"dd\/MM\/yyyy", Null)
Dim areEqual = (dateA = dateB);
Assuming that your date format is day/month/year.
If it's month/day/year just swap dd and MM
Try something like this:
String.Compare("00/00/0000", dateTime.ToString("MM/dd/yyyy"))
But perhaps a better approach would be to do this:
DateTime.Equals(yourDateTime, DateTime.Parse(databaseDateTime));
Try the following
Dim date1 = CDate(firstDateString)
Dim date2 = CDate(secondDateString)
Dim comp = date1 = date2
When you say compare, are you trying to analysis if the dates are the same (to the day) or within a period of a few days ? If to compare if the dates are the same then you can just compare the string or use the date.equals (as mentioned in posts before this one) , if you are trying to determine with a range you will have to use date compare
Dim lDate1 As String = "29/03/2009"
Dim lDate2 As String = "30/03/2009"
Dim lPeriod As Int16 = 7
If lDate1 = lDate2 Then
'** Dates the same
End If
If Date.Equals(Date.ParseExact(lDate1, "dd/MM/yyyy", Nothing), Date.ParseExact(lDate2, "dd/MM/yyyy", Nothing)) Then
'** The same
End If
If Date.Compare(Date.ParseExact(lDate1, "dd/MM/yyyy", Nothing), Date.ParseExact(lDate2, "dd/MM/yyyy", Nothing)) > (lPeriod * -1) And Date.Compare(Date.ParseExact(lDate1, "dd/MM/yyyy", Nothing), Date.ParseExact(lDate2, "dd/MM/yyyy", Nothing)) < lPeriod Then
'** Within the period
End If