Why converting a date to a string changes the order? - vb.net

Here is a peculiar result generated from this simple code:
Dim TodaysDate As Date = Date.Today ' Returns #8/12/2014#
Dim StringDate As String = TodaysDate ' Returns 12/08/2014
Dim AnotherStringDate As String = TodaysDate.ToString ' Returns 12/08/2014 00:00:00
What is going on? Why the string reversed the result, although I did not even used any conversion command?

Change Option Strict to On, then you get a compiler error instead of weird conversions. In general, a Date is not a String but it can be represented as one.
If i remember correctly VB uses helper methods with Option Strict Off to convert the type automatically which are sitting in the namespace Microsoft.VisualBasic.CompilerServices.
I've looked at the source-code (with ILSpy) and found a class StringType which has a method FromDate:
' Microsoft.VisualBasic.CompilerServices.StringType
Public Shared Function FromDate(Value As DateTime) As String
Dim ticks As Long = Value.TimeOfDay.Ticks
If ticks = Value.Ticks OrElse (Value.Year = 1899 AndAlso Value.Month = 12 AndAlso Value.Day = 30) Then
Return Value.ToString("T", Nothing)
End If
If ticks = 0L Then
Return Value.ToString("d", Nothing)
End If
Return Value.ToString("G", Nothing)
End Function
Since your Date was derived from Date.Today which is the current date without time, the code will be executed which starts with If ticks = 0L Then(ticks is from the time of the day).
This returns:
Value.ToString("d", Nothing)
which is the same as Date.ToShortDateString. The format is derived from your current culture since null is passed as CultureInfo. So obviously your current culture uses / as date separator.
You could also force this format by using:
Dim StringDate As String = TodaysDate.ToString("d")
StringDate = TodaysDate.ToShortdateString()
StringDate = TodaysDate.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture)
The last option also ensures that this format is used even if your current culture is different.

A date is stored internally as number. And a date/datetime variable doesn't really know or care what actual date it represents; it is just a number (decimal). The string representation is for our eyes only. When you convert a date/datetime variable to string type, it is converted in the format specified by our machine locale settings, unless we specifically tell it to convert it to some other format.
I am assuming that the date/time settings on your PC is in the dd/mm/yyyy (indian format) format rather than the default mm/dd/yyyy (US format).
So this is what is actually happening:
' You store today's date in a Date variable and it returns #8/12/2014# i.e. 12-Aug-2014
Dim TodaysDate As Date = Date.Today
' You convert it to string. Since you didn't sepecify the format, it picks up the fromat settings from your PC regional settings.
' Returns 12/08/2014 which means 12-Aug-2014 (in your locale)
' You didn't do .ToString, but that's implicit, unless you set OPTION STRICT ON, in which case it will force you to put .ToString
Dim StringDate As String = TodaysDate
' Same argument as above.
Dim AnotherStringDate As String = TodaysDate.ToString ' Returns 12/08/2014 00:00:00

As for the question why converting a date to a string changes the order? The answer is that it doesnt.
When you convert to string, your local culture format is used, as explained by Tim. That's not teh case with Date literals in VB.
Date literals - values between hashes such as #02/11/2014# - are always displayed in InvariantCulture or "m/d/y" pattern. This is likely because when you wish to create a date using a literal, you must specify the Day and Month in that format. See MSDN:
Date literals must be in the format #m/d/yyyy# or they are invalid.
So, it would make no sense to display the date to you in one pattern but require you to create them using a different pattern. This is just the way VB works (in part because the legacy functions have no notion of cultures beyond the local one in use). This is a VB-ism as seen in this VB vs C# date display in Visual Studio:
The culture is set to fr-FR.
But your strings ultimately represent the same date - they can make a roundtrip:
Dim TodaysDate As Date = Date.Today ' Returns #8/12/2014#
Dim AnotherStringDate As String = TodaysDate.ToString
Dim mydt As DateTime = DateTime.Parse(AnotherStringDate)
If mydt = TodaysDate Then
Console.Beep()
End If
It will beep because the same DateTime is created from the string even though it may display in the pattern of "d/m/y" for yur culture.

Related

My Format Date Function Doesn't Work In Microsoft Access

I am writing a simple code that converts the date value of the default format(MM/DD/YYYY) of the first textbox into a different format of(DD/MM/YYYY) of the second textbox based on the Exit Event
For some reason, it ALWAYS returns the date format MM/DD/YYYY.
'First Code to convert it into a string
Private Sub date1_Exit(Cancel As Integer)
Dim dat_ed As Date
dat_ed = CDate(Me.date1.Value)
dat_ed = Format(CStr(dat_ed), "d/m/yyyy")
Me.date2.Value = dat_ed
End Sub
'Second Attempt to convert it directly
Dim dat_ed As Date
dat_ed = CDate(Me.date1.Value)
dat_ed = Format(dat_ed, "d/m/yyyy")
Me.date2.Value = dat_ed
Your code is wrong on a couple of places, mainly because you're confusing dates and strings formatted as dates.
Dim dat_ed As String 'You want this to hold a formatted date, so it's a string not a date
'dat_ed = CDate(Me.date1.Value) 'We can't do this because a string can't hold a date
'So we combine the next two calls
dat_ed = Format(CDate(Me.date1.Value), "d/m/yyyy")
'No CString in format, we need it to get the date as a date
'Note that / in format means the system date separator, if you want literal slashes, use \/ instead
Me.date2.Value = dat_ed
Also note, if your textbox has the Format property set to a specific date format, you need to modify that property, instead of assigning a formatted date to it.
You are making it way too complicated.
First, if you have applied a date/time format to the Format property of a textbox, Access knows that this is a datetime value.
Second, a date/time value carries no format. It is a value.
Third, to have a date value displayed in a specific format, apply this format to the Format property of the textbox.
Thus, apply the format d/m/yyyy (or d\/m\/yyyy) to textbox date2. Then:
Private Sub date1_Exit(Cancel As Integer)
Me!date2.Value = Me!date1.Value
End Sub

VB.NET - Unable to enforce two digit day and month when converting string to Date

I am having difficulty taking a string and converting it to a vb.net Date object, while enforcing two digit day and month. Please consider the following form example, using today's date. (02/01/2019)
Dim myDate As Date = Date.Now
Dim myDateString = String.Format("{0:D2}/{1:D2}/{2:D4}", myDate.Month, myDate.Day, myDate.Year)
myDate = DateTime.ParseExact(myDateString, "MM/dd/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None)
Label1.Text = myDate 'This will show "2/1/2019"
Label2.Text = myDateString 'This will show "02/01/2019"
This situation leaves Label1.Text as "2/1/2019", but Label2.Text as "02/01/2019". No matter what I have tried, it appears that the actual conversion from the correctly formatted String into a Date object will remove these zeros. Does anyone have any thoughts as to how I can enforce a "MM/dd/yyyy" format when converting to a Date object?
Thank you in advance,
You should consider that a DateTime variable has no format. It is just a number expressing the Ticks elapsed from the starting DateTime.MinValue (1/1/0001).
It has no memory that you have built it using a particular formatting parser.
So, when you assign a date to a string like you do in your
Label1.Text = myDate
then you are asking the ToString representation of that date. The output of this method without a formatting parameter is whatever your locale settings decide it to be. If you want to force the desidered output you need to tell the date's ToString method in what format you want the output
Label1.Text = myDate.ToString("MM/dd/yyyy")

Console Application: User entered date Visual Basic

I'm using VS 2013 and VB language
My task is to store a user entered date in the format mm/dd/yyyy
Dim date1 As String = Format("MM/dd/yyyy")
Dim date2 As Date
Dim date3 As Date
date1 = Console.ReadLine()
date2 = DateTime.Now
date3 = DateTime.Parse(date1)
Console.ReadLine()
I first tried entering the date as Dim date1 as Date, but entering it in mm/dd/yyyy is invalid format.
So I tried this method, and get the error "String was not recognized as a valid DateTime"
How can I format the entered date so that it will be recognized as a valid datetime?
Thanks
User cannot be forced to enter the date in the format that you expect (particularly on a console application). So your best line of action is trying to parse this date and inform your user that the input is invalid
Dim isValid = False
Dim dt As DateTime
While(Not isValid)
Console.WriteLine("Please enter a date in the format MM/dd/yyyy")
Dim input = Console.ReadLine()
isValid = DateTime.TryParseExact(input, "MM/dd/yyyy", _
CultureInfo.InvariantCulture, DateTimeStyles.None, dt)
End While
DateTime.TryParseExact is a method of the DateTime that tries to parse the input string accordingly to a format specified. If the string complies to the format required then the method returns true and the last parameter is set to the datetime resulting from the conversion. Otherwise the method return false without throwing an exception so you could take the appropriate measures (in this case request again the input)
All dates are stored in memory as dates, and do not actually have formats. The formats appear when you change the date into a string (i.e. with the Date.ToString() method).
I think the best option here is to use Date.Parse() with no arguments, so that the command-line will accept all date formats (be prepared to catch format exceptions), and then when you need to display the date back to the user, format it using a format string and the Date.ToString() method.
Code example follows:
Dim strDateFormat = "MM/dd/yyyy"
Dim date2 As Date
Dim date3 As Date
date2 = Now()
date3 = Date.Parse(Console.ReadLine())
Console.WriteLine(date3.ToString(strDateFormat))
P.S. As you have it written, the command input overwrites your formatting string, so your formatting string is effectively useless.

Convert string date to show 2 year digits

i have a string which has a value of "08-06-2008". I want the result to look like "08-06-08". Is there a way to do this? I've tried CDate but that only gives me 8/06/2008 which doesnt resolve the issue.
Parse it to Date and back to string:
Dim dt As Date = Date.ParseExact("08-06-2008", "MM-dd-yyyy", CultureInfo.InvariantCulture)
Dim result As String = dt.ToString("MM-dd-yy", CultureInfo.InvariantCulture)
Since that is a normal format you could also omit the format string and use Date.Parse directly:
Dim dt As Date = Date.Parse("08-06-2008", CultureInfo.InvariantCulture)
I have used CultureInfo.InvariantCulture to avoid localization issues, normally your current culture is used in Parse/ParseExact and ToString.
See: Custom Date and Time Format Strings
Firstly, avoid CDate. It is a hangover from VB6, and is almost certainly less efficient than using the .net equivalent.
The following should give you the right answer:
string value = DateTime.ParseExact("08-06-2008", "dd-MM-yyyy").ToString("dd-MM-yy")
Note that your existing date format is ambiguous, so I've been unable to tell if you're meaning the 6th of August or the 8th of June - this is why I've used ParseExact over Parse. ParseExact is also slightly more efficient, as it tells the framework which format to use, rather than it having to guess.
Try this
Dim FormatString As String = ""
Dim SampleDate As DateTime
SampleDate = Now()
FormatString = Format(SampleDate,"dd-MM-yy")

How to get a date field from MM/dd/yyyy to yyyy/MM/dd in vb.net

I need to get a date field from MM/dd/yyyy to yyyy/MM/dd in vb.net but it should still be a date field afterward so that I can match it against a date in a database.
At the moment all I'm managing to do is to change it to a string in that format.
I tried this type of code which also did not work.
DateTime.Parse(yourDataAsAString).ToString("yyyy-MM-dd")
fromDeString = String.Format("{0:yyyy/MM/dd}", aDate)
fromDate = Format("{0:yyyy/MM/dd}", aDate)
Any help would be much apreciated, thanks
You're not understanding that a date object does not store the digits in any particular format. The only way to get the digits formatted in the order you want is to convert it to a string. Why do you need to compare them in a particular format? A date is a date no matter how it is formatted. 12/15/78 == 1978/12/15.
If you are not able to compare dates from the DB against a date object in VB, it is likely that the date you are comparing to in the database is being returned to you in string format, in which case you should covert it to a date object for comparison.
Dim sDate As String = "2009/12/15" 'Get the date from the database and store it as a string
Dim dDate As New Date(2009, 12, 15) 'Your date object, set to whatever date you want to compare against
Select Case Date.Compare(dDate, Date.Parse(sDate))
Case 0
'The dates are equal
Case Is > 0
'The date in the database is less
Case Is < 0
'The date in the database is greater
End Select
Here's a sample module demonstrating the functionality you desire.
Imports System.Globalization
Module Module1
Sub Main()
Dim culture As New CultureInfo("en-us", True)
Dim mmDDyy As String = "10/23/2009"
Dim realDate As Date = Date.ParseExact(mmDDyy, "mm/dd/yyyy", culture)
Dim yyMMdd As String = realDate.ToString("yyyy/MM/dd")
End Sub
End Module
Hope this helps.
Kind Regards
Noel
Your second should actually work. Instead just try:
dim chislo as date = date.now dim message As String = $"
Today`s Date: {String.Format("{0:dddd, dd/MM/yyyy}", Chislo)} "
MsgBox(message)