I've created an array of DateTime objects. However when doing so by default the array has the time portion attacthed. I need to this removed to compare to another date which is simply in the "dd/MM/yyyy" format.
Creating the array:
DateTime[] exclusionDates = new DateTime[] { new DateTime(2017, 1, 1) };
I'm trying to compare that with
monthlyCalendar.SelectionEnd.Date == excluHarry[0].Date
How do I remove the time portion to the element of the array?
Thanks.
You are already excluding the time portion when you use the .Date on the DateTime object.
Also, a DateTime object has no format, it only gets a format when you call .ToString() on it, your monthlyCalendar object calls .ToString("dd/MM/yyyy") internally before displaying it to the user, that is the only reason you see it in that form from the user's perspective.
.Date from a DateTime object will get you what you looking for without having to got to string conversion. I have attached example code with two DateTime objects with same date but with different times. The if statement compares only the date portion. Please do accept the answer that helped you the most. Welcome to stack overflow
using System;
namespace DateObject
{
class Program
{
static void Main(string[] args)
{
DateTime[] exDates = new DateTime[] {new DateTime(2017, 1, 1)};
var dt = exDates[0].Date;
//new date with a different time
DateTime t = new DateTime(2017, 1, 1, 5, 30, 23);
//compare the two for date part only --exclude the time in the comparision
if (dt.Equals(t.Date))
{
Console.WriteLine("Dates are the same without comparing the time");
}
}
}
}
Related
I have time input data as below:
1536271200
1536184800
1536098400
1536012000
1535925600
I made quick Unix TimeConverter:
public static DateTime Converter(double ts)
{
DateTime org= new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
org = org.AddSeconds(ts);
org = org.ToLocalTime();
return org;
}
but after convert it return me date as below:
2018-09-10 00:00:00
2018-09-07 00:00:00
2018-09-06 00:00:00
2018-09-05 00:00:00
2018-09-04 00:00:00
2018-09-03 00:00:00
How to get shortDateFormat (YYYY-MM-DD)?
You can use .ToString(format) to get what ever format you want, and in this case it would be .ToString("yyyy-MM-dd"):
public static string Converter(double ts)
{
DateTime org= new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
org = org.AddSeconds(ts);
org = org.ToLocalTime();
return org.ToString("yyyy-MM-dd");
}
and of course the function's return type must be string.
You're getting confused between a DateTime object, and a "text string that looks like a date"
Your DateTime object holds the instant in time that the date is. You can make it into a text string that looks like whatever you want by using .ToString() and a format string:
https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings
https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings
Or you can use one of the provided shortcut methods for standard format strings, like .ToShortDateString()
https://learn.microsoft.com/en-us/dotnet/api/system.datetime?view=netframework-4.7.2
Ultimately, what you need to appreciate is that you're complaining "my date has a time tacked on the end" -> datetimes always have a time component. There is no date in this world, your birthday, your grad day, new year's day etc that does NOT have a time associated with it.
Everything happens at a time, on a date.
When you told your program to print those dates out to the console, it included the times (all midnight) because that's what your system does by default. If you want to print them out without the times, specify a format that doesn't include time placeholders.. It is in the process of preparing data for display, that we choose what we want to see
I just cannot figure this out....Damnit! Please see the calling method in the second code snippet. You'll see a commented out line that reads //_time = time.ToUTCString(); Go to the first code snippet to see the method ToUTCString(). You can see that it takes the datetime, converts it to Universal Time and subtracts the UnixEpoch to get the TotalSeconds. Then it converts that value to Int64() and finally to a string. I tried calling the methos ToLocalString but that's changing the date as well.
The date that I pass in is the date that I want to be converted to Int64 and eventually to a string. The datetime I pass in. Not changed.
I don't want to change the date that is passed in. I always pass in the date starting with 12:00:00AM (or 00:00:00) and that is the time I always want. Both of these methods change the date and or time. The date I pass in is 06/01/2017 12:00:00AM but sometimes it gets changed to 05/31/2017 04:00:00 or it keeps the date but the time is wrong. Dark Sky requires the date to be a value of Convert.ToInt64(milliseconds) and then converted to a string.
Does anybody know how to get the exact date and time that is passed in converted to Int64 using milliseconds?
I have the following Extensions class:
public static class Extensions
{
private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static DateTime ToDateTime(this Int64 _input)
{
return UnixEpoch.AddSeconds(_input);
}
public static string ToLocalString(this DateTime _input)
{
// _input = {6/1/2017 12:00:00 AM} System.DateTime
var milliseconds = _input.ToLocalTime().Subtract(UnixEpoch).TotalSeconds;
return Convert.ToInt64(milliseconds).ToString();
// I want to get the milliseconds for {6/1/2017 12:00:00 AM}
// I don't want the date or time to change
}
public static string ToUTCString(this DateTime _input)
{
// _input = {6/1/2017 12:00:00 AM} System.DateTime
var milliseconds = _input.ToUniversalTime().Subtract(UnixEpoch).TotalSeconds;
return Convert.ToInt64(milliseconds).ToString();
// I want to get the milliseconds for {6/1/2017 12:00:00 AM}
// I don't want the date or time to change
}
}
This is the calling method:
public ForecastIORequest(string apiKey, float latF, float longF, DateTime time, Unit unit, Language? lang = null, Extend[] extend = null, Exclude[] exclude = null)
{
_apiKey = apiKey;
_latitude = latF.ToString(CultureInfo.InvariantCulture);
_longitude = longF.ToString(CultureInfo.InvariantCulture);
//_time = time.ToUTCString();
_time = time.ToLocalString();
//DateTime t = _time.
_unit = Enum.GetName(typeof(Unit), unit);
_extend = (extend != null) ? RequestHelpers.FormatExtendString(extend) : "";
_exclude = (exclude != null) ? RequestHelpers.FormatExcludeString(exclude) : "";
_lang = (lang != null) ? RequestHelpers.FormatLanguageEnum(lang) : Language.en.ToString();
}
There's a fundamental problem with the way you're handling dates here, and if I boil it down to one thing, I think the problem is that ToUniversalTime() doesn't work the way you think it does.
What ToUniversalTime() does is, simply giving the UTC time of a time that's defined in a different time zone. For example, say my local time is UTC-7. So if I define a DateTime object without specifying DateTimeKind and set the value to, say, 2017/6/1 9:00:00, that means, at that time the actual UTC time is 2017/6/1 16:00:00 at that time, and ToUniversalTime() will give you a DateTime object with that value.
Let me change your ToUTCString() method a little bit and show you the problem with it. It's returning a long value instead of string now, and I break down the first line of code into two.
public static long ToUTC(this DateTime _input)
{
var utcTime = _input.ToUniversalTime();
var totalSeconds = utcTime.Subtract(UnixEpoch).TotalSeconds;
return Convert.ToInt64(totalSeconds);
}
And notice that in your Extensions class, the UnixEpoch object's DateTimeKind is set to UTC. I changed the date to 2017/6/1 8:00:00 for the ease of understanding.
private static readonly DateTime UnixEpoch = new DateTime(2017, 6, 1, 8, 0, 0, DateTimeKind.Utc);
public static DateTime ToDateTime(this Int64 _input)
{
return UnixEpoch.AddSeconds(_input);
}
Now let's call that method with a DateTime object whose DateTimeKind is set to UTC.
// dateObj will have time 2017/6/1 9:00:00 _in UTC_.
var dateObj = new DateTime(2017, 6, 1, 9, 0, 0, DateTimeKind.Utc);
// This method converts to UTC, but it's already in UTC, so no actual conversion takes place.
// Then subtracts UnixEpoch from it, which is also in UTC.
long dateInLong = dateObj.ToUTC();
// The difference is one hour, so dateInLong will be 3600.
Console.WriteLine(dateInLong);
// This method adds the above difference to UnixEpoch, and displays the time.
Console.WriteLine(dateInLong.ToDateTime());
Now, here, everything is in UTC and you should see output as expected, like below:
3600
6/1/2017 09:00:00
All good so far.
Now change things a bit, and let's set our dateObj to local instead of UTC, as you do in your example.
// Notice that the object is in local time now.
var dateObj = new DateTime(2017, 6, 1, 9, 0, 0);
long dateInLong = dateObj.ToUTC();
Console.WriteLine(dateInLong);
Console.WriteLine(dateInLong.ToDateTime());
Now, the above dateObj will have time 9:00:00, but in my local time. My actual location is UTC-7 so note that this means 9AM local time for me is 4PM UTC. But note that we haven't changed the UnixEpoch object, which is still in UTC and time is set to 8AM UTC in it. And therefore, dateInLong will be 28,800 (8 hours x 60 mins x 60 seconds). So when your ToDateTime() method is called, it adds 28,000 seconds to 8AM UTC time, and returns as a DateTime object, of which time now is 4PM UTC.
28800
6/1/2017 16:00:00
And that's why depending on the time you set your dateObj to, your output changes time as you said.
Solution
You need to decide which time zone to use, and stick to that. One option would be to get rid of all the UTC conversions and have all times set in local time.
public static class Extensions
{
// NOT set to UTC
private static readonly DateTime UnixEpoch = new DateTime(2017, 6, 1, 8, 0, 0);
public static DateTime ToDateTime(this Int64 _input)
{
return UnixEpoch.AddSeconds(_input);
}
public static long ToUTC(this DateTime _input)
{
// NOT converted to UTC. So... change variable names accordingly.
var utcTime = _input;
var totalSeconds = utcTime.Subtract(UnixEpoch).TotalSeconds;
return Convert.ToInt64(totalSeconds);
}
}
class Program
{
static void Main(string[] args)
{
// Notice that the object is in local time and NOT UTC.
var dateObj = new DateTime(2017, 6, 1, 9, 0, 0);
long dateInLong = dateObj.ToUTC();
Console.WriteLine(dateInLong);
Console.WriteLine(dateInLong.ToDateTime());
Console.ReadLine();
}
}
The other option, set EVERYTHING to UTC, but then you'll have to make sure that the DateTime object on which you call ToUTC() is defined in UTC and not local.
So:
private static readonly DateTime UnixEpoch = new DateTime(2017, 6, 1, 8, 0, 0, DateTimeKind.Utc);
And
var utcTime = _input.ToUniversalTime();
And finally
var dateObj = new DateTime(2017, 6, 1, 9, 0, 0, DateTimeKind.Utc);
BUT...
I see a bigger problem with you code, looking at the second code snippet. In the ForecastIORequest() constructor, you're saving time as a string. And that's not an ideal solution in my opinion. Because as you found the hard way, depending on what time zone the calling object was created, your time difference will be, well, different. And you'd have no way of knowing which.
I'd rather store the DateTime object as it is, and read it and calculate the difference when needed, taking into account time zones.
Hope this helps.
See DateTime.Ticks - there are 10,000 ticks in a millisecond. Simply take DateTime.Ticks / 10000 (ten thousand) and you have your milliseconds.
Here's a simple extension method to get the milliseconds as a long (that's Int64):
public static long ToMilliseconds(this DateTime dateTime)
{
return dateTime.Ticks / 10000;
}
I'm currently learning C# and making some console applications.
I want to create a console app which take two dates as parameters (YEAR/MONTH/DAY).
One for the start, and another one for the end.
I've tried to make a difference between the two of them, but I get the following error message:
"Cannot implicitly convert type 'System.TimeSpan' to 'System.DateTime' [Calendar]"
Here's my code:
static void Main(string[] args)
{
DateTime t = DateTime.Now;
DateTime end = new DateTime(2017, 11, 17);
int result = DateTime.Compare(t, end);
TimeSpan timeSpan = end - t;
DateTime days_left = timeSpan;
Console.WriteLine("Left", timeSpan.TotalDays);
Console.ReadKey();
}
In this version, I enter the end date in the code.
Thanks in advance for your help and for your time,
The following line is the problem:
DateTime days_left = timeSpan;
When you declared timeSpan you gave it the type TimeSpan. On the very next line, you try to assign timeSpan to days_left, which is a variable of type DateTime. This is not possible, as you cannot directly cast one type to the other.
If you think about it, this line doesn't even make sense, as DateTime objects represent a date not a time span. That is what TimeSpan objects are for!
Simply remove that line and your program will compile no problem.
Also, if I may make a suggestion, do not directly subtract DateTimes like you have done here:
var timeSpan = end - t;
Instead use DateTime.Subtract:
var timeSpan = end.Subtract(t);
This is the recommended approach when dealing with the difference between DateTimes, as it offers benefits such as adjusting for different time zones.
Finally, note my usage of the var keyword instead of explicitly declaring the type. This is a common coding convention in C# that I wish I knew as a beginner.
Here is a revised version of your code. Take some tips from it if you want for programs you write in the future:
public static void Main()
{
var currentDate = DateTime.Now; // Descriptive variable names
var endDate = new DateTime(2017, 11, 17);
double remainingDays = endDate.Subtract(currentDate).TotalDays; //TimeSpan stores everything in doubles instead of integers
Console.WriteLine("Days left: {0}", remainingDays); // Use String.Format formatting
Console.ReadLine(); // Use readline so that program only exists when ENTER is pressed
}
Try changing your code to this
DateTime t = DateTime.Now;
DateTime end = new DateTime(2017, 11, 17);
int result = DateTime.Compare(t, end);
TimeSpan timeSpan = end.Subtract(t);
How do I use a specific date as an input value?
var experiment1 = WorkingWithDates.GetDisplayString("London", DateTime.Today, 45.00);
Later on, I'll be convering it to a string, but I need it to be input as a DateTime.
public static string GetDisplayString(string city, DateTime date, double temp)
{
}
I'm using DateTime.Today as a placeholder, simply because it works. The thing is, I need it input as a specific day of a month of a year. (I've tried using (10, 10, 10) but it simply gives me a compiler error.
Edit.: I can't believe I did not figure out all I need to do is to add "new". Thanks folks
In (10, 10, 10) do you want the year 10?
Use the constructor that takes in a year, a month and a day. As below.
DateTime dt = new DateTime(2013, 12, 12);
then call your method
var experiment1 = WorkingWithDates.GetDisplayString("London", dt, 45.00);
PS: If you want year 10
DateTime dt = new DateTime(10, 10, 10);
will work. The year will be 0010
WorkingWithDates.GetDisplayString("London", DateTime.Today, 45.00);
you need a DateTime object to be used in place of DateTime.Today, so construct your instance using
DateTime newdate = new DateTime(2013,10,10) // year, month , day
and then
WorkingWithDates.GetDisplayString("London", newdate, 45.00);
I have a DateTime object which may or may not already contain some date/time information. With that I need to replace the time with my new time independently of the date and vice versa. How would I achieve this? I can't see anything obvious other than creating two new DateTime objects, one with the old/new date and one with the old/new time and concatenating. There surely must be a better way than this?
I would write two or three extension methods:
public static DateTime WithTime(this DateTime date, TimeSpan time)
{
return date.Date + time;
}
public static DateTime WithDate(this DateTime original, DateTime newDate)
{
return newDate.WithTime(original);
}
public static DateTime WithTime(this DateTime original, DateTime newTime)
{
return original.Date + newTime.TimeOfDay;
}
(You really don't need both of the second methods, but occasionally it might be simpler if you're chaining together a lot of calls.)
Note that you aren't creating any objects in terms of items on the heap, as DateTime is a struct.
DateTime is an immutable structure.
The only option is to construct a new DateTime struct based off your two existing values. This is the best approach. Luckily, it's a one liner:
DateTime CreateNewDateTime(DateTime date, DateTime time)
{
return new DateTime(date.Year, date.Month, date.Day, time.Hour, time.Minute, time.Second);
}
Strip the time from an existing datetime by writing .Date
DateTime new = oldDate.Date;
Add your TIme by either adding the hours, minutes & seconds individually
DateTime new = oldDate.Date.AddHours(14).AddMinutes(12).AddSeconds(33);
or all at once
DateTime new = oldDate.Date.AddSeconds(51153);
or by adding a TimeSpan()
DateTime new = oldDate.Date.Add(new TimeSpan(14,12,33));
This may not be exactly what you're looking for, but the DateTime class has a series of Add methods (AddMinutes(), AddDays(), etc.). I say this might not be what you're looking for, because these return a DateTime, so you would have to do something like
myDate = myDate.AddMinutes(60);