I have already seen this.
I am going to get only Date from a DateTime variable and in this way I used this code:
DateTime Start = GetaDateTime();
String Day = Start.ToString("yyyy/MM/dd");
DateTime d = Convert.ToDateTime(Day);
But when I use d.Date it gives me '2014-08-23 12:00 AM'
Actually I should not get 12:00AM any more????
Actually I should not get 12:00AM any more????
Why not? A DateTime has no notion of whether it's meant to be a date or a date and time, or any sort of string formatting. It's just a point in time (and not even quite that, given the odd Kind part of it).
Note that a simpler way of getting a DateTime which is the same as another but at midnight is just to use Date to start with:
DateTime start = Foo();
DateTime date = start.Date;
No need for formatting and then parsing.
There's no .NET type representing just a date. For that, you'll want something like my Noda Time project, which has a rather richer set of date/time types to play with.
Related
I have following date time format
TimeZoneDetails.TimeZoneInstance ="Australia/Perth"
DateTime Today = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow,TimeZoneDetails.TimeZoneInstance);
Does today variable store the date based on timezone?
string date = "2020-03-19";
DateTime startdate = DateTime.Parse(date);
What is the timezone of startdate variable?
DateTime enddate = TimeZoneInfo.ConvertTimeToUtc(startdate, TimeZoneDetails.TimeZoneInstance);
Will enddate variable converted to UTC time?
A few things:
"Australia/Perth" is an IANA time zone identifier. It will work with .NET on Linux or Mac OSX, but on Windows you'd have to use "W. Australia Standard Time" instead. Alternatively, you could use my TimeZoneConverter library to work with either form of identifier on any platform.
In your code:
TimeZoneDetails.TimeZoneInstance ="Australia/Perth"
This isn't generally valid. Given the usage in the rest of your code, your TimeZoneInstance would have to be a TimeZoneInfo object. You can't assign a string in that way. You'd have to use a function like TimeZoneInfo.FindSystemTimeZoneById, or TZConvert.GetTimeZoneInfo from TimeZoneConverter, or a similar function in your own code. (Also you're missing a semicolon.)
In your code:
string date = "2020-03-19";
DateTime startdate = DateTime.Parse(date);
You asked what the time zone is in the startdate variable. That's a DateTime, which does not store time zone or offset information. It only has a .Kind property, which is of type DateTimeKind. In your example, it will be DateTimeKind.Unspecified. Also note the time will be set to 00:00:00.0000000.
You can read more about this in the documentation, here and here.
In your code:
DateTime enddate = TimeZoneInfo.ConvertTimeToUtc(startdate, TimeZoneDetails.TimeZoneInstance);
Yes, that will correctly convert the DateTime from the time zone given to UTC. Because startdate.Kind == DateTimeKind.Unspecified, the value is treated as belonging to the time zone specified. The resulting value will have enddate.Kind == DateTimeKind.Utc.
You can read more in the documentation, here.
In comments you asked:
which one is default for DateTimeKind?
That depends on which method you call to create the DateTime, and what values you pass in. In your case, because you call DateTime.Parse and pass a string that contains no time zone offset information, the resulting value has .Kind == DateTimeKind.Unspecified. You can read more about the behavior of DateTime.Parse in the remarks section here. Other methods and constructors behave similarly, but you should check the documentation for each, or validate the results yourself. You may find conversion errors if you, for example, think a DateTime has Unspecified kind, but it actually has Local kind due to how you obtain it.
I've been racking my brain all afternoon trying to figure this one out. Essentially, the problem itself seems simple. I'm given a date/time that is representative of a date and time in another time zone (not local). I want to convert this value to a UTC value to store in the database. However, all of the methods I find online seem to point to you either starting with UTC or starting with a local time zone. You can convert TO other time zones from these, but you can't start with anything other than those. As a result, it appears that I'll have to do some kind of convoluted offset math to do what I want. Here is an example of the problem:
var dateString = "8/20/2014 6:00:00 AM";
DateTime date1 = DateTime.Parse(dateString,
System.Globalization.CultureInfo.InvariantCulture);
var currentTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
// Now the server is set to Central Standard Time, so any automated offset calculation that it runs will come from that point of view:
var utcDate = date1.ToUniversalTime; // This is wrong
// Similarly, if I try to reverse-calculate it, it doesn't work either
var convertedDate = TimeZoneInfo.ConvertTime(date1, currentTimeZone);
utcDate = convertedDate.ToUniversalTime; // This is also wrong
In essence, I want to somehow tell the system that the datetime object I'm currently working with is from that time zone other than local, so that I know the conversion will be correct. I know that I'll eventually need to figure Daylight Savings Time in there, but that is a problem for another day.
Would this method be of any use to you ?
The TimeZoneInfo.ConvertTime method converts a time from one time zone
to another.
Alternatively, you could use the ConvertTimeToUtc method to simply convert any date (specifying the source time zone) to UTC.
var dateString = "8/20/2014 6:00:00 AM";
DateTime date1 = DateTime.Parse(dateString,
System.Globalization.CultureInfo.InvariantCulture);
var currentTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
var utcDate = TimeZoneInfo.ConvertTimeToUtc(date1, currentTimeZone);
The System.DateTime struct only has two bits for storing the "kind" information. That is why you can only have "local" or "universal" or "unknown" (or "magicl local").
Take a look at the System.DateTimeOffset struct. It is like a DateTime, but it also keeps the time zone (offset from (plus or minus) UTC).
Sorry if this seems as a stupid question, but I cannot find an answer anywhere and I am a bit of a newbie. DateTime shows to be what I surmised as the Min Date. For instance:
DateTime updatedDate = new DateTime();
outItem.AddDate = updatedDate.ToLongDateString();
The output comes out to January 01, 0001. I've tried many variations of this with similar results. What am I doing wrong?
It depends on what you mean by "wrong". new DateTime() does indeed have the same value as DateTime.MinValue. If you want the current time, you should use:
DateTime updatedDate = DateTime.Now;
or
DateTime updatedDate = DateTime.UtcNow;
(The first gives you the local time, the second gives you the universal time. DateTime is somewhat messed up when it comes to the local/universal divide.)
If you're looking to get the current date, use DateTime.Now. You're creating a new instance of the date class, and the min value is its default value.
DateTime updatedDate = DateTime.Now;
outItem.AddDate = updatedDate.ToLongDateString();
EDIT: Actually, you can shorten your code by just doing this:
outItem.AddDate = DateTime.Now.ToLongDateString();
Jon Skeet says correct, and I have some to add.
The "wrong" depends on what time you want to get.
The DateTime is a struct, and the the default contructor of a struct
always initializes all fields to their zero for numeric type and null
for reference type.
so if you want to get the current local date and time, you can call static property DateTime.Now.
var curDateTime = DateTime.Now;
if you want to get UTC time.
var utcDateTime = DateTime.UtcNow;
Note: the DateTime.UtcNow get the current date and time, but instead of using local time zone, it uses UTC time instead.
You can reference the link as below.
http://blackrabbitcoder.net/archive/2010/11/18/c.net-little-wonders-datetime-is-packed-with-goodies.aspx
Can anyone explain the difference between System.DateTime.Now and System.DateTime.Today in C#.NET? Pros and cons of each if possible.
DateTime.Now returns a DateTime value that consists of the local date and time of the computer where the code is running. It has DateTimeKind.Local assigned to its Kind property. It is equivalent to calling any of the following:
DateTime.UtcNow.ToLocalTime()
DateTimeOffset.UtcNow.LocalDateTime
DateTimeOffset.Now.LocalDateTime
TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Local)
TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.Local)
DateTime.Today returns a DateTime value that has the same year, month, and day components as any of the above expressions, but with the time components set to zero. It also has DateTimeKind.Local in its Kind property. It is equivalent to any of the following:
DateTime.Now.Date
DateTime.UtcNow.ToLocalTime().Date
DateTimeOffset.UtcNow.LocalDateTime.Date
DateTimeOffset.Now.LocalDateTime.Date
TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Local).Date
TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.Local).Date
Note that internally, the system clock is in terms of UTC, so when you call DateTime.Now it first gets the UTC time (via the GetSystemTimeAsFileTime function in the Win32 API) and then it converts the value to the local time zone. (Therefore DateTime.Now.ToUniversalTime() is more expensive than DateTime.UtcNow.)
Also note that DateTimeOffset.Now.DateTime will have similar values to DateTime.Now, but it will have DateTimeKind.Unspecified rather than DateTimeKind.Local - which could lead to other errors depending on what you do with it.
So, the simple answer is that DateTime.Today is equivalent to DateTime.Now.Date.
But IMHO - You shouldn't use either one of these, or any of the above equivalents.
When you ask for DateTime.Now, you are asking for the value of the local calendar clock of the computer that the code is running on. But what you get back does not have any information about that clock! The best that you get is that DateTime.Now.Kind == DateTimeKind.Local. But whose local is it? That information gets lost as soon as you do anything with the value, such as store it in a database, display it on screen, or transmit it using a web service.
If your local time zone follows any daylight savings rules, you do not get that information back from DateTime.Now. In ambiguous times, such as during a "fall-back" transition, you won't know which of the two possible moments correspond to the value you retrieved with DateTime.Now. For example, say your system time zone is set to Mountain Time (US & Canada) and you ask for DateTime.Now in the early hours of November 3rd, 2013. What does the result 2013-11-03 01:00:00 mean? There are two moments of instantaneous time represented by this same calendar datetime. If I were to send this value to someone else, they would have no idea which one I meant. Especially if they are in a time zone where the rules are different.
The best thing you could do would be to use DateTimeOffset instead:
// This will always be unambiguous.
DateTimeOffset now = DateTimeOffset.Now;
Now for the same scenario I described above, I get the value 2013-11-03 01:00:00 -0600 before the transition, or 2013-11-03 01:00:00 -0700 after the transition. Anyone looking at these values can tell what I meant.
I wrote a blog post on this very subject. Please read - The Case Against DateTime.Now.
Also, there are some places in this world (such as Brazil) where the "spring-forward" transition happens exactly at Midnight. The clocks go from 23:59 to 01:00. This means that the value you get for DateTime.Today on that date, does not exist! Even if you use DateTimeOffset.Now.Date, you are getting the same result, and you still have this problem. It is because traditionally, there has been no such thing as a Date object in .Net. So regardless of how you obtain the value, once you strip off the time - you have to remember that it doesn't really represent "midnight", even though that's the value you're working with.
If you really want a fully correct solution to this problem, the best approach is to use NodaTime. The LocalDate class properly represents a date without a time. You can get the current date for any time zone, including the local system time zone:
using NodaTime;
...
Instant now = SystemClock.Instance.Now;
DateTimeZone zone1 = DateTimeZoneProviders.Tzdb.GetSystemDefault();
LocalDate todayInTheSystemZone = now.InZone(zone1).Date;
DateTimeZone zone2 = DateTimeZoneProviders.Tzdb["America/New_York"];
LocalDate todayInTheOtherZone = now.InZone(zone2).Date;
If you don't want to use Noda Time, there is now another option. I've contributed an implementation of a date-only object to the .Net CoreFX Lab project. You can find the System.Time package object in their MyGet feed. Once added to your project, you will find you can do any of the following:
using System;
...
Date localDate = Date.Today;
Date utcDate = Date.UtcToday;
Date tzSpecificDate = Date.TodayInTimeZone(anyTimeZoneInfoObject);
Time. .Now includes the 09:23:12 or whatever; .Today is the date-part only (at 00:00:00 on that day).
So use .Now if you want to include the time, and .Today if you just want the date!
.Today is essentially the same as .Now.Date
The DateTime.Now property returns the current date and time, for example 2011-07-01 10:09.45310.
The DateTime.Today property returns the current date with the time compnents set to zero, for example 2011-07-01 00:00.00000.
The DateTime.Today property actually is implemented to return DateTime.Now.Date:
public static DateTime Today {
get {
DateTime now = DateTime.Now;
return now.Date;
}
}
DateTime.Today represents the current system date with the time part set to 00:00:00
and
DateTime.Now represents the current system date and time
I thought of Adding these links -
A brief History of DateTime - By Anthony Moore by BCL team
Choosing between Datetime and DateTime Offset - by MSDN
Do not forget SQL server 2008 onwards has a new Datatype as DateTimeOffset
The .NET Framework includes the DateTime, DateTimeOffset, and
TimeZoneInfo types, all of which can be used to build applications
that work with dates and times.
Performing Arithmetic Operations with Dates and Times-MSDN
Coming back to original question , Using Reflector i have explained the difference in code
public static DateTime Today
{
get
{
return DateTime.Now.Date; // It returns the date part of Now
//Date Property
// returns same date as this instance, and the time value set to 12:00:00 midnight (00:00:00)
}
}
private const long TicksPerMillisecond = 10000L;
private const long TicksPerDay = 864000000000L;
private const int MillisPerDay = 86400000;
public DateTime Date
{
get
{
long internalTicks = this.InternalTicks; // Date this instance is converted to Ticks
return new DateTime((ulong) (internalTicks - internalTicks % 864000000000L) | this.InternalKind);
// Modulo of TicksPerDay is subtracted - which brings the time to Midnight time
}
}
public static DateTime Now
{
get
{
/* this is why I guess Jon Skeet is recommending to use UtcNow as you can see in one of the above comment*/
DateTime utcNow = DateTime.UtcNow;
/* After this i guess it is Timezone conversion */
bool isAmbiguousLocalDst = false;
long ticks1 = TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(utcNow, out isAmbiguousLocalDst).Ticks;
long ticks2 = utcNow.Ticks + ticks1;
if (ticks2 > 3155378975999999999L)
return new DateTime(3155378975999999999L, DateTimeKind.Local);
if (ticks2 < 0L)
return new DateTime(0L, DateTimeKind.Local);
else
return new DateTime(ticks2, DateTimeKind.Local, isAmbiguousLocalDst);
}
}
DateTime dt = new DateTime();// gives 01/01/0001 12:00:00 AM
DateTime dt = DateTime.Now;// gives today date with current time
DateTime dt = DateTime.Today;// gives today date and 12:00:00 AM time
DateTime.Today is DateTime.Now with time set to zero.
It is important to note that there is a difference between a DateTime value, which represents the number of ticks that have elapsed since midnight of January 1, 0000, and the string representation of that DateTime value, which expresses a date and time value in a culture-specific-specific format:
https://msdn.microsoft.com/en-us/library/system.datetime.now%28v=vs.110%29.aspx
DateTime.Now.Ticks is the actual time stored by .net (essentially UTC time), the rest are just representations (which are important for display purposes).
If the Kind property is DateTimeKind.Local it implicitly includes the time zone information of the local computer. When sending over a .net web service, DateTime values are by default serialized with time zone information included, e.g. 2008-10-31T15:07:38.6875000-05:00, and a computer in another time zone can still exactly know what time is being referred to.
So, using DateTime.Now and DateTime.Today is perfectly OK.
You usually start running into trouble when you begin confusing the string representation with the actual value and try to "fix" the DateTime, when it isn't broken.
DateTime.Now.ToShortDateString() will display only the date part
In C# if I want to parse a datetime, but some times I just have either a date and not a time component or no date but a time component, how would I do this? Usually when you leave out the time component, it automatically assumes that the time is 12:00AM. But I don't want this. If the time component is missing then I just want the DateTime to store a date only and the leave the time component off.
The value of a DateTime internally is just an UInt64 (ulong in C#) that stores the number of ticks since some date in the past, so whether you like it or not, the time component will always be there.
If you only need to display certain parts, just use any of the format strings (examples are for "en-us" culture):
DateTime.Now.ToString("d"); // 5/26/2009
DateTime.Now.ToString("t"); // 4:56 PM
The complete reference: http://msdn.microsoft.com/en-us/library/az4se3k1.aspx
It's not possible to have a DateTime without a time component. You could store a boolean flag along with it in a struct to store data about existence of that component. However, there's no way to use the automatic parsing routine to distinguish between a DateTime string with a time specified as 12:00 PM and a nonexistent one.
If it really bugs you you can always create a wrapper class that can hide the time portions of the datetime class.
No you will have the time component no matter what. The best you can do is access the Date property on your DateTime object if you really have to.
http://msdn.microsoft.com/en-us/library/system.datetime.date.aspx
DateTime by definition stores a date and a time such that it cannot just represent one of them without representing the other. If you only want the date (or only the time), parse out the information you need and discard the rest of it.
As mentioned before DateTime will always have a Date and a Time part of it if you only want a single part use the way described by the others
DateTime date = DateTime.Parse("2009-11-30);
date.Year; = 2009
date.Month; = 11
date.Day; = 30
date.Hour; = 0
and so on
The thing you must be aware is that all of these methods will only return an integer.
If you want to know all the possible ways to parse a string John Sheehan has put together a great Cheat Sheet wit all possible ways to parse and manipulate dates, and other strings for that matter.
You could have a class that stores a DateTime and determines if the time was ever set or if just the date was set and return values accordingly.
Use
DateTime date = new DateTime();
date = DateTime.Parse("1/1/2001");
to set the date, then use
date.ToShortDateString();
or
date.Year;
date.Month;
date.Day;
to get what you need. Hope that helps!
A DateTime object is always stores a date + a time, not just one. You can always choose to work only with the date part, i.e. only use properties like Year, Month, DayOfWeek. But underneath there will aways be some stored time.
It is very dangerous to assume that the date portion of a DateTime is necessarily the date you are expecting. As pointed-out, DateTime always includes and considers the time aspect, even when you don't see it.
This is a big problem when you have data stored in different time-zones (and particularly if knowledge of that offset is not also kept, because it is assumed that what is being stored is a Date, not a date-with-time).
You may store a birthdate as '01/01/2000 00:00:00' during Summer-Time, which then is stored in UCT as '31/12/1999 23:00:00'. When you then read that birth-date later, the date portion is now a day early.
Best to create your own type. Strange that Microsoft didn't think it worth having a Date type.