Hi,
Follow some best practices
Best Practice #1
When coding, store the time-zone information associated with a DateTime type in an adjunct variable.
An
alternative, but less reliable, strategy is to make a steadfast rule
that your stored dates will always be converted to a particular
time-zone, such as GMT, prior to storage. This may seem sensible, and
many teams can make it work. However, the lack of an overt signal that
says that a particular DateTime column in a table in a database is in a
specific time zone invariably leads to mistakes in interpretation in
later iterations of a project.
A common strategy seen in an
informal survey of different .NET-based applications is the desire to
always have dates represented in universal (GMT) time. I say "desire"
because this is not always practical. A case in point arises when
serializing a class that has a DateTime member variable via a Web
service. The reason is that a DateTime value type maps to a XSD:DateTime
type (as one would expect), and the XSD type accommodates representing
points in time in any time zone. We'll discuss the XML case later. More
interestingly, a good percentage of these projects weren't actually
achieving their goal, and were storing the date information in the
server time zone without realizing it.
In these cases, an
interesting fact is that the testers weren't seeing time conversion
issues, so nobody had noticed that the code that was supposed to convert
the local date information to UCT time was failing. In these specific
cases, the data was later serialized via XML and was converted properly
because the date information was in machine local time to start with.
Let's look at some code that doesn't work:
Dim d As DateTime
d = DateTime.Parse("Dec 03, 2003 12:00:00 PM") 'date assignment
d.ToUniversalTime()
The program above takes the value in variable d and saves it to a database, expecting the stored value to represent a UCT view of time. This example recognizes that the Parse
method renders the result in local time unless some non-default culture
is used as an optional argument to the Parse family of methods.
The previously shown code actually fails to convert the value in the DateTime variable d to universal time in the third line because, as written, the sample violates http://msdn.microsoft.com/en-us/library/ms973825.aspx#datetime_rules
(the methods on the DateTime class do not convert the underlying
value). Note: this code was seen in an actual application that had been
tested.
How did it pass? The applications involved were able to
successfully compare the stored dates because, during testing, all of
the data was coming from machines set to the same time-zone, so http://msdn.microsoft.com/en-us/library/ms973825.aspx#datetime_rules
was satisfied (all dates being compared and calculated are localized to
the same time-zone point of view). The bug in this code is the kind
that is hard to spot—a statement that executes but that doesn't do
anything (hint: the last statement in the example is a no-op as
written).
Best Practice #2
When testing, check to see that stored values represent the point-in-time value you intend in the time zone you intend.
Fixing the code sample is easy:
Dim d As DateTime
d = DateTime.Parse("Dec 03, 2003 12:00:00 PM").ToUniversalTime()
Since the calculation methods associated with the DateTime
value type never impact the underlying value, but instead return the
result of the calculation, a program must remember to store the
converted value (if this is desired, of course). Next we'll examine how
even this seemingly proper calculation can fail to achieve the expected
results in certain circumstances involving daylight savings time.
Performing Calculations
On
first glance, the calculation functions that come with the
System.DateTime class are really useful. Support is provided for adding
intervals to time values, performing arithmetic on time values, and even
converting .NET time values to the corresponding value-type appropriate
for Win32® API calls, as well as OLE Automation calls. A look at the
support methods that surround the DateTime type evokes a nostalgic look
back at the different ways that MS-DOS® and Windows® have evolved for
dealing with time and timestamps over the years.
The fact that
all of these components are still present in various parts of the
operating system is related to the backwards-compatibility requirements
that Microsoft maintains. To a programmer, this means that if you are
moving data representing timestamps on files, directories, or doing
COM/OLE Interop involving date and DateTime values, you'll have to
become proficient at dealing with conversions between the different
generations of time that are present in Windows.
Don't Get Fooled Again
Let's
suppose you have adopted the "we store everything in UCT time"
strategy, presumably to avoid the overhead of having to store a time
zone offset (and perhaps a user-eyed view of time zone, such as Pacific
Standard Time, or PST). There are several advantages to performing
calculations using UCT time. Chief among them is the fact that when
represented in universal time, every day has a fixed length, and there
are no time-zone offsets to deal with.
If you were surprised
reading that a day can have different lengths, be aware that in any time
zone that allows for daylight savings time, on two days of the year
(typically), days have a different length. So even if you are using a
local time value, such as Pacific Standard Time (PST), if you try and
add a span of time to a specific DateTime instance value, you may not
get the result you thought you should if the interval being added takes
you past the change-over time on a date that daylight savings time
either starts or ends.
Let's look at an example of code that doesn't work in the Pacific Time zone in the United States:
Dim d As DateTime
d = DateTime.Parse("Oct 26, 2003 12:00:00 AM") 'date assignment
d = d.AddHours(3.0)
' - displays 10/26/2003 03:00:00 AM – an ERROR!
MsgBox(d.ToString)
The result that is displayed from this calculation may seem
correct on first glance; however, on October 26, 2003, one minute after
1:59 AM PST, the daylight savings time change took effect. The correct
answer should have been 10/26/2003, 02:00:00 AM, so this calculation
based on a local time value failed to yield the correct result. But if
we look back at http://msdn.microsoft.com/en-us/library/ms973825.aspx#datetime_rules, we seem to have a contradiction, but we don't. Let's just call it a special case for using the Add/Subtract methods in time zones that celebrate daylight savings time.
Best Practice #3
When
coding, be careful if you need to perform DateTime calculations
(add/subtract) on values representing time zones that practice daylight
savings time. Unexpected calculation errors can result. Instead, convert
the local time value to universal time, perform the calculation, and
convert back to achieve maximum accuracy.
Fixing this broken code is straightforward:
Dim d As DateTime
d = DateTime.Parse("Oct 26, 2003 12:00:00 AM") 'date assignment
d = d.ToUniversalTime().AddHours(3.0).ToLocalTime()
' - displays 10/26/2003 02:00:00 AM – Correct!
MsgBox(d.ToString)
The easiest way to reliably add spans of time is to convert
local-time-based values to universal time, perform the calculations, and
then convert the values back.
Sorting Out DateTime Methods
Throughout
this article, different System.DateTime class methods are discussed.
Some yield a correct result when the underlying instance represents
local time, some when they represent Universal time, and others still
require no underlying instance at all. Further, some are completely
agnostic to time zone (e.g., AddYear, AddMonth). To
simplify the overall understanding of the assumptions behind the most
commonly encountered DateTime support methods, the following table is
provided.
To read the table, consider the starting (input) and
ending (returned value) viewpoint. In all cases, the end state of
calling a method is returned by the method. No conversion is made to the
underlying instance of data. Caveats that describe exceptions or useful
guidance are also provided.
| Method Name |
Starting Viewpoint |
Ending Viewpoint |
Caveats |
| ToUniversalTime |
Local Time |
UTC |
Do not call on a DateTime instance that already represents Universal Time |
| ToLocalTime |
UTC |
Local Time |
Do not call on an DateTime instance that already represents local time |
| ToFileTime |
Local Time |
|
Method returns an INT64 that represents Win32 file time (UCT time) |
| FromFileTime |
|
Local Time |
Static method—no instance required. Takes a INT64 UCT time as input |
| ToFileTimeUtc
(V1.1 only)
|
UTC |
|
Method returns a INT64 that represents a Win32 file time (UCT time) |
| FromFileTimeUtc
(V1.1 only)
|
|
UTC |
Method converts INT64 Win32 file time to a DateTime UCT instance |
| Now |
|
Local Time |
Static method—no instance required. Returns a DateTime that represents the current time in Local machine time |
| UtcNow |
|
UTC |
Static method—no instance required |
| IsLeapYear |
Local Time |
|
Returns Boolean that indicates true if year portion of the local time instance is a leap year. |
| Today |
|
Local Time |
Static method—no instance required. Returns a DateTime set to Midnight of the current day in local machine time. |
The Special Case of XML
Several
people I've talked to recently had the design goal of serializing time
values over Web services such that the XML that represents the DateTime
would be formatted in GMT (e.g., with a zero offset). While I've heard
various reasons ranging from the desire to simply parse the field as a
text string for display in a client to wanting to preserve the "stored
in UCT" assumptions that exist on the server to the callers of Web
services, I've not been convinced that there is ever a good reason to
control the marshalling format on the wire to this degree. Why? Simply
because the XML encoding for a DateTime type is perfectly adequate for
representing an instant in time, and the XML serializer that is built
into the .NET Framework does a fine job of managing the serialization
and deserialization issues associated with time values.
Further,
it turns out that forcing the System.XML.Serialization serializer to
encode a date value in GMT on the wire is not possible in .NET, at least
not today. As a programmer, designer, or project manager, your job then
becomes making sure that the data that is being passed in your
application is performed accurately with a minimum of cost.
Several
of the groups I talked with in the research that went into this paper
had adopted the strategy of defining special classes and writing their
own XML serializers so that they have full control over what the
DateTime values on the wire looked like in their XML. While I admire the
pluck that developers have when making the leap into this brave
undertaking, rest assured that the nuances of dealing with daylight
savings time and time zone conversion issues alone should make a good
manager say, "No way," especially when the mechanisms provided in the
.NET Framework do a perfectly accurate job of serializing time values
already.
There is only one trick you have to be aware of, and as a designer you MUST understand this and adhere to the rule (see http://msdn.microsoft.com/en-us/library/ms973825.aspx#datetime_rules).
Code that doesn't work:
Let's
first define a simple XML class with a DateTime member variable. For
completeness, this class is the simplified equivalent of the recommended
approach illustrated later in the article.
<XmlType(TypeName:="timeTestDef", _
Namespace:= "http://tempuri.org/Timetester.xsd")>), _
XmlRoot(), Serializable()> _
Public Class timeTestDef
Private __timeVal As DateTime
<XmlIgnore()> _
Public timeValSpecified As Boolean
<XmlElement(ElementName:="timeVal", IsNullable:=False, _
Form:=XmlSchemaForm.Qualified, DataType:="dateTime", _
Namespace:="http://tempuri.org/Timetester.xsd")> _
Public Property timeVal() As DateTime
Get
timeVal = __timeVal
End Get
Set(ByVal Value As DateTime)
__timeVal = Value
timeValSpecified = True
End Set
End Property
End Class
Now, let's use this class to write some XML to a file.
' write out to the file
Dim t As Xml.XmlTextWriter
Dim ser As XmlSerializer
Dim tt As New timeTest ' a class that has a DateTime variable
' set the fields in your class
tt.timeVal = DateTime.Parse("12/12/2003 12:01:02 PM")
tt.timeVal = tt.TimeVal.ToUniversalTime()
' get a serializer for the root type, and serialize this UTC time
ser = New XmlSerializer(GetType(timeTest))
t = New Xml.XmlTextWriter("c:\timetest.xml", System.Text.Encoding.UTF8)
ser.Serialize(t, tt)
t.Close()
t = Nothing
tt = Nothing
When this code runs, the XML that is serialized to the output file contains an XML DateTime representation as follows:
<timeVal>2003-12-12T20:01:02.0000000-08:00</timeVal>
This is an error: the value encoded in the XML is off by
eight hours! Since this happens to be the time zone offset of my current
machine, we should be suspicious. Looking at the XML itself, the date
is right, and the 20:01:02 date corresponds to the clock time in London
for my own noontime, but the offset portion is not correct for a
London-based clock. When the XML looks like the London time, the offset
should also represent the London viewpoint, which this code doesn't
achieve.
The XML serializer always assumes that DateTime values
being serialized represent local machine time, so it applies the machine
local time zone offset as the offset portion of the encoded XML time.
When we deserialize this onto another machine, the original offset is
subtracted from the value being parsed, and the current machine's
time-zone offset is added.
When we start with a local time, the
result of serialization (encode to XML DateTime followed by decode to
local machine time) is always correct—but only if the starting DateTime
value being serialized represents local time when serialization begins.
In the case of this broken code example, we had already adjusted the
DateTime value in the timeVal member variable to UCT time, so
when we serialize and deserialize, the result is off by the number of
hours equal to the time-zone offset of the originating machine. This is
bad.
Best Practice #4
When
testing, calculate the value you expect to see in the XML string that
is serialized using a machine local time view of the point in time being
tested. If the XML in the serialization stream differs, log a bug!
Fixing this code is simple. Comment out the line that calls ToUniversalTime().
Best Practice #5
When
writing code to serialize classes that have DateTime member variables,
the values must represent local time. If they do not contain local time,
adjust them prior to any serialization step, including passing or
returning types that contain DateTime values in Web services.
The Class Coders Quandary
Earlier
we looked at a pretty unsophisticated class that exposed a DateTime
property. In that class, we simply serialized what we stored in a
DateTime, without regard to whether the value represented a local or
universal time viewpoint. Let's look at a more sophisticated approach
that offers programmers an overt choice as to what time-zone assumptions
they desire, while always serializing properly.
When coding a
class that will have a member variable of type DateTime, a programmer
has a choice of making the member variable public or writing the
property logic to wrap the member variable with get/set
operations. Choosing to make the type public has several disadvantages
that, in the case of DateTime types, can have consequences that are not
under the class developer's control.
Using what we learned so far, consider instead providing two properties for each DateTime type.
The following example illustrates the recommended approach to managing DateTime member variables:
<XmlType(TypeName:="timeTestDef", _
Namespace:= "http://tempuri.org/Timetester.xsd")>), _
XmlRoot(), Serializable(), _
EditorBrowsable(EditorBrowsableState.Advanced)> _
Public Class timeTestDef
Private __timeVal As DateTime
<XmlIgnore()> _
Public timeValSpecified As Boolean
<XmlElement(ElementName:="timeVal", IsNullable:=False, _
Form:=XmlSchemaForm.Qualified, DataType:="dateTime", _
Namespace:="http://tempuri.org/Timetester.xsd")> _
Public Property timeVal() As DateTime
Get
timeVal = __timeVal.ToLocalTime()
End Get
Set(ByVal Value As DateTime)
__timeVal = Value.ToUniversalTime()
timeValSpecified = True
End Set
End Property
<XmlIgnore()> _
Public Property timeValUTC() As DateTime
Get
timeValUTC = __timeVal
End Get
Set(ByVal Value As DateTime)
__timeVal = Value
timeValSpecified = True
End Set
End Property
End Class
This example is the corrected equivalent to the prior class
serialization example. In both class examples (this one and the earlier
one), the classes are implementations that are described with the
following schema:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="Timetester"
targetNamespace="http://tempuri.org/Timetester.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/Timetester.xsd"
xmlns:mstns="http://tempuri.org/Timetester.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="timeTest" type="timeTestDef"/>
<xs:complexType name="timeTestDef">
<xs:sequence>
<xs:element name="timeVal" type="xs:dateTime"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
In this schema, and in any class implementations, we define a
member variable that represents an optional time value. In our
recommended example, we have provided two properties with both getters
and setters—one for the universal time and one for local time. The
angle-bracketed attributes that you see in the code tell the XML
serializer to use the local time version for serialization, and
generally make the class implementation result in schema-compliant
output. To make the class properly deal with the optional lack of
expression when no value is set in the instance, the timeValSpecified
variable and associated logic in the property setter controls whether
the XML element is expressed at serialization time or not. This optional
behavior exploits a feature in the serialization subsystem that was
designed to support optional XML content.
Using this approach to
managing DateTime values in your .NET classes gives you the best of both
worlds—you get storage access based on universal time so that
calculations are accurate, and you get proper serialization of local
time views.
Best Practice #6
When
coding, make DateTime member variables private and provide two
properties for manipulating your DateTime members in either local or
universal time. Bias the storage in the private member as UCT time by
controlling the logic in your getters and setters. Add the XML
serialization attributes to the local time property declaration to make
sure that the local time value is what is serialized (see example).
Caveats to this approach
The
recommended approach of managing a DateTime in Universal time within
your private member variables is sound, as is the recommendation to
provide dual properties to allow coders to deal with the versions of
time that they are most comfortable with. One issue that a developer
using this or any other approach that exposes any local time to a
program continues to be the 25-hour-day issue around daylight savings
time. This will continue to be an issue for programs that use CLR
version 1.0 and 1.1, so you have to be aware as to whether your program
falls into this special case (the added or missing hour for the time
being represented), and adjust manually. For those who cannot tolerate a
one-hour per year issue window, the current recommendation is to store
your dates as strings or some other self-managed approach. (Unix long
integers are a good option.)
For CLR version 2.0 (available in
the upcoming release of Visual Studio® code-named "Whidbey"), awareness
of whether a DateTime contains a local time or a universal time value is
being added to the .NET Framework. At that point, the recommended
pattern will continue to work, but for programs that interact with
member variables via the UTC properties, these errors in the
missing/extra hour period will be eliminated. For this reason, the best
practice for coding using dual properties is strongly suggested today,
so that your programs will migrate cleanly to CLR version 2.0.
Dealing with Daylight Savings Time
As
we prepare to close and leave the topic of coding and testing practices
for DateTime values, there remains one special case that you need to
understand. This case involves the ambiguities that surround daylight
saving time and the repeated one-hour per year issue. This issue is
primarily one that only affects applications that collect time values
from user input.
For those of you in the country-count majority,
this case is trivial because in most countries daylight savings time is
not practiced. But for those of you who are in the affected programs
majority (that is, all of you who have applications that need to deal
with time that may be represented in or sourced in places that DO
practice daylight savings), you have to know this problem exists and
account for it.
In areas of the world that practice daylight
savings time, there is one hour each fall and spring where time
seemingly goes haywire. On the night that the clock time shifts from
standard time to daylight time, the time jumps ahead an hour. This
occurs in the spring. In the fall of the year, on one night, the local
time clock jumps back an hour.
On these days, you can encounter
conditions where the day is 23 or 25 hours in length. So if you are
adding or subtracting spans of time from date values and the span
crosses this strange point in time where the clocks switch, your code
needs to make a manual adjustment.
For logic that is using the DateTime.Parse()
method to calculate a DateTime value based on user input of a specific
date and time, you need to detect that certain values are not valid (on
the 23-hour day), and certain values have two meanings because a
particular hour repeats (on the 25-hour day). To do this, you need to
know the dates involved and look for these hours. It may be useful to
parse and redisplay the interpreted date information as the user exits
the fields used to enter dates. As a rule, avoid having users specify
daylight savings time in their input.
We've already covered the
best practice for time-span calculations. By converting your local time
views to universal time prior to performing your calculations, you get
past the issues of time accuracy. The harder-to-manage case is the
ambiguity case associated with parsing user input that occurs during
this magical hour in the spring and fall.
Presently there is no
way to parse a string that represents a user's view of time and have it
accurately assigned a universal time value. The reason is that people
who experience daylight savings time don't live in places where the time
zone is Greenwich Mean Time. Thus, it is entirely possible that someone
living on the east coast of the United States types in a value like
"Oct 26, 2003 01:10:00 AM".
On this particular morning, at 2:00
AM, the local clock is reset to 1:00 AM, creating a 25-hour day. Since
all values of clock time between 1:00 AM and 2:00 AM occur twice on that
particular morning—at least in most of the United states and Canada.
The computer really has no way to know which 1:10 AM was meant—the one
that occurs prior to the switch, or the one that occurs 10 minutes after
the daylight savings time switch.
Similarly, your programs have
to deal with the problem that happens in the springtime when, on a
particular morning, there is no such time as 2:10 AM. The reason is that
at 2:00 on that particular morning, the time on local clocks suddenly
changes to 3:00 AM. The entire 2:00 hour never happens on this 23-hour
day.
Your programs have to deal with these cases, possibly by
prompting the user when you detect the ambiguity. If you aren't
collecting date-time strings from users and parsing them, then you
probably don't have these issues. Programs that need to determine
whether a particular time falls in daylight savings time can make use of
the following:
Timezone.CurrentTimeZone.IsDaylightSavingTime(DateTimeInstance)
or
DateTimeInstance.IsDaylightSavingTime
Best Practice #7
When
testing, if your programs accept user input specifying date and time
values, be sure to test for data loss on "spring-ahead", "fall-back" 23-
and 25-hour days. Also make sure to test for dates gathered on a
machine in one time zone and stored on a machine in another time zone.
Formatting and Parsing User-Ready Values
For
programs that do take date and time information from users and need to
convert this user input into DateTime values, the Framework provides
support for parsing strings that are formatted in specific ways. In
general, the DateTime.Parse and ParseExact methods are useful for converting strings that contain dates and times into DateTime values. Conversely, the methods ToString, ToLongDateString, ToLongTimeString, ToShortDateString, and ToShortTimeString are all useful for rendering DateTime values into human-readable strings.
Two main issues that affect parsing are culture and format string. The http://www.gotdotnet.com/team/clr/bcl/TechArticles/techarticles/datetimefaq.doc covers the basic issues around culture, so here we'll focus on the format string best practices that affect DateTime parsing.
The recommended format strings for converting DateTime to strings are:
'yyyy'-'MM'-'dd'T'HH': 'mm': 'ss.fffffff'Z' —For UCT values
'yyyy'-'MM'-'dd'T'HH': 'mm': 'ss.fffffff'zzz' —For local values
'yyyy'-'MM'-'dd'T'HH': 'mm': 'ss.fffffff' —For abstract time values
These are the format string values that would be passed to the DateTime.ToString
method if you want to get output that is compatible with the XML
DateTime type specification. The quotes insure that the local date-time
settings on the machine don't override your formatting options. If you
need to specify different layouts, you can pass other format strings for
a fairly flexible date rendering capability, but you need to be careful
to only use the Z notation to render strings from UCT values, and use the zzz notation for local time values.
Parsing
strings and converting them to DateTime values can be accomplished with
the DateTime.Parse and ParseExact methods. For most of us, Parse is
sufficient since ParseExact requires you to provide your own Formatter object instance. Parse is pretty capable and flexible, and can accurately convert most strings that contain dates and times.
Finally, it is important to always call the Parse and ToString methods only after setting the thread's CultureInfo to CultureInfo.InvariantCulture.
Future Consideration
One
thing you can't do easily at present with DateTime.ToString is format a
DateTime value into an arbitrary time zone. This feature is being
considered for future implementations of the .NET Framework. If you need
to be able to determine that the string "12:00:00 EST" is equivalent to
"11:00:00 EDT", you will have to handle the conversion and comparison
yourself.
Issues with the DateTime.Now() Method
There are several issues when dealing with the method named Now. For the Visual Basic developers reading this, this applies to the Visual Basic Now
function, as well. Developers who regularly use the Now method know
that it is commonly used to get the current time. The value returned by
the Now method is in the current machine time-zone context, and cannot
be treated as an immutable value. A common practice is to convert times
that are going to be stored or sent between machines into Universal
(UCT) time.
When daylight savings time is a possibility, there is
one coding practice that you should avoid. Consider the following code
that can introduce a hard-to-detect bug:
Dim timeval As DateTime
timeval = DateTime.Now().ToUniversalTime()
The value that results from running this code will be off by
an hour if called during the extra hour that occurs during the daylight
savings time switch in the fall. (This only applies to machines that are
in time-zones that practice daylight savings time.) Because the extra
hour falls into that place where the same value, such as 1:10:00 AM,
occurs twice on that morning, the value returned may not match the value
you wanted.
To fix this, a best practice is to call DateTime.UtcNow() instead of calling DateTime.Now, and then converting to universal time.
Dim timeval As DateTime
timeval = DateTime.UtcNow()
This code will always have the proper 24-hour-day perspective, and may then be safely converted to local time.
Best Practice #8
When
you are coding and desire to store current time represented as
universal time, avoid calling DateTime.Now() followed by a conversion to
universal time. Instead, call the DateTime.UtcNow function directly.
Caveat:
If you are going to serialize a class that contains a DateTime value,
be sure that the value being serialized does not represent Universal
time. XML serialization will not support UCT serialization until the
Whidbey release of Visual Studio.
A Couple of Little Known Extras
Sometimes
when you start diving into a part of an API you find a hidden
gem—something that helps you achieve a goal, but which, if you aren't
told about it, you don't uncover in your day-to-day travels. The
DateTime value type in .NET has several such gems that may help you
achieve more consistent use of universal time.
The first is the DateTimeStyles enumeration that is found in the System.Globalization
namespace. The enumeration controls behaviors of the DateTime.Parse()
and ParseExact functions that are used to convert user-specified input
and other forms of input string representations to DateTime values.
The following table highlights some of the features that the DateTimeStyles enumeration enables.
| Enumeration Constant |
Purpose |
Caveats |
| AdjustToUniversal |
When passed as a part of a Parse or ParseExact method, this flag causes the value returned to be universal time. |
Documentation is ambiguous, but this works with both Parse and ParseExact. |
| NoCurrentDateDefault |
Suppresses
the assumption that strings being parsed with no date components will
have a DateTime value returned that is the time on the current date. |
If this option is used, the DateTime value returned is the time specified on the Gregorian date January 1 in the year 1. |
| AllowWhiteSpaces
AllowTrailingWhite
AllowLeadingWhite
AllowInnerWhite
|
These
options all enable tolerance for added white spaces in front of,
behind, and in the middle of the date strings being parsed. |
None |
Other interesting support functions are found in the System.Timezone
class. Be sure to check those out if you want to detect whether
daylight savings time will affect a DateTime value, or if you want to
programmatically determine the current time zone offset for the local
machine.
this may also help u
http://
http://
http://