468,765 Members | 1,279 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,765 developers. It's quick & easy.

Globalization versus DateTime.ParseExact

Hello everybody,

Jay and Herfried are telling me every time when I use CDate that using the
datetime.parseexact is always the best way to do String to datetime
conversions. They don't tell why only that I have to listen to them because
they know it better.

They told also that in a business situation it is better to use
datetime.parseexact for changing cultures and not to use the globalization
setting. I did not give them this sample, only told the situation how that
in my opinion has to be done. Jay gave the business sample by the way in
another thread, where he told that using datetime.parseexact was the way to
go for that. However did in that thread as well not tell how and why it was
better, only that he, Herfried and a C# MVP were telling that and therefore
it was better.

I have made a little code example from it, to make it more showable, can
someone tell me how it can be done better using datetime.parseexact as Jay
and Herfried constantly are telling, and why that is better to use in this
kind of situations where the documents can come from all over the world.

Public Class test
Shared Sub main()
Dim d As New document
Dim o As New order
'The next is the setting from an XML file or whatever document
d.culture = "nl-NL"
d.deliverydate = "25 aug 2004"
d.orderdate = "10 juli 2004"
d.price = "? 111,10"
d.quantity = "10.000"
Dim thisErrors As Errors = ConvertDocumentToOrder(d, o)
'Do the debugprinting yourself
'This is another document
d.culture = "en-US"
d.deliverydate = "aug 25 2004"
d.orderdate = "july 10 2004"
d.price = "$ 111.10"
d.quantity = "10,000"
thisErrors = ConvertDocumentToOrder(d, o)
'Do the debugprinting yourself
End Sub
Public Shared Function ConvertDocumentToOrder(ByVal d As document, _
ByVal o As order) As Errors
Dim myError As New Errors
Try
Threading.Thread.CurrentThread.CurrentCulture = _
New Globalization.CultureInfo(d.culture)
o.orderdate = CDate(d.orderdate)
o.deliverydate = CDate(d.deliverydate)
o.price = CDec(d.price)
o.quantity = CInt(d.quantity)
o.culture = d.culture
Return myError
Catch ex As Exception 'However whatever error set
'evaluate(myerror, ex)
Return myError
Finally
Threading.Thread.CurrentThread.CurrentCulture = _
Globalization.CultureInfo.InstalledUICulture
End Try
End Function
End Class
Public Class document
Public orderdate As String
Public deliverydate As String
Public quantity As String
Public price As String
Public culture As String
End Class
Public Class order 'Normally with properties where validation is used
Public orderdate As DateTime
Public deliverydate As DateTime
Public quantity As Integer
Public price As Decimal
Public culture As String
End Class
Public Class Errors
Public whatever As String
Public Sub New()
whatever = ""
End Sub
End Class

With what I don't say that there can be probably situations where
datetime.parseexact are simpler to use, however that in my opinion when you
know exactly the format of the string(s), that will be used in the document.
Nov 21 '05 #1
11 6701
"Cor Ligthert" <no************@planet.nl> schrieb:
Public Class test
Shared Sub main()
Dim d As New document
Dim o As New order
'The next is the setting from an XML file or whatever document
d.culture = "nl-NL"
d.deliverydate = "25 aug 2004"
d.orderdate = "10 juli 2004"
d.price = "? 111,10"
d.quantity = "10.000"
Dim thisErrors As Errors = ConvertDocumentToOrder(d, o)
'Do the debugprinting yourself
'This is another document
d.culture = "en-US"
d.deliverydate = "aug 25 2004"
d.orderdate = "july 10 2004"
d.price = "$ 111.10"
d.quantity = "10,000"
thisErrors = ConvertDocumentToOrder(d, o)
'Do the debugprinting yourself
End Sub
Public Shared Function ConvertDocumentToOrder(ByVal d As document, _
ByVal o As order) As Errors
Dim myError As New Errors
Try
Threading.Thread.CurrentThread.CurrentCulture = _
New Globalization.CultureInfo(d.culture)
o.orderdate = CDate(d.orderdate)
o.deliverydate = CDate(d.deliverydate)
o.price = CDec(d.price)
o.quantity = CInt(d.quantity)
o.culture = d.culture
Return myError
Catch ex As Exception 'However whatever error set
'evaluate(myerror, ex)
Return myError
Finally
Threading.Thread.CurrentThread.CurrentCulture = _
Globalization.CultureInfo.InstalledUICulture


Same bug. This will not necessarily reset the culture to the culture used
before.

Instead of using 'CDate' and changing the culture, I would use
'DateTime.Parse' (= 'Date.Parse') and specify the 'DateTimeInfo':

\\\
.... = Date.Parse(d.DiliveryDate, ci.DateTimeFormat)
///

.... 'ci' is your custom culture info with the custom date/time format set.

--
Herfried K. Wagner [MVP]
<URL:http://dotnet.mvps.org/>

Nov 21 '05 #2
>
Instead of using 'CDate' and changing the culture, I would use
'DateTime.Parse' (= 'Date.Parse') and specify the 'DateTimeInfo':

\\\
... = Date.Parse(d.DiliveryDate, ci.DateTimeFormat)
///

This is this newsgroup almost full of, I asked why, what is the benefit, I
see only more to type words?

And what about all the other culture depending values?

Cor
Nov 21 '05 #3
"Cor Ligthert" <no************@planet.nl> schrieb:
Instead of using 'CDate' and changing the culture, I would use
'DateTime.Parse' (= 'Date.Parse') and specify the 'DateTimeInfo':

\\\
... = Date.Parse(d.DiliveryDate, ci.DateTimeFormat)
///

This is this newsgroup almost full of, I asked why, what is the benefit, I
see only more to type words?

And what about all the other culture depending values?


Most 'Parse' methods expect a format information, for example
'Int32.Parse'...

--
Herfried K. Wagner [MVP]
<URL:http://dotnet.mvps.org/>

Nov 21 '05 #4
Cor,
Jay and Herfried are telling me every time when I use CDate that using the
datetime.parseexact is always the best way to do String to datetime Ah! There's the rub, you are talking Oranges; Herfried, Jon & I are talking
Apples! :-)

The Oranges:

Actually in Your Example I would use DateTime.Parse:

Instead of: Threading.Thread.CurrentThread.CurrentCulture = _
New Globalization.CultureInfo(d.culture)
o.orderdate = CDate(d.orderdate)
o.deliverydate = CDate(d.deliverydate)
I would use:
Dim culture As New Globalization.CultureInfo(d.culture)

o.orderdate = DateTime.Parse(d.orderdate, culture)
o.deliverydate = DateTime.Parse(d.deliverydate, culture)

Notice that I am simply passing the culture required in the above, rather
then relying on the "global variable" CurrentCulture. By passing the cutlure
as a parameter, I don't need a Try/Finally to restore the "global variable"
CurrentCulture. Also I do not risk changing the "global variable"
CurrentCulture that routines that ConvertDocumentToOrder may call require
set in a specific way. Yes you want it changed for CDate, however you may
not want it changed for CDec or CInt! For example changing the decimal
separator from a comma to a period. Plus you may call one of your own
routines (or team's routines) that requires the CurrentCulture to be a
specific value.

I hope you agree tracking down problems with "global variables" in a program
can be very difficult, especially when they are being set & reset all over
the program, as opposed to being set once & left alone...

All the formatting information needed by DateTime.Parse is contained in the
passed CutltureInfo object, As Herfried showed, DateTime.Parse will notice
that its a CultureInfo & actually use CultureInfo.DateTimeFormat property.
Likewise with CDec & CInt, if they need to follow the specific culture,
there is Decimal.Parse & Integer.Parse that accepts a CultureInfo object.
o.price = Decimal.Parse(d.price, culture)
o.quantity =Integer.Parse(d.quantity, culture)
Both Decimal.Parse & Integer.Parse will see the CultureInfo and actually use
CultureInfo.NumberFormat.

CDate, CDec, & CInt use the same CultureInfo object, they just don't allow
you to pass it directly, instead they rely on a global variable... Maybe MS
could simplify it for you & beginner VB.NET developers by allowing you to
specify the format or culture on VB.NET's conversion functions. Rather then
try to explain why you might use DateTime.Parse or DateTime.ParseExact
instead of the CDate. Would you understand it better if you could do the
following?
Dim ci As New Globalization.CultureInfo(d.culture) o.orderdate = CDate(d.orderdate, ci)
o.deliverydate = CDate(d.deliverydate, ci)
o.price = CDec(d.price, ci)
o.quantity = CInt(d.quantity, ci)
In other words: CDate, CDec, & CInt do not allow you to specify the
CultureInfo needed, I am suggesting using DateTime.Parse rather then change
a global variable/setting.

Note: In your example, you are not restoring the original value of the
"global variable" CurrentCulture. At the very least save the current
CurrentCulture, then return the CurrentCulture to the one you save.

Dim startingCulture As CultureInfo =
Threading.Thread.CurrentThread.CurrentCulture Try
Threading.Thread.CurrentThread.CurrentCulture = _
New Globalization.CultureInfo(d.culture)
o.orderdate = CDate(d.orderdate)
o.deliverydate = CDate(d.deliverydate)
o.price = CDec(d.price)
o.quantity = CInt(d.quantity)
o.culture = d.culture
Return myError
Catch ex As Exception 'However whatever error set
'evaluate(myerror, ex)
Return myError
Finally
Threading.Thread.CurrentThread.CurrentCulture = _ startingCulture End Try

Consider what happens if at the top of the Main routine the CurrentCulture
is set to a specific culture:
Shared Sub main() ' we have many different installed cultures on our network
' we need to insure that German - Switzerland is used all the time!
Threading.Thread.CurrentThread.CurrentCulture = _
New Globalization.CultureInfo("de-CH")
Dim d As New document
More then likely the above would be an ASP.NET app, and the CurrentCulture
is determined by the login routine, seeing as the ASP.NET app is world wide,
the CurrentCulture will be very different then the InstalledUICulture!
The Apples:

The other examples include a specific date format, they have nothing to do
with changing the culture!

For example, if I am exchanging text or XML documents between the US, The
Netherlands, Switzerland, Germany & Japan, having the date in a specific
format, such as Year, Month, Day is required otherwise we would get Oct 1
confused with Jan 10. In this case I would use DateTime.ParseExact to
convert the date string in a specific format in the text document to an
actual DateTime object.

' dates are always in Year, Month, Day format! o.orderdate = DateTime.ParseExact(d.orderdate, "yyyy/MM/dd",
nothing)
o.deliverydate = DateTime.ParseExact(d.deliverydate,
"yyyy/MM/dd", nothing)
In the two aforementioned threads I am discussing this last scenario.

I'm really hoping that this is helping!
Jay

"Cor Ligthert" <no************@planet.nl> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl... Hello everybody,

Jay and Herfried are telling me every time when I use CDate that using the
datetime.parseexact is always the best way to do String to datetime
conversions. They don't tell why only that I have to listen to them
because they know it better.

They told also that in a business situation it is better to use
datetime.parseexact for changing cultures and not to use the globalization
setting. I did not give them this sample, only told the situation how
that in my opinion has to be done. Jay gave the business sample by the way
in another thread, where he told that using datetime.parseexact was the
way to go for that. However did in that thread as well not tell how and
why it was better, only that he, Herfried and a C# MVP were telling that
and therefore it was better.

I have made a little code example from it, to make it more showable, can
someone tell me how it can be done better using datetime.parseexact as Jay
and Herfried constantly are telling, and why that is better to use in this
kind of situations where the documents can come from all over the world.

Public Class test
Shared Sub main()
Dim d As New document
Dim o As New order
'The next is the setting from an XML file or whatever document
d.culture = "nl-NL"
d.deliverydate = "25 aug 2004"
d.orderdate = "10 juli 2004"
d.price = "? 111,10"
d.quantity = "10.000"
Dim thisErrors As Errors = ConvertDocumentToOrder(d, o)
'Do the debugprinting yourself
'This is another document
d.culture = "en-US"
d.deliverydate = "aug 25 2004"
d.orderdate = "july 10 2004"
d.price = "$ 111.10"
d.quantity = "10,000"
thisErrors = ConvertDocumentToOrder(d, o)
'Do the debugprinting yourself
End Sub
Public Shared Function ConvertDocumentToOrder(ByVal d As document, _
ByVal o As order) As Errors
Dim myError As New Errors
Try
Threading.Thread.CurrentThread.CurrentCulture = _
New Globalization.CultureInfo(d.culture)
o.orderdate = CDate(d.orderdate)
o.deliverydate = CDate(d.deliverydate)
o.price = CDec(d.price)
o.quantity = CInt(d.quantity)
o.culture = d.culture
Return myError
Catch ex As Exception 'However whatever error set
'evaluate(myerror, ex)
Return myError
Finally
Threading.Thread.CurrentThread.CurrentCulture = _
Globalization.CultureInfo.InstalledUICulture
End Try
End Function
End Class
Public Class document
Public orderdate As String
Public deliverydate As String
Public quantity As String
Public price As String
Public culture As String
End Class
Public Class order 'Normally with properties where validation is used
Public orderdate As DateTime
Public deliverydate As DateTime
Public quantity As Integer
Public price As Decimal
Public culture As String
End Class
Public Class Errors
Public whatever As String
Public Sub New()
whatever = ""
End Sub
End Class

With what I don't say that there can be probably situations where
datetime.parseexact are simpler to use, however that in my opinion when
you know exactly the format of the string(s), that will be used in the
document.

Nov 21 '05 #5

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com>
Cor,
Jay and Herfried are telling me every time when I use CDate that using
the datetime.parseexact is always the best way to do String to datetime Ah! There's the rub, you are talking Oranges; Herfried, Jon & I are
talking Apples! :-)

The Oranges:

Actually in Your Example I would use DateTime.Parse:

Instead of:
Threading.Thread.CurrentThread.CurrentCulture = _
New Globalization.CultureInfo(d.culture)
o.orderdate = CDate(d.orderdate)
o.deliverydate = CDate(d.deliverydate)


I would use:
Dim culture As New Globalization.CultureInfo(d.culture)

o.orderdate = DateTime.Parse(d.orderdate, culture)
o.deliverydate = DateTime.Parse(d.deliverydate, culture)


Why?

I am asking that in every message however did not get an answer not from you
and not from Herfried. Microsoft advises to use the Microsoft.VisualBasic
conversion functions for this. Do you know something that there is wrong in
documentation from Microsoft about this.? Or is there a piece of
documentation I never saw. Until that I relly on this from this page.

================================================== =======
http://msdn.microsoft.com/library/de...tinternals.asp
Conversion Functions, CType, DirectCast, and System.Convert
Visual Basic .NET includes data type conversion keywords, many of which are
carried over from Visual Basic 6. But unlike the Visual Basic 6 functions,
these keywords are not function calls but intrinsic language features. The
keywords CBool, CByte, CChar, CShort, CInt, CLng, CSng, CDbl, CDec, CDate,
CObj, and CStr map to Visual Basic Runtime method calls, .NET Framework
class library method calls, or IL type conversion instructions. The exact
method call or IL instructions generated depends on the expression against
which the conversion is being applied. Some conversions are optimized away,
such as CInt(123.45) which is replaced with the integer constant 123 in the
IL. This is an example where using the Visual Basic Runtime results in
better performance than using the System namespace. CInt("123") becomes a
call that leads to calls to System.Double.Parse then System.Math.Round.
CStr(4853) is ultimately handled by System.Int32.ToString. Conversions that
are not optimized away eventually lead to methods in the System namespace,
but there is no significant performance benefit when using the System
namespace methods directly. Furthermore, the Visual Basic compiler is able
to perform certain optimizations on conversions using the language keywords
that it does not perform on conversions done through the System namespace.

--------------------------------------------------------------------------------------- Notice that I am simply passing the culture required in the above, rather
then relying on the "global variable" CurrentCulture. By passing the
cutlure as a parameter, I don't need a Try/Finally to restore the "global
variable"
The Try/Finally is not for the global variable setting however to catch
mistypings and throwed errors by the validation from the orderclass wich can
than be catched and processed by the sender of the DocumentToOrder
procedure.
CurrentCulture. Also I do not risk changing the "global variable"
CurrentCulture that routines that ConvertDocumentToOrder may call require
set in a specific way. Yes you want it changed for CDate, however you may
not want it changed for CDec or CInt! For example changing the decimal
separator from a comma to a period. Plus you may call one of your own
Obvious I want to change those, do you not know that they are part of
culture settings and in an ASPNET application would be than very important.
routines (or team's routines) that requires the CurrentCulture to be a
specific value.
What I would do in my orderclass, with the culture however I thougth that
everybody would understand that.
I hope you agree tracking down problems with "global variables" in a
program can be very difficult, especially when they are being set & reset
all over the program, as opposed to being set once & left alone...
You are using them in every line. That is exact why I tell to use a global
setting and when that is build in, use that. .
All the formatting information needed by DateTime.Parse is contained in
the passed CutltureInfo object, As Herfried showed, DateTime.Parse will
notice that its a CultureInfo & actually use CultureInfo.DateTimeFormat
property. Likewise with CDec & CInt, if they need to follow the specific
culture, there is Decimal.Parse & Integer.Parse that accepts a CultureInfo
object.
o.price = Decimal.Parse(d.price, culture)
o.quantity =Integer.Parse(d.quantity, culture)

Again you avoid the avised methodes by Microsoft, can you give the
documentation where this is stated by Microsoft as better, it seems to me
code witch has very much change on errors.
Both Decimal.Parse & Integer.Parse will see the CultureInfo and actually
use CultureInfo.NumberFormat.

CDate, CDec, & CInt use the same CultureInfo object, they just don't allow
you to pass it directly, instead they rely on a global variable... Maybe
MS
I am very lucky with that, it is one of the basics from OOP programming to
narrowing everything as much as possible.
could simplify it for you & beginner VB.NET developers by allowing you to
Again I am not a beginner and it is not needed to simplify it for me, I can
everything understand what you and Herfried and Jon are writting. However I
use documentation you know not just empty writting, so show that.

And again do not make the suggestion that I am a beginner. I have pasted 20
replies I think with an answer in the same trend, however I stuffed them
all, I do not go to that low level of arguing.
specify the format or culture on VB.NET's conversion functions. Rather
then try to explain why you might use DateTime.Parse or
DateTime.ParseExact instead of the CDate. Would you understand it better
if you could do the following?
I showed you the Microsoft documentation, show yours. I think Microsoft did
a good job with that documtation, I do not understand your critique on that.
Dim ci As New Globalization.CultureInfo(d.culture)
o.orderdate = CDate(d.orderdate, ci)
o.deliverydate = CDate(d.deliverydate, ci)
o.price = CDec(d.price, ci)
o.quantity = CInt(d.quantity, ci)


In other words: CDate, CDec, & CInt do not allow you to specify the
CultureInfo needed, I am suggesting using DateTime.Parse rather then
change a global variable/setting.


Again see my sentence by narrowing the change on errors.

By the way it was all the time DateTime.ParseExact where you and Herfried
where talking about as the best way to go, Google archives everything you
know. .

Note: In your example, you are not restoring the original value of the
"global variable" CurrentCulture. At the very least save the current
CurrentCulture, then return the CurrentCulture to the one you save.
Dim startingCulture As CultureInfo =
Threading.Thread.CurrentThread.CurrentCulture
Try
Threading.Thread.CurrentThread.CurrentCulture = _
New Globalization.CultureInfo(d.culture)
o.orderdate = CDate(d.orderdate)
o.deliverydate = CDate(d.deliverydate)
o.price = CDec(d.price)
o.quantity = CInt(d.quantity)
o.culture = d.culture
Return myError
Catch ex As Exception 'However whatever error set
'evaluate(myerror, ex)
Return myError
Finally
Threading.Thread.CurrentThread.CurrentCulture = _ startingCulture
End Try

Consider what happens if at the top of the Main routine the CurrentCulture
is set to a specific culture:
Shared Sub main()

' we have many different installed cultures on our network
' we need to insure that German - Switzerland is used all the time!
Threading.Thread.CurrentThread.CurrentCulture =


Did you see that Thread.CurrentThread.CurrentCulture, dotNet is working with
threads which in themself are processing the steps, step by step so it will
be set in the end of my procedure evertime to the basic culture. Or by
setting it using the standard culture saved before when there is a bug as
Herfried wrote, that is really beginners work.
New Globalization.CultureInfo("de-CH")

They are in the Net, you do not have to set them.
Dim d As New document


More then likely the above would be an ASP.NET app, and the CurrentCulture
is determined by the login routine, seeing as the ASP.NET app is world
wide, the CurrentCulture will be very different then the
InstalledUICulture!


My sample is exatly made for ASPNET, it seems you did not read it, it should
work for documents from all over the world not only for Japan, Germanny, the
Netherlands, etc. where a culture setting is.

And in my sample you have nothing to do for it. (With the exception that the
IIS server variables are at the moment not sufficient for it, so we have to
wait on better ones, by instance the clientsertificates) and therefore needs
there to be field from the client at the moment where he tells his language
and country (by instance for Canada) what than can be done in my opinon by
an checked to a keys of an Idictionary implementing class which gives than
as value the culture.

I would say, try the sample and add some cultures, maybe than you understand
it better.

Cor
Nov 21 '05 #6
Cor
I'm sorry, I am not discussing this matter with you any further.

I am more then willing to help people who are actually willing to be helped.
You however...

Its really not worth my time!

Good bye!

Jay


"Cor Ligthert" <no************@planet.nl> wrote in message
news:uM****************@TK2MSFTNGP09.phx.gbl...

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com>
Cor,
Jay and Herfried are telling me every time when I use CDate that using
the datetime.parseexact is always the best way to do String to datetime

Ah! There's the rub, you are talking Oranges; Herfried, Jon & I are
talking Apples! :-)

The Oranges:

Actually in Your Example I would use DateTime.Parse:

Instead of:
Threading.Thread.CurrentThread.CurrentCulture = _
New Globalization.CultureInfo(d.culture)
o.orderdate = CDate(d.orderdate)
o.deliverydate = CDate(d.deliverydate)


I would use:
Dim culture As New Globalization.CultureInfo(d.culture)

o.orderdate = DateTime.Parse(d.orderdate, culture)
o.deliverydate = DateTime.Parse(d.deliverydate, culture)


Why?

I am asking that in every message however did not get an answer not from
you and not from Herfried. Microsoft advises to use the
Microsoft.VisualBasic conversion functions for this. Do you know something
that there is wrong in documentation from Microsoft about this.? Or is
there a piece of documentation I never saw. Until that I relly on this
from this page.

================================================== =======
http://msdn.microsoft.com/library/de...tinternals.asp
Conversion Functions, CType, DirectCast, and System.Convert
Visual Basic .NET includes data type conversion keywords, many of which
are carried over from Visual Basic 6. But unlike the Visual Basic 6
functions, these keywords are not function calls but intrinsic language
features. The keywords CBool, CByte, CChar, CShort, CInt, CLng, CSng,
CDbl, CDec, CDate, CObj, and CStr map to Visual Basic Runtime method
calls, .NET Framework class library method calls, or IL type conversion
instructions. The exact method call or IL instructions generated depends
on the expression against which the conversion is being applied. Some
conversions are optimized away, such as CInt(123.45) which is replaced
with the integer constant 123 in the IL. This is an example where using
the Visual Basic Runtime results in better performance than using the
System namespace. CInt("123") becomes a call that leads to calls to
System.Double.Parse then System.Math.Round. CStr(4853) is ultimately
handled by System.Int32.ToString. Conversions that are not optimized away
eventually lead to methods in the System namespace, but there is no
significant performance benefit when using the System namespace methods
directly. Furthermore, the Visual Basic compiler is able to perform
certain optimizations on conversions using the language keywords that it
does not perform on conversions done through the System namespace.

---------------------------------------------------------------------------------------
Notice that I am simply passing the culture required in the above, rather
then relying on the "global variable" CurrentCulture. By passing the
cutlure as a parameter, I don't need a Try/Finally to restore the "global
variable"


The Try/Finally is not for the global variable setting however to catch
mistypings and throwed errors by the validation from the orderclass wich
can than be catched and processed by the sender of the DocumentToOrder
procedure.
CurrentCulture. Also I do not risk changing the "global variable"
CurrentCulture that routines that ConvertDocumentToOrder may call require
set in a specific way. Yes you want it changed for CDate, however you may
not want it changed for CDec or CInt! For example changing the decimal
separator from a comma to a period. Plus you may call one of your own


Obvious I want to change those, do you not know that they are part of
culture settings and in an ASPNET application would be than very
important.
routines (or team's routines) that requires the CurrentCulture to be a
specific value.


What I would do in my orderclass, with the culture however I thougth that
everybody would understand that.

I hope you agree tracking down problems with "global variables" in a
program can be very difficult, especially when they are being set & reset
all over the program, as opposed to being set once & left alone...


You are using them in every line. That is exact why I tell to use a global
setting and when that is build in, use that. .
All the formatting information needed by DateTime.Parse is contained in
the passed CutltureInfo object, As Herfried showed, DateTime.Parse will
notice that its a CultureInfo & actually use CultureInfo.DateTimeFormat
property. Likewise with CDec & CInt, if they need to follow the specific
culture, there is Decimal.Parse & Integer.Parse that accepts a
CultureInfo object.
o.price = Decimal.Parse(d.price, culture)
o.quantity =Integer.Parse(d.quantity, culture)

Again you avoid the avised methodes by Microsoft, can you give the
documentation where this is stated by Microsoft as better, it seems to me
code witch has very much change on errors.
Both Decimal.Parse & Integer.Parse will see the CultureInfo and actually
use CultureInfo.NumberFormat.

CDate, CDec, & CInt use the same CultureInfo object, they just don't
allow you to pass it directly, instead they rely on a global variable...
Maybe MS


I am very lucky with that, it is one of the basics from OOP programming
to narrowing everything as much as possible.
could simplify it for you & beginner VB.NET developers by allowing you to


Again I am not a beginner and it is not needed to simplify it for me, I
can everything understand what you and Herfried and Jon are writting.
However I use documentation you know not just empty writting, so show
that.

And again do not make the suggestion that I am a beginner. I have pasted
20 replies I think with an answer in the same trend, however I stuffed
them all, I do not go to that low level of arguing.
specify the format or culture on VB.NET's conversion functions. Rather
then try to explain why you might use DateTime.Parse or
DateTime.ParseExact instead of the CDate. Would you understand it better
if you could do the following?


I showed you the Microsoft documentation, show yours. I think Microsoft
did a good job with that documtation, I do not understand your critique on
that.
Dim ci As New Globalization.CultureInfo(d.culture)

o.orderdate = CDate(d.orderdate, ci)
o.deliverydate = CDate(d.deliverydate, ci)
o.price = CDec(d.price, ci)
o.quantity = CInt(d.quantity, ci)


In other words: CDate, CDec, & CInt do not allow you to specify the
CultureInfo needed, I am suggesting using DateTime.Parse rather then
change a global variable/setting.


Again see my sentence by narrowing the change on errors.

By the way it was all the time DateTime.ParseExact where you and Herfried
where talking about as the best way to go, Google archives everything you
know. .

Note: In your example, you are not restoring the original value of the
"global variable" CurrentCulture. At the very least save the current
CurrentCulture, then return the CurrentCulture to the one you save.

Dim startingCulture As CultureInfo =
Threading.Thread.CurrentThread.CurrentCulture
Try
Threading.Thread.CurrentThread.CurrentCulture = _
New Globalization.CultureInfo(d.culture)
o.orderdate = CDate(d.orderdate)
o.deliverydate = CDate(d.deliverydate)
o.price = CDec(d.price)
o.quantity = CInt(d.quantity)
o.culture = d.culture
Return myError
Catch ex As Exception 'However whatever error set
'evaluate(myerror, ex)
Return myError
Finally
Threading.Thread.CurrentThread.CurrentCulture = _

startingCulture
End Try

Consider what happens if at the top of the Main routine the
CurrentCulture is set to a specific culture:
Shared Sub main()

' we have many different installed cultures on our network
' we need to insure that German - Switzerland is used all the time!
Threading.Thread.CurrentThread.CurrentCulture =


Did you see that Thread.CurrentThread.CurrentCulture, dotNet is working
with threads which in themself are processing the steps, step by step so
it will be set in the end of my procedure evertime to the basic culture.
Or by setting it using the standard culture saved before when there is a
bug as Herfried wrote, that is really beginners work.
New Globalization.CultureInfo("de-CH")

They are in the Net, you do not have to set them.
Dim d As New document


More then likely the above would be an ASP.NET app, and the
CurrentCulture is determined by the login routine, seeing as the ASP.NET
app is world wide, the CurrentCulture will be very different then the
InstalledUICulture!


My sample is exatly made for ASPNET, it seems you did not read it, it
should work for documents from all over the world not only for Japan,
Germanny, the Netherlands, etc. where a culture setting is.

And in my sample you have nothing to do for it. (With the exception that
the IIS server variables are at the moment not sufficient for it, so we
have to wait on better ones, by instance the clientsertificates) and
therefore needs there to be field from the client at the moment where he
tells his language and country (by instance for Canada) what than can be
done in my opinon by an checked to a keys of an Idictionary implementing
class which gives than as value the culture.

I would say, try the sample and add some cultures, maybe than you
understand it better.

Cor

Nov 21 '05 #7
"Cor Ligthert" <no************@planet.nl> schrieb:
Actually in Your Example I would use DateTime.Parse:

Instead of:
Threading.Thread.CurrentThread.CurrentCulture = _
New Globalization.CultureInfo(d.culture)
o.orderdate = CDate(d.orderdate)
o.deliverydate = CDate(d.deliverydate)
I would use:
Dim culture As New Globalization.CultureInfo(d.culture)

o.orderdate = DateTime.Parse(d.orderdate, culture)
o.deliverydate = DateTime.Parse(d.deliverydate, culture)


Why?


You snipped the explanation that goes directly after the quoted code in
Jay's post.
Microsoft advises to use the Microsoft.VisualBasic conversion functions
for this.
No.
Do you know something that there is wrong in documentation from Microsoft
about this.? Or is there a piece of documentation I never saw. Until that
I relly on this from this page.
The quoted part of the documentation does not talk about cultures.
Notice that I am simply passing the culture required in the above, rather
then relying on the "global variable" CurrentCulture. By passing the
cutlure as a parameter, I don't need a Try/Finally to restore the "global
variable"


The Try/Finally is not for the global variable setting however to catch
mistypings and throwed errors by the validation from the orderclass wich
can than be catched and processed by the sender of the DocumentToOrder
procedure.


Setting the current culture is like setting a global variable. This
variable needs to be set back.
I hope you agree tracking down problems with "global variables" in a
program can be very difficult, especially when they are being set & reset
all over the program, as opposed to being set once & left alone...


You are using them in every line. That is exact why I tell to use a global
setting and when that is build in, use that. .


There is a difference. You snipped Jay's explanation.
o.price = Decimal.Parse(d.price, culture)
o.quantity =Integer.Parse(d.quantity, culture)

Again you avoid the avised methodes by Microsoft


Microsoft doesn't give the advice to use 'C*' functions even if their use is
semantically incorrect...
could simplify it for you & beginner VB.NET developers by allowing you to


Again I am not a beginner and it is not needed to simplify it for me, I
can everything understand what you and Herfried and Jon are writting.
However I use documentation you know not just empty writting, so show
that.


If you read the docs and took at look at how 'C*' methods are working in
matters of culture variance/invariance, then you would realize that the
'CDate' method calls 'Date.Parse' and passes the current culture to it. In
fact, we do /not/ want to work with the current culture but instead want to
use a certain culture. In order to be able to specify this specific culture
without changing the current culture we pass this culture in the culture
parameter of the 'Parse' method.
My sample is exatly made for ASPNET, it seems you did not read it, it
should work for documents from all over the world not only for Japan,
Germanny, the Netherlands, etc. where a culture setting is.


That's not the point. The point is that methods called by your
implementation will use the selected culture too, which is not always
desired.

--
Herfried K. Wagner [MVP]
<URL:http://dotnet.mvps.org/>

Nov 21 '05 #8
YS
If you just want to convert a string to a date using a certain culture, then
DateTime::Parse with the culture is the best bet. I'm not going to set the
thread culture just to do one call to CDate, which as Herfried said just
calls DateTime::Parse with the culture anyway. I vote with Herfried, Jay,
John.

YS

"Cor Ligthert" <no************@planet.nl> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
Hello everybody,

Jay and Herfried are telling me every time when I use CDate that using the
datetime.parseexact is always the best way to do String to datetime
conversions. They don't tell why only that I have to listen to them because they know it better.

They told also that in a business situation it is better to use
datetime.parseexact for changing cultures and not to use the globalization
setting. I did not give them this sample, only told the situation how that in my opinion has to be done. Jay gave the business sample by the way in
another thread, where he told that using datetime.parseexact was the way to go for that. However did in that thread as well not tell how and why it was better, only that he, Herfried and a C# MVP were telling that and therefore it was better.

I have made a little code example from it, to make it more showable, can
someone tell me how it can be done better using datetime.parseexact as Jay
and Herfried constantly are telling, and why that is better to use in this
kind of situations where the documents can come from all over the world.

Public Class test
Shared Sub main()
Dim d As New document
Dim o As New order
'The next is the setting from an XML file or whatever document
d.culture = "nl-NL"
d.deliverydate = "25 aug 2004"
d.orderdate = "10 juli 2004"
d.price = "? 111,10"
d.quantity = "10.000"
Dim thisErrors As Errors = ConvertDocumentToOrder(d, o)
'Do the debugprinting yourself
'This is another document
d.culture = "en-US"
d.deliverydate = "aug 25 2004"
d.orderdate = "july 10 2004"
d.price = "$ 111.10"
d.quantity = "10,000"
thisErrors = ConvertDocumentToOrder(d, o)
'Do the debugprinting yourself
End Sub
Public Shared Function ConvertDocumentToOrder(ByVal d As document, _
ByVal o As order) As Errors
Dim myError As New Errors
Try
Threading.Thread.CurrentThread.CurrentCulture = _
New Globalization.CultureInfo(d.culture)
o.orderdate = CDate(d.orderdate)
o.deliverydate = CDate(d.deliverydate)
o.price = CDec(d.price)
o.quantity = CInt(d.quantity)
o.culture = d.culture
Return myError
Catch ex As Exception 'However whatever error set
'evaluate(myerror, ex)
Return myError
Finally
Threading.Thread.CurrentThread.CurrentCulture = _
Globalization.CultureInfo.InstalledUICulture
End Try
End Function
End Class
Public Class document
Public orderdate As String
Public deliverydate As String
Public quantity As String
Public price As String
Public culture As String
End Class
Public Class order 'Normally with properties where validation is used
Public orderdate As DateTime
Public deliverydate As DateTime
Public quantity As Integer
Public price As Decimal
Public culture As String
End Class
Public Class Errors
Public whatever As String
Public Sub New()
whatever = ""
End Sub
End Class

With what I don't say that there can be probably situations where
datetime.parseexact are simpler to use, however that in my opinion when you know exactly the format of the string(s), that will be used in the document.

Nov 21 '05 #9
Did you read that page from Microsoft where I gave the link too?

It is obvious you did not, and with that are all answers on this message
given.

Cor
Nov 21 '05 #10
Jay,
I am more then willing to help people who are actually willing to be
helped.


I have the last year nowwhere asked for your help, your knowledge is far to
few for that, there was a time I missed VBNet knowledge, however I have not
the idea I mis not much from that as well anymore at the moment.

This were answers on flames from you where you consequently are telling that
I am a beginner. I am sure that I am longer in this business as you, however
not only as programmer but in almost every dicipline of it.

I have seen replys from others on your answers as well in this trend, it
would be good when you would read them and think once about them.

Cor
Nov 21 '05 #11
"Cor Ligthert" <no************@planet.nl> schrieb:
Did you read that page from Microsoft where I gave the link too?

It is obvious you did not, and with that are all answers on this
message given.


I'm now leaving this discussion...

--
Herfried K. Wagner [MVP]
<URL:http://dotnet.mvps.org/>
Nov 21 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Fred Strauss | last post: by
3 posts views Thread by Dave P. | last post: by
1 post views Thread by Pablo | last post: by
1 post views Thread by Erica | last post: by
3 posts views Thread by Peter Duniho | last post: by
11 posts views Thread by Peter Holschbach | last post: by
1 post views Thread by =?Utf-8?B?RGFwcGVyRGFuSEBub3NwYW0ubm9zcGFt?= | last post: by
5 posts views Thread by John B | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by Marin | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.