VB.net Time Zone Issues - vb.net

I have a legacy application that uses the windows time zone information for calculating dates. For example, 35 = East Coast, 20 = central, 15=mountain. Here is the current function. It takes a date with a timezone and converts it to the timezone passed in. This works just fine on xp, but it crashes on Windows 7. I am guessing it has to do with the win32 portion of it or Windows 7 handles time zones differently.
I would prefer not to change the format of the time zone as that could cause some issues. The code is vb.net and I did not write it.
Public Shared Function ConvertTime(ByVal time As Date, ByVal timeZone As Integer) As Date
Dim UtcNow As Date = time.ToUniversalTime
Dim selectedTimeZone As TimeZones.Win32.Win32TimeZone = TimeZones.Win32.TimeZones.GetTimeZone(timeZone)
Return selectedTimeZone.ToLocalTime(UtcNow)
End Function
Anyone have this issue before?

Dim selectedTimeZone As TimeZones.Win32.Win32TimeZone =
TimeZones.Win32.TimeZones.GetTimeZone(timeZone)
In VB.NET you should be using the following class to replace Win32TimeZone
MSDN TimeZone Class (System)
Refer to the link i provided above to see the correct way of using the TimeZone Class in VB.NET.
It appears to not wont work due to TimZones.Win32.Win32TimeZone not being a valid class of .NET

That Timezones library is not a in the .NET BCL. Contact the author of your Timezones library for help.

Related

VB.Net Convert time from UTC to Local

I am working on a news website and I am saving all dates in the database in UTC. Then, depending on the browser/machine location, I want to display the date/time correspondingly (Convert from UTC to the Local time of the machine/browser).
First of all, I would like to know if I am doing this the way it should be done or not (UTC dates in the database).
Second, I wonder why isn't it that straightforward to do so in VB.NET? Below are the approaches I tried but none worked as needed:
Approach 1:
TimeZoneInfo.ConvertTimeFromUtC
This kept returning the server time and not the client/machine time.
Approach 2:
Dim TimeZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Middle East Standard Time")
Dim Dated As DateTime = TimeZoneInfo.ConvertTimeFromUtC(TempDate, TimeZone)
This worked but not as intended. This converted the UTC date/time in the database to the Middle East Time Zone but any user from any other place in the world will only see the date/time in Middle East Time Zone and not in the actual timezone of his place. Also, I am not sure if the conversion considers DayLightSaving or not.
Approach 3:
I tried to fix this using JavaScript. I created a cookie that saves the offset from UTC and tried handling the offset in VB.NET and do the conversion.
<script>
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getTimeOffset() {
var offset = new Date().getTimezoneOffset();
setCookie("_tz", offset);
}
</script>
JavaScripts returns the correct Offset and I am saving this offset in a cookie. Since JavaScript launches after Page_Load, I am calling the JavaScript function getTimeOffset() on Page_Init:
ScriptManager.RegisterStartupScript(Me, Page.GetType, "Script", "getTimeOffset();", True)
The cookie is being created before the page is rendered and the offset stored in the cookie is correct (This is what I actually want!). The problem here is on the first load. VB.NET reads the cookie value as empty string on the first load. On the second Page_Load onwards, VB.NET reads the cookie value and does the conversion correctly.
Approach 4
Tried to get the offset using all the examples in this fiddle but the offset is always 0 which is wrong.
Summary
I wonder if there is any function I missed in VB.NET to avoid all that hassle. Shouldn't it be an easy task to convert date/time from UTC to Local?
Please let me know if there is anything I am doing wrong or if there is a better alternative.
Your back-end code doesn't know anything about the time zone of the browser. It doesn't matter what language you are using, only the browser will know anything about the user's time zone.
When .Net code (regardless of VB or C#) refers to "local", it means the local time zone of where that code is running. In other words, in an ASP.Net web application, that's the local time zone of your server, not of the user. Generally speaking, the server's local time zone is usually irrelevant.
To achieve your goal, break the problem up into two parts.
Get the user's time zone in the browser, send it to the server.
Convert time on the server, using the time zone passed in.
For step 1, read this answer I posted to a different question. Note that the output will be an IANA time zone identifier. Do not pass a numeric offset, as it does not carry enough information to properly convert different points in time (consider daylight saving time, and other anomalies with time zones).
For step 2, you'll need to choose between one of these approaches:
You can use the IANA time zone identifier natively with TimeZoneInfo if you're running .NET Core on a non-Windows OS, or with the Noda Time library on any platform.
You can convert the IANA time zone identifier to a Windows time zone identifier using my TimeZoneConverter library, and then you can use the result with the TimeZoneInfo class on Windows.
One little thing: You used TimeZoneInfo.ConvertTimeToUtc, where I think you meant TimeZoneInfo.ConvertTimeFromUtc. Be careful of the directionality of the conversions.
I'll also point out that there's an alternative approach, which is to pass the UTC timestamp all the way down to the browser, and just convert from UTC to local time in JavaScript. Then you don't need to do any time zone detection at all.

Issue on single computer only - Conversion from string to type 'Date' is not valid

I regret having to write such a vague question, but I'm not really sure what to try. I have general programming experience, but no access to the source code for this and not a lot of experience with VB/.NET
We have a custom (Read: Crappy) CRM software we use at work that was written ~2008 by someone who has long since left the company. It works on both Windows 7 and Windows 10 just fine for multiple users. I am trying help a user with an "Unexpected program error":
"frmMain - FillGridTable
Conversion from string "03/31/2016 15:23:22" to type 'Date' is not valid."
when I close the dialog box it just says "LoopX = 0"
I do not have access to the source code, and regardless, it works on every other computer.
Could this be some issue with some type of library on the computer? Is there any way to check versions between computers for .NET/Microsoft libraries?
Thanks for any ideas!
Chase Rocker helped me get here in the comment he left on the question.
The windows date/time format settings were displaying a date that wasn't in the correct format. Resolved this by changing it to the MM/dd/YYYY format the error was suggesting the program expected.
I'm glad to see that you solved the issue by changing the computer's regional settings, but to be honest this is probably overkill for what you're wanting to do. Instead, you could have used the DateTime.TryParseExact function.
Here is a quick example of utilizing the built-in method:
Dim conversion As DateTime
Dim input As String = "11/30/2017"
If DateTime.TryParseExact(input, "MM/dd/yyyy", New CultureInfo("en-US"), DateTimeStyles.None, conversion) Then
'Converted successfully
Else
'A true conversion error occured
End If
Fiddle: Live Demo

Date Differences between Windows 10 and Windows 7

I recently asked this question:
DateTime.ParseExact was not recognized as a valid DateTime
The question was answered and the approach worked great. This was until I tried running it on a windows 10 machine. I then get the error:
String Not Recognized As Valid DateTime
By "String" I assume the debugger is referencing the dd/MM/yy. Does anyone have any idea why this may be? Here's the code if you don't want to trawl through the linked question:
Tabledate = DateTime.ParseExact("30/11/12", "dd/MM/yy", CultureInfo.InvariantCulture)
UPDATE 1
Thanks to #Blackwood for the comment about the actual computers time, I just changed window's 10 Short Date format to "dd/MM/yy" from "dd/MM/yyyy" and the code runs fine!
Now I don't know what format other people's computers may be in, so I suppose my next approach will be to research if I can obtain what format the current PC is in and then use that format as a variable
I guess this has something to do with Culture, ist seems to be the dateformat u r passing : "dd/MM/yy"
Try this :
DateTime.ParseExact("30/11/12","d", CultureInfo.InvariantCulture)
https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx

How to change Time Format in VB.NET from 24 to 12?

I am using these codes for displaying time in VB.NET
it shows up in 24 hours format besides i need it in 12 hours format
System.DateTime.Now.Hour
System.DateTime.Now.Minute
System.DateTime.Now.Second
example:
14:12:42
I need it as :
02:12:42
thanks.
Use String.Format. For example:
String.Format("{0:T}", System.DateTime.Now) //02:12:42 PM
String.Format("{0:hh:mm:ss}", System.DateTime.Now) //02:12:42
String.Format("{0:hh:mm:ss tt}", System.DateTime.Now) //02:12:42 PM
Also, this website to be very helpful in summarizing the various ways you can use String.Format. Keep in mind the culture can make a difference on non-custom formats. The first example above using T (Long Time format) works on my US-based PC just fine. But if you say:
String.Format(System.Globalization.CultureInfo.InvariantCulture, _
"{0:T}", System.DateTime.Now)
You end up with 14:12:42. The latter two examples are custom formats and are not affected by culture.
When using DateTime objects you can actually use the ToString() method and set your format inside it.
string currentTime = System.DateTime.Now.ToString("hh:mm:ss");
Check this msdn article out for more clarity:
http://msdn.microsoft.com/en-us/library/zdtaw1bw.aspx
Use the appropriate format string for display.
string formatted = myDateTime.ToString("hh:mm:ss");
I have used a custom format string in this case.
1-Use regex to get first two characters of that string ie from 23:11:59 get 23
2-convert this number to integer type
3-now check it if it is not greater than 12 and if it is subtract 12 from it and by using string.replace replace the old value.
Try This...
Dim CurTime As String
CurTime = TimeOfDay.ToString("h:mm:ss tt")

VisualBasic Month function inconsistency

I'm working in a web application using VB.NET. There is also VisualBasic code mixed in it, in particular the Date variable and the Month function of VB.
The problem is this part:
Month("10/01/2008")
On the servers, I get 10 (October) as the month (which is supposed to be correct). On my machine, I get 1 (January) (which is supposed to be wrong).
Two of my colleagues (on their own machines) get different answers, one got 1, the other got 10.
The question is, why is this so?
On my end, I can solve the problem by using .NET's DateTime's Parse (or ParseExact) function to force everything to be "dd/MM/yyyy" format. This works. I'm just wondering why there's an inconsistency.
Extra info: I know the parameter for Month function is supposed to be a Date variable. The code used a string as parameter, and Option Strict was off, and the developers mainly let VB do its own conversion thing. (Legacy code maintenance has a lot of inertia...)
If it helps, the version of Microsoft.VisualBasic.dll on the servers is 7.10.6310.4 (under the Framework folder v1.1.4322). The version on mine (and my 2 colleagues') machine is 7.10.6001.4.
Edit: Regional settings for all machines already set to dd/MM/yyyy format (short date format).
This normally has to do with the regional settings, and more specifically the date/time formats. If you set these formats so that they are all the same on the machines you're testing on, the results should be consistent.
Your idea of using ParseExact is definitely the better solution to go with, IMHO.
This is because the runtime has to convert your given value "10/01/2008" which is indeed a string implicitly to the DateTime datatype.
When converting strings to dates and the other way round, the string format depends on the locale settings of windows.
See this link on msdn.
In this article a way to specify a date literal which is independent of your locale settings:
Just enclose the date with the sign # and specify it in the form mm/dd/yyyy:
So the code
Month(#10/01/2008#)
should give you the answer 10 on any machine.
Ther a two more worarounds given in that msdn article:
1. Use the Format Function with predifned Date/Time Format
To convert a Date literal to the
format of your locale, or to a custom
format, supply the literal to the
Format Function, specifying either
Predefined Date/Time Formats (Format
Function) or User-Defined Date/Time
Formats (Format Function). The
following example demonstrates this.
MsgBox("The formatted date is " &
Format(#5/31/1993#, "dddd, d MMM
yyyy"))
2. Use the DateTime-Class Constructor to construt the right DateTime value
Alternatively, you can use one of the
overloaded constructors of the
DateTime structure to assemble a date
and time value. The following example
creates a value to represent May 31,
1993 at 12:14 in the afternoon.
Dim dateInMay As New
System.DateTime(1993, 5, 31, 12, 14,
0)