Compare two dates with a range - c#

is it possible to have something that can compare two dates in this format..
example today "Sep 30, 2013" and one week ago "Sep 22, 2013"
if its within this range say "good" if older then say "not good"
how can I make this in C# or vb.net

If difference between dates is smaller than 7 days, it will print "good" otherwise "Not good"
var ok = (firstDate-secondDate).TotalDays < 7? "good": "Not good";
Console.WriteLine(ok);
TotalDays is double so you can check if differnce is in full days, use Days if you want completed days difference as int
Read more about TimeSpan and it's properties.

if(date1 >= Convert.ToDateTime("Sep 22, 2013") && date1 <= Convert.ToDateTime("Sep 30, 2013"))
{
good
}
else
{
bad
}

You can use this generic Range class for checking some comparable value (like DateTime) falls into range:
public class Range<T>
where T : IComparable
{
public Range(T from, T to)
{
if (from.CompareTo(to) > 0)
throw new ArgumentException("From should not be greater than To");
From = from;
To = to;
}
public T From { get; private set; }
public T To { get; private set; }
public bool Contains(T value)
{
return value.CompareTo(From) >= 0 && value.CompareTo(To) <= 0;
}
// other methods like Intersects etc
}
Usage:
var today = DateTime.Today;
var range = new Range<DateTime>(today.AddDays(-7), today);
DateTime date = new DateTime(2013, 9, 25);
if (range.Contains(date))
// say good

thanks to all users who helped me here.. this is the final code that I am using..
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim fileDate As Date = Convert.ToDateTime("Sep 25, 2013")
Dim rightNow As Date = Convert.ToDateTime(Date.Now.ToString("MMM dd, yyyy"))
Dim lastWeek = rightNow.AddDays(-7)
If rightNow >= fileDate And lastWeek <= fileDate Then
Debug.Print("its new")
Else
Debug.Print("too old")
End If
End Sub

Related

Finding the month between a range

I have a datasource that returns dates and I have to find where the months falls within the month and day range buckets. The months and day range buckets are predefined so I put it in a Dictionary (not sure if that is even a good idea). I am using linq to find the min and Max dates and extracting the month from them. I need to find month from the dictionary where that month extracted falls within the range. For Example
Dictionary<int, int> MonthDayBuckets = new Dictionary<int, int>() { { 3,31 }, { 6,30 }, { 9,30 }, { 12,31 } };
var MinyDate = _dataSource.Min(x => x.values[0]);
var MaxDate = _dataSource.Max(x => x.values[0]);
var startMonth = Convert.ToDateTime(MinyDate).ToString("MM");
var endMonth = Convert.ToDateTime(MaxDate).ToString("MM");
Say startmonth return Jan so I want to be able to go to the dictionary and return only march (03.31) and if I get 10 for the Max (October) I am trying to return (12,31) December
If my understanding is correct, your MonthDayBuckets variable is meant to represent date ranges:
3/31 - 6/30
6/30 - 9/30
9/30 - 12/31
12/31 - 3/31
...and given a month, you're wanting to see what the end date is of the interval that the first of that month falls between? Like you gave the example of October returning 12/31.
This problem can be simplified since you'll get the same result saying "what's the next occurring date after this given date?" The next occurring date for 10/01 would be 12/31. So here's how you could rearrange your data:
var availableDates = new List<string> { "03/31", "06/30", "09/30", "12/31" };
Now you'll be able to find a match by finding the index of the first one that's greater than your given date. Note how I made the month/day combos lexicographical orderable.
var startMonth = Convert.ToDateTime(MinyDate).ToString("MM");
var startDate = startMonth + "/01";
var endMonth = Convert.ToDateTime(MaxDate).ToString("MM");
var endDate = endMonth + "/01";
// Wrap around to the first date if this falls after the end
var nextStartDate = availableDates.FirstOrDefault(d => d.CompareTo(startDate) >= 1) ?? availableDates[0];
var nextEndDate = availableDates.FirstOrDefault(d => d.CompareTo(endDate) >= 1) ?? availableDates[0];
You could use Linq for the purpose. For example,
var nearestKey = MonthDayBuckets.Keys.Where(x => x >= endMonth.Month).Min();
var nearestDate = new DateTime(DateTime.Now.Year,nearestKey,MonthDayBuckets[nearestKey]); // or whatever the year it needs to be represent
Though above query would get you the result, I would suggest you define a structure to store the Range itself, rather than using Dictionary
For example,
public class Range
{
public MonthDate StartRange{get;set;}
public MonthDate EndRange{get;set;}
public Range(MonthDate startRange,MonthDate endRange)
{
StartRange = startRange;
EndRange = endRange;
}
}
public class MonthDate
{
public MonthDate(int month,int date)
{
Month = month;
Date = date;
}
public int Month{get;set;}
public int Date{get;set;}
//Depending on if your Ranges are inclusive or not,you need to decide how to compare
public static bool operator >=(MonthDate source, MonthDate comparer)
{
return source.Month>= comparer.Month && source.Date>=comparer.Date;
}
public static bool operator <=(MonthDate source, MonthDate comparer)
{
return source.Month<= comparer.Month && source.Date<=comparer.Date;
}
}
Now you could define ranges as
var dateRanges = new Range[]
{
new Range(new MonthDate(12,31),new MonthDate(3,31)),
new Range(new MonthDate(3,31),new MonthDate(6,30)),
new Range(new MonthDate(6,30),new MonthDate(12,31)),
};
var result = dateRanges.First(x=>x.StartRange <= new MonthDate(endMonth.Month,endMonth.Day) && x.EndRange >= new MonthDate(endMonth.Month,endMonth.Day));

How to read from string?

I'm trying to learn how to schedule pictures depending on what time a user has selected.
Here is code with questions:
private void startjob()
{
string theDate = DateTimePicker1.Value.ToString();
DateTime dt = Convert.ToDateTime(date);
{
DateTime start = new DateTime(2009, 12, 9, 10, 0, 0); //How Do I make this to read the string that is converted from DateTimePicker instead of this?
DateTime end = new DateTime(2009, 12, 10, 12, 0, 0); //How Do I make this to read the string that is converted from DateTimePicker instead of this?
DateTime now = DateTime.Now;
if ((now > start) && (now < end))
{
//match found
}
}
}
DateTimePicker.Value returns the DateTime object. You're trying to convert to and from a string type unnecessarily.
DateTime start = DateTimePickerStart.Value;
DateTime end = DateTimePickerEnd.Value;
Supposing your controls are named as DateTimePicker1 and DateTimePicker2:
private void startjob()
{
DateTime start = DateTimePicker1.Value;
DateTime end = DateTimePicker2.Value;
DateTime now = DateTime.Now;
if ((now > start) && (now < end))
{
//match found
}
}
DateTimePicker.Value property is a DateTime object itself, hence your code can be simplified, no need to convert to string.

Finding every friday from start date till the end of the year

So I'm back with another baffling DateTime question.
In C#, how would I return the (day) for every Friday from a start date (DateTime.Now) until the end of the current year?
So for example, today being Friday the 19th, it would return, 26, 2, 9, 16, 23, 30, 7, etc.
Does this work?
static IEnumerable<DateTime> GetFridays(DateTime startdate, DateTime enddate)
{
// step forward to the first friday
while (startdate.DayOfWeek != DayOfWeek.Friday)
startdate = startdate.AddDays(1);
while (startdate < enddate)
{
yield return startdate;
startdate = startdate.AddDays(7);
}
}
var start = DateTime.Today;
var startDay = ((int) start.DayOfWeek);
var nextFriday = startDay<6 //5 if today is friday and you don't want to count it
? start.AddDays(5 - startDay) //friday this week
: start.AddDays(12 - startDay); //friday next week
var remainingFridays = Enumerable.Range(0,53)
.Select(i => nextFriday.AddDays(7 * i))
.TakeWhile(d => d.Year == start.Year);
This would do what you want.
IList<int> getFridaysForYearFromPoint(DateTime startDate)
{
DateTime currentFriday = startDate;
List<int> results = new List<int>();
//Find the nearest Friday forward of the start date
while(currentFriday.DayOfWeek != DayOfWeek.Friday)
{
currentFriday = currentFriday.AddDays(1);
}
//FIND ALL THE FRIDAYS!
int currentYear = startDate.Year;
while (currentFriday.Year == currentYear)
{
results.Add(startDate.Day);
currentFriday = currentFriday.AddDays(7);
}
return results;
}
My Answer...
static void Main(string[] args)
{
DateTime begin = DateTime.Now;
DateTime end = DateTime.Now.AddDays(200);
while (begin <= end)
{
if (begin.DayOfWeek == DayOfWeek.Friday)
Console.WriteLine(begin.ToLongDateString());
begin = begin.AddDays(1);
}
Console.ReadKey();
}
You can use the CalendarPeriodCollector of the Time Period Library for .NET:
// ----------------------------------------------------------------------
public void FindRemainigYearFridaysSample()
{
// filter: only Fridays
CalendarPeriodCollectorFilter filter = new CalendarPeriodCollectorFilter();
filter.WeekDays.Add( DayOfWeek.Friday );
// the collecting period
CalendarTimeRange collectPeriod = new CalendarTimeRange( DateTime.Now, new Year().End.Date );
// collect all Fridays
CalendarPeriodCollector collector = new CalendarPeriodCollector( filter, collectPeriod );
collector.CollectDays();
// show the results
foreach ( ITimePeriod period in collector.Periods )
{
Console.WriteLine( "Friday: " + period );
}
} // FindRemainigYearFridaysSample
I'm expert in vb.net .. but there is no different ..
I wrote the code below in page_load of a asp.net web form ...
make an asp.net application
add a web form to it
write the code below in page_load
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim gc As New System.Globalization.GregorianCalendar
Dim d As New DateTime(gc.GetYear(DateTime.Now), 1, 1)
Dim i As Int16 = 1
While i <= gc.GetDaysInYear(gc.GetYear(DateTime.Now))
If gc.GetDayOfWeek(d) = DayOfWeek.Friday Then
Response.Write(d & "<br />")
d = gc.AddDays(d, 7)
i += 7
Else
d = gc.AddDays(d, 1)
i += 1
End If
End While
End Sub

Elegantly check if a given date is yesterday

Assuming you have a Unix timestamp, what would be an easy and/or elegant way to check if that timestamp was some time yesterday?
I am mostly looking for solutions in Javascript, PHP or C#, but pseudo code and language agnostic solutions (if any) are welcome as well.
In C# you could use this:
bool isYesterday = DateTime.Today - time.Date == TimeSpan.FromDays(1);
You can use this in C#:
bool isYesterday = (dateToCheck.Date.AddDays(1) == DateTime.Now.Date);
PHP:
$isYesterday = date('Ymd', $timestamp) == date('Ymd', strtotime('yesterday'));
In pseudo code, to compare timestamps:
get current Unix timestamp
transform the retrieved timestamp to a date
subtract 1 day from the date
transform the timestamp to test to a date
compare both dates. If they're equal the tested timestamp was yesterday.
Watch out for timezones if you show the results to a user. For me it's now 13:39 on July 9 2010. A timestamp for 14 hours ago for me is yesterday. But for someone in a different timezone where it's now 15:39, 14 hours ago wasn't yesterday!
Another problem might be systems with a wrong time/date setup. For example if you use JavaScript and the system time of the visitors PC is wrong, the program may come to a wrong conclusion. If it's essential to get a correct answer, retrieve the current time from a known source with a correct time.
An example in Smalltalk using Pharo/Squeak
(Date year: 2014 month: 4 day: 24) = Date yesterday
This accepts an optional DateTimeZone object. If it's not given, it uses the currently set default timezone.
<?php
function isYesterday($timestamp, $timezone = null) {
$t = new DateTime(null, $timezone);
$t->setTimestamp($timestamp);
$t->setTime(0,0);
$yesterday = new DateTime("now", $timezone);
$yesterday->setTime(0,0);
$yesterday = $yesterday->sub(new DateInterval('P1D'));
return $t == $yesterday;
}
Another C# example:
bool isYesterday = DateTime.Now.Date.AddDays(-1) == dateToCheck.Date;
Code:
static class ExtensionMethods
{
private static readonly DateTime UnixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0);;
public static bool IsYesterday(this int unixTime)
{
DateTime convertedTime = UnixStart.AddSeconds(unixTime);
return convertedTime.Date == DateTime.Now.AddDays(-1).Date;
}
public static bool IsYesterday(this DateTime date)
{
return date.Date == DateTime.Now.AddDays(-1).Date;
}
}
Examples:
public class Examples
{
public void Tests()
{
if (1278677571.IsYesterday()) System.Console.WriteLine("Is yesterday");
DateTime aDate = new DateTime(2010, 12, 31);
if (aDate.IsYesterday()) System.Console.WriteLine("Is yesterday");
}
}
In JavaScript, you could write
var someDate = new Date(2010, 6, 9);
Date.yesterday.date == someDate.date // true
Left out needless implementation details, but it's possible. Ok, there ya go :)
(function() {
function date(d) {
var year = d.getFullYear();
var month = d.getMonth();
var day = d.getDate();
return new Date(year, month, day);
}
Object.defineProperty(Date, 'yesterday', {
enumerable: true,
configurable: false,
get: function() {
var today = new Date();
var millisecondsInADay = 86400000;
var yesterday = new Date(today - millisecondsInADay);
return yesterday;
},
set: undefined
});​​​​​​​​
Object.defineProperty(Date.prototype, 'date', {
enumerable: true,
configurable: true,
get: function() {
return date(this).valueOf();
},
set: undefined
});
})();
C#
TimeSpan difference = DateTime.Now.Date - olderDate.Date;
bool isYesterday = difference.TotalDays == 1;
You can give this function a shot:
public bool IsFromYesterday(long unixTime) {
DateTime convertedTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
convertedTime.AddSeconds(unixTime);
DateTime rightNow = DateTime.Now;
DateTime startOfToday = DateTime.Today;
DateTime startOfYesterday = startOfToday - new TimeSpan(1, 0, 0, 0);
if (convertedTime > startOfYesterday && convertedTime < rightNow)
return true;
else
return false;
}

Count of days intersecting between two date ranges

Would anyone have any ideas of how to best calculate the amount of days that intersect between two date ranges?
Here's a little method I wrote to calculate this.
private static int inclusiveDays(DateTime s1, DateTime e1, DateTime s2, DateTime e2)
{
// If they don't intersect return 0.
if (!(s1 <= e2 && e1 >= s2))
{
return 0;
}
// Take the highest start date and the lowest end date.
DateTime start = s1 > s2 ? s1 : s2;
DateTime end = e1 > e2 ? e2 : e1;
// Add one to the time range since its inclusive.
return (int)(end - start).TotalDays + 1;
}
Obtain a new range, defined by the later of the beginnings and the earlier of the ends, and determine the number of days since the beginning of the epoch for each day in that new range.
The difference is the number of days in the intersection. Accept only positive values.
Edited to take into account ranges instead of individual dates.
Here is an example from R. That might clarify the answer.
c_st = as.POSIXct("1996-10-14")
c_ed = as.POSIXct("1996-10-19")
d_st = as.POSIXct("1996-10-17")
d_ed = as.POSIXct("1999-10-22")
max(range(c_st,c_ed ))-min(range(d_st,d_ed) ) >= 0 & min(range(c_st,c_ed )) < max(range(d_st,d_ed) )
True would indicate that they intersect, False otherwise.
[r]
If I understand your question, you're asking for the number of days that overlap two date ranges, such as:
Range 1 = 2010-1-1 to 2010-2-1
Range 2 = 2010-1-5 to 2010-2-5
in this example the number of intersecting days would be 28 days.
Here is a code sample for that example
DateTime rs1 = new DateTime(2010, 1, 1);
DateTime re1 = new DateTime(2010, 2, 1);
DateTime rs2 = new DateTime(2010, 1, 5);
DateTime re2 = new DateTime(2010, 2, 5);
TimeSpan d = new TimeSpan(Math.Max(Math.Min(re1.Ticks, re2.Ticks) - Math.Max(rs1.Ticks, rs2.Ticks) + TimeSpan.TicksPerDay, 0));
The question asks between two date Ranges not two Dates. (Edited in response to comments)
So if you have 2 Date Ranges (r1s,r1e), you need to determine which starts first, Is there overlap, and what is the overlap.
double overlap(DateTime r1s, DateTime r1e, DateTime r2s, DateTime r1e){
DateTime t1s,t1e,t2s,t2e;
if (rs1<rs2) //Determine which range starts first
{
t1s = r1s;
t1e = r1e;
t2s = r2s;
t2e = r2e;
}
else
}
t1s = r2s;
t1e = r2e;
t2s = r1s;
t2e = r1e;
}
if (t1e<t2s) //No Overlap
{
return -1;
}
if (t1e<t2e) //Partial Overlap
}
TimeSpan diff = new TimeSpan(t1e.Ticks - t2s.Ticks);
{
else //Range 2 totally withing Range 1
}
TimeSpan diff = new TimeSpan(t2e.Ticks - t2s.Ticks);
{
double daysDiff = diff.TotalDays;
return daysDiff;
}

Categories