VB.Net inverse of a function to convert SAP Datetime to DateTime - vb.net

I've this simple function in VB.net
Private Function SBODateTime2DateTime2(SboTicks As Long) As DateTime
Dim str As String = Convert.ToString(SboTicks, 2)
str = str.Substring(0, str.Length - 8)
If str.Length = &H38 Then
str = str.Substring(1, &H37)
End If
Dim num As Long = Convert.ToInt64(str, 2)
Dim time As New DateTime(&H7B2, 1, 1, 0, 0, 0, DateTimeKind.Utc)
Return time.AddMilliseconds(CDbl(num) / 1000.0)
End Function
That takes a SAP tick number like 444447614733000184 and it returns the Datetime, in this example is 06/01/2025 00:31:35
The problem is that I don't know how to do the inverse of this procedure in VB.net mostly because there isn't a lot of documentation about SAP DateTime around.
Does anybody knows if it's possible to do the Datetime to SAP Datetime conversion?

Related

How to Convert Date, Time and UTC Offset to Local DateTime

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

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.

Convert Arabic string to an array of bytes

I have a function which converts string to an array of bytes. If the string is written in English, the function works fine. But if the input string is Arabic, the function doesn't return, and I get this error:
Value was either too large or too small for an unsigned byte
Friend Function StringtoByteArray(ByRef value As String) As Byte()
Dim temp() As Byte
ReDim temp(Len(value) - 1)
Dim i As Integer
For i = 0 To Len(value) - 1 Step 1
temp(i) = Convert.ToByte(Convert.ToChar(Mid(value, i + 1, 1)))
Next
StringtoByteArray = temp
End Function
What should I change to convert Arabic characters to byte?
I am using VB.NET.
You don't need to write your function for that, this should work:
Dim b As Byte() = System.Text.Encoding.Unicode.GetBytes(value)

Converting unix time to DateTime

I would like to convert a Unix time stamp to a VB.NET DateTime.
I have tried
Public Function UnixToDateTime(ByVal strUnixTime As String) As DateTime
Dim nTimestamp As Double = strUnixTime
Dim nDateTime As System.DateTime = New System.DateTime(1970, 1, 1, 0, 0, 0, 0)
nDateTime.AddSeconds(nTimestamp)
Return nDateTime
End Function
But when I feed it
strUnixTime = "1401093810"
I get the return value
nDateTime = #1/1/1970#
What am I doing wrong?
Thank you
This line of code
nDateTime.AddSeconds(nTimestamp)
does not modify nDateTime. It's like writing a + 3 on a line by it's own -- a won't be modified.
It does, however, return a new DateTime object that contains the incremented value. So, what you actually wanted to write is:
nDateTime = nDateTime.AddSeconds(nTimestamp)
PS: It appears that your code does not use Option Strict On. It is strongly recommended that you activate Option Strict and use explicit instead of implicit conversions.

Converting DateTime to number of seconds in VB .NET

For converting number of seconds to DateTime, in VB .NET, I use the following code:
Dim startDate As New DateTime(1970, 1, 1)
Dim targetDate As DateTime
Dim noOfSeconds As Integer = DataInSeconds
targetDate = startDate.AddSeconds(noOfSeconds)
where DataInSeconds is an Integer containing the number of seconds (starting from 1/1/1970)
This works good. But I don't know how make the inverse conversion. (from DateTime to number of seconds). Anyone can help me?
When you subtract DateTime instances from each other, you get a TimeSpan - you can use this to get the number of seconds:
Dim startDate As New DateTime(1970, 1, 1)
Dim noOfSeconds As Integer
noOfSeconds = (currentDate - startDate).TotalSeconds
1/1/1970 is the Unix epoch. Beware that it is a UTC date, you cannot ignore that in conversions. Thus:
Module DateConversion
Public ReadOnly Property Epoch() As DateTime
Get
Return New DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
End Get
End Property
Public Function FromUnix(ByVal seconds As Integer, local As Boolean) As DateTime
Dim dt = Epoch.AddSeconds(seconds)
If local Then dt = dt.ToLocalTime
Return dt
End Function
Public Function ToUnix(ByVal dt As DateTime) As Integer
If dt.Kind = DateTimeKind.Local Then dt = dt.ToUniversalTime
Return CInt((dt - Epoch).TotalSeconds)
End Function
End Module
Watch out for ToUnix(), the DateTimeKind may be unspecified, as it was in your snippet. Consider using DateTimeOffset instead to make it unambiguous. And be sure to do something reasonable in 2038 when all of this comes tumbling down.
Label1.Text = New DateTime(1970, 1, 1, 0, 0, 0,
DateTimeKind.Utc).AddSeconds(CLng(TextBox1.Text) / 1000)
Make a textbox and a button and a label, put this code into the button and depending if you're using microseconds (keep the /1000) or seconds (delete the /1000) will show you the date/time etc.
Public Function Date2Unix(ByVal vDate As Date) As Long
Return (vDate - #1970/01/01#).TotalSeconds
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
MsgBox(Date2Unix(Now()))
End Sub