How to get 30 days from today including the month january - c#

My sql table contains date of birth of many people.dates are in mm/dd/yyyy format. I want select the persons details whose birth day in next 30days. And i use the following query for that,
SELECT Mem_FirstNA, Mem_LastNA, Mem_DOB FROM MemberDetails WHERE
ltrim(str(year(GETDATE()))) + -' + ltrim(str(month(Mem_DOB))) + '-' +
ltrim(str(day(Mem_DOB))) >= getdate() - 1 AND
ltrim(str(year(GETDATE()))) + '-' + ltrim(str(month(Mem_DOB))) + '-' +
ltrim(str(day(Mem_DOB))) <= getdate() + 30
And full code is
public List<MemberData> GetThisMonthBirthday()
{
List<MemberData> MD = new List<MemberData>();
using (SqlConnection con = new SqlConnection(Config.ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("SELECT Mem_FirstNA, Mem_LastNA, Mem_DOB FROM MemberDetails WHERE ltrim(str(year(GETDATE()))) + '-' + ltrim(str(month(Mem_DOB))) + '-' + ltrim(str(day(Mem_DOB))) >= getdate() - 1 AND ltrim(str(year(GETDATE()))) + '-' + ltrim(str(month(Mem_DOB))) + '-' + ltrim(str(day(Mem_DOB))) <= getdate() + 30", con))
{
try
{
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
MemberData mb = new MemberData();
mb.Mem_NA = (string)reader["Mem_FirstNA"];
mb.Mem_LastNA =(string)reader["Mem_LastNA"];
mb.Mem_DOB = (Convert.ToDateTime(reader["Mem_DOB"]));
MD.Add(mb);
}
}
catch (Exception e) { throw e; }
finally { if (con.State == System.Data.ConnectionState.Open) con.Close(); }
return MD;
}
}
The problem is that this check only till December 31, if the persons birthday in 01/01/1987 , the query is not selected that details. Please help me to solve this problem. Thank you

There are lots of ways to do this, you need conditional logic depending on whether or not you are within 30 days of the end of the year. If you're using SQL Server, I'd wrap the logic in a function to make it more readable, e.g.:
CREATE FUNCTION [dbo].[IsBirthdayInRange]
(
#Birthday DATETIME,
#StartDate DATETIME,
#EndDate DATETIME
)
RETURNS BIT
AS
BEGIN
DECLARE #StartMonthDay INT
DECLARE #EndMonthDay INT
DECLARE #BirthdayMonthDay INT
SET #StartMonthDay = MONTH(#StartDate) * 100 + DAY(#StartDate)
SET #EndMonthDay = MONTH(#EndDate) * 100 + DAY(#EndDate)
SET #BirthdayMonthDay = MONTH(#Birthday) * 100 + DAY(#Birthday)
IF YEAR(#StartDate) <> YEAR(#EndDate)
BEGIN
IF #BirthdayMonthDay >= #StartMonthDay OR #BirthdayMonthDay <= #EndMonthDay
BEGIN
RETURN 1
END
END
ELSE
BEGIN
IF #BirthdayMonthDay >= #StartMonthDay AND #BirthdayMonthDay <= #EndMonthDay
BEGIN
RETURN 1
END
END
RETURN 0
END
You can then use it as:
...
WHERE IsBirthdayInRange(Mem_DOB, GETDATE(), GETDATE() + 30)

Related

InvalidArgument=Value of '1' is not valid for 'index'

I have an error in my C# application that interacts with MDB access DB.
The error is:
InvalidArgument=Value of '1' is not valid for 'index'.
My code:
objConn.Open();
listView1.Items.Clear();
OleDbCommand cmd = new OleDbCommand("select a.bill_Id,a.bill_Number,a.bill_Date,c.sup_Name,Sum(b.de_NetPrice),a.bill_Note from (suppliers c right JOIN bills a on c.sup_Id = a.bill_From) LEFT JOIN bill_Details b on a.bill_Id = b.bill_Id where a.bill_Id like '%" + txbSearch.Text + "%' or a.bill_Number like '%" + txbSearch.Text + "%' or c.sup_Name like '%" + txbSearch.Text + "%' or a.bill_Note like '%" + txbSearch.Text + "%' group by a.bill_Id,a.bill_Number,a.bill_Date,c.sup_Name,a.bill_Note order by a.bill_Date desc", objConn);
OleDbDataReader dataReader = cmd.ExecuteReader();
int i = 0;
while (dataReader.Read())
{
DateTime dt0 = DateTime.Parse(dataReader.GetValue(2).ToString());
int Date1 = DateTime.Compare(DateTime.Parse(dt0.ToShortDateString()), DateTime.Parse(txbFrom.Value.ToShortDateString()));
int Date2 = DateTime.Compare(DateTime.Parse(dt0.ToShortDateString()), DateTime.Parse(txbTo.Value.ToShortDateString()));
if (Date1 >= 0 && Date2 <= 0)
{
listView1.Items.Add(dataReader.GetValue(0).ToString());
// The error happens on the following line
listView1.Items[i].SubItems.Add(dataReader.GetValue(1).ToString());
listView1.Items[i].SubItems.Add(dt0.ToShortDateString());
listView1.Items[i].SubItems.Add(dataReader.IsDBNull(3) ? "0" : dataReader.GetString(3));
listView1.Items[i].SubItems.Add(dataReader.IsDBNull(4) ? "0" : dataReader.GetDouble(4).ToString("n2"));
listView1.Items[i].SubItems.Add(dataReader.IsDBNull(5) ? "-" : dataReader.GetString(5));
}
i++;
}
objConn.Close();
The listview has these columns:
ID -- Number -- BillDate -- Supplier -- total -- Note
I may have found the issue.
If first time around the 'if (Date1 >= 0 && Date2 <= 0)' statemant evaluates to false, the i index will still get incremented. And then on the second iteration the if statement might evaluate to true, and then your index will be off-by-one, as there is just one Item in the ListView, but you try to get at using listView1.Items[1], instead of listView1.Items[0], which would be correct.
Solution would be to change the code to:
if (Date1 >= 0 && Date2 <= 0)
{
listView1.Items.Add(dataReader.GetValue(0).ToString());
listView1.Items[i].SubItems.Add(dataReader.GetValue(1).ToString());// The error appears on this line
listView1.Items[i].SubItems.Add(dt0.ToShortDateString());
listView1.Items[i].SubItems.Add(dataReader.IsDBNull(3) ? "0" : dataReader.GetString(3));
listView1.Items[i].SubItems.Add(dataReader.IsDBNull(4) ? "0" : dataReader.GetDouble(4).ToString("n2"));
listView1.Items[i].SubItems.Add(dataReader.IsDBNull(5) ? "-" : dataReader.GetString(5));
i++;
}

SQL Server & C# Stored Procedure & Divide by Zero Exception

So first here is my C# code and then comes the stored procedure.
public DataTable GetCourseHighPass(String tmpCourse)
{
command.Connection = OpenConnection();
try
{
command.CommandText = "exec GetCourseCompletions #tmpCourse = '" + tmpCourse + "'";
SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
dataAdapter.Fill(dataTable);
return dataTable;
}
catch (Exception)
{
throw new Exception("There are no VG's for this course.");
}
finally
{
command.Connection.Close();
}
}
And here is my stored procedure.
create procedure GetCourseCompletions
#tmpCourse nvarchar(30)
as
select (count(pnr) * 100 / (select count(pnr)
from HasStudied
where courseCode = #tmpCourse
and count(pnr) =)) as VGPrecentage
from HasStudied
where grade >= 5
and courseCode = #tmpCourse
go
The problem is that if there are no students with a high pass I will get a divide by zero exception. Looking for suggestions on how to catch this exception so the program does not crash or even better to re-write the stored procedure so it does not get an exception in the first place.
Thank you for your assistance!
Do what Eric said:
DECLARE #count int
Set #count = (select count(pnr) from HasStudied where courseCode = #tmpCourse and count(pnr) =...)
IF #count = 0
BEGIN
SELECT 0 as VGPrecentage
END
ELSE
BEGIN
select (count(pnr)*100 / #count) as VGPrecentage from HasStudied where grade >= 5 and courseCode = #tmpCourse
END
I suggest you to use this kind of query instead of yours that will handle NULL values and Zero values:
SELECT
CASE WHEN part * total <> 0 THEN part * 100 / total ELSE 0 END
FROM (
SELECT SUM(CASE WHEN grade > 5 THEN 1.00 ELSE 0.00 END) As part, SUM(1.00) as total
FROM HasStudied
WHERE courseCode = #tmpCourse) t

How to check if for example 30 min have passed?

i have the following Code:
if (v != null && DateTime.Now > v.Besetzt_Von)
{
Debug.WriteLine("Hallo, das ist die Ausgabe! : " + v.Thema + v.Besetzt_Von + v.Besetzt_Bis);
string clientId = GetClientId(req);
DateTime TimeCheck = v.Besetzt_Von;
if (TimeCheck.AddMinutes(30) > v.Besetzt_Von)
{
String hql = "UPDATE Buchung as b " +
"set STORNO = :Storno " +
"where ID IN (SELECT rr.Buchung FROM Raumreservierung rr " +
"where BESETZT_VON = :Von and Raum IN (SELECT r.ID FROM Raum r " +
"join r.Panel pl where pl.ID = :PanelId))";
IQuery query = CurrentSession.CreateQuery(hql);
query.SetParameter("Storno", DateTime.Now);
query.SetParameter("Von", v.Besetzt_Von);
query.SetParameter("PanelId", clientId);
int result = query.ExecuteUpdate();
Debug.WriteLine("Rows affected: " + result);
}
}
I want that if for example Besetzt_Von = 14:00 o'clock, the Query only gets executed if 30 minutes have passed (14:30). I did that with the if clause, but it does not work. The Query is always executing. What iam doing wrong?
change
if (TimeCheck.AddMinutes(30) > v.Besetzt_Von)
which doesn't do anything (this means if v.Besetz_von < v.BesetzVon + 30 minutes, which is of course always true)
to
if (DateTime.Now > v.Besezt_Von.AddMinutes(30))
// DateTime TimeCheck = v.Besetzt_Von; <-- you don't need this
if (DateTime.Now > v.Besetzt_Von.AddMinutes(30))
{
// ...
}

How to get 14 days prior to the given date avoiding holidays

In my system ,the due date of the bill must be 14 days after the issued date.
I have due date and I want to know issued date .
I have to calculate :
issued date = 14 days prior to the due date
but 14 days must be business days ,not holidays.
Holidays is stored in a table 'tblHolidayMaster' like this,
Date Description
2012/05/13 Mother's
Day2012/06/02 Saturnday2012/12/25 Christmas
How can I calculate the issued date avoiding holidays?
Thank you for all of your interests and replies.
I would calculate the Date using a function like the one below (which i use)
public static DateTime AddBusinessDays(DateTime date, int days)
{
if (days == 0) return date;
if (date.DayOfWeek == DayOfWeek.Saturday)
{
date = date.AddDays(2);
days -= 1;
}
else if (date.DayOfWeek == DayOfWeek.Sunday)
{
date = date.AddDays(1);
days -= 1;
}
date = date.AddDays(days / 5 * 7);
int extraDays = days % 5;
if ((int)date.DayOfWeek + extraDays > 5)
{
extraDays += 2;
}
int extraDaysForHolidays =-1;
//Load holidays from DB into list
List<DateTime> dates = GetHolidays();
while(extraDaysForHolidays !=0)
{
var days = dates.Where(x => x >= date && x <= date.AddDays(extraDays)).Count;
extraDaysForHolidays =days;
extraDays+=days;
}
return date.AddDays(extraDays);
}
Haven't tested the ast section that does the holidays
I went with the straight forward looping solution, so it will be slow for long intervals. But for short intervals like 14 days, it should be quite fast.
You need to pass in the holidays in the constructor. An instance of BusinessDays is immutable and can be reused. In practice you probably will use an IoC singleton or a similar construct to get it.
AddBusinessDays throws an ArgumentException if the start date is a non business day, since you didn't specify how to treat that case. In particular AddBusinessDays(0) on a non business day would have strange properties otherwise. It'd either break time reversal symmetry, or return a non business day.
public class BusinessDays
{
private HashSet<DateTime> holidaySet;
public ReadOnlyCollection<DayOfWeek> WeekendDays{get; private set;}
public BusinessDays(IEnumerable<DateTime> holidays, IEnumerable<DayOfWeek> weekendDays)
{
WeekendDays = new ReadOnlyCollection<DayOfWeek>(weekendDays.Distinct().OrderBy(x=>x).ToArray());
if(holidays.Any(d => d != d.Date))
throw new ArgumentException("holidays", "A date must have time set to midnight");
holidaySet = new HashSet<DateTime>(holidays);
}
public BusinessDays(IEnumerable<DateTime> holidays)
:this(holidays, new[]{DayOfWeek.Saturday, DayOfWeek.Sunday})
{
}
public bool IsWeekend(DayOfWeek dayOfWeek)
{
return WeekendDays.Contains(dayOfWeek);
}
public bool IsWeekend(DateTime date)
{
return IsWeekend(date.DayOfWeek);
}
public bool IsHoliday(DateTime date)
{
return holidaySet.Contains(date.Date);
}
public bool IsBusinessDay(DateTime date)
{
return !IsWeekend(date) && !IsHoliday(date);
}
public DateTime AddBusinessDays(DateTime date, int days)
{
if(!IsBusinessDay(date))
throw new ArgumentException("date", "date bust be a business day");
int sign = Math.Sign(days);
while(days != 0)
{
do
{
date.AddDays(sign);
} while(!IsBusinessDay(date));
days -= sign;
}
return date;
}
}
I think that is what you required. It is simple and I have tested it and it is working... And it is not a bad approach to write a function or SP in databases rather to write the complex code in C#... (change column name of date as in your db.)
Make it function or SP as what you want.
Note: Comment the check of 'Saturday' and 'Sunday'. If it is already added in your table reocrds.
declare #NextWorkingDate datetime
declare #CurrentDate datetime
set #CurrentDate = GETDATE()
set #NextWorkingDate = #CurrentDate
declare #i int = 0
While(#i < 14)
Begin
if(((select COUNT(*) from dbo.tblHolidayMaster where convert(varchar(10),[Date],101) like convert(varchar(10),#NextWorkingDate,101)) > 0) OR DATENAME(WEEKDAY,#NextWorkingDate) = 'Saturday' OR DATENAME(WEEKDAY,#NextWorkingDate) = 'Sunday')
Begin
print 'a '
print #NextWorkingDate
set #NextWorkingDate = #NextWorkingDate + 1
CONTINUE
End
else
Begin
print 'b '
print #NextWorkingDate
set #NextWorkingDate = #NextWorkingDate + 1
set #i = #i + 1
CONTINUE
End
End
print #NextWorkingDate
I calculate the issued date avoid your holiday from your table 'tblHolidayMaster' only.
int addDay = -14;
DateTime dtInputDay = System.DateTime.Now;//Your input day
DateTime dtResultDate = new DateTime();
dtResultDate = dtInputDay.AddDays(addDay);
bool result = false;
string strExpression;
DataView haveHoliday;
while (!result) {
strExpression = "Date >='" + Convert.ToDateTime(dtResultDate.ToString("yyyy/MM/dd")) + "' and Date <='" + Convert.ToDateTime(dtInputDay.ToString("yyyy/MM/dd")) + "'";
haveHoliday = new DataView(tblHolidayMaster);
haveHoliday.RowFilter = strExpression;
if (haveHoliday.Count == 0) {
result = true;
} else {
addDay = -(haveHoliday.Count);
dtInputDay = dtResultDate.AddDays(-1);
dtResultDate = dtResultDate.AddDays(addDay);
}
}
Your issued date is dtResultDate
Try the following link,
http://www.c-sharpcorner.com/uploadfile/tirthacs/difference-between-two-dates-excluding-weekends/

How do I write this logic of C#'s datetime difference in SQL Server?

I have this logic in my C# code which gives me time difference between two times
Example inputs are: '12:00 AM' - '11:15 AM' gives 45 minutes.
DateTime startTime = Convert.ToDateTime(startTimeHH + ":" + startTimeMM + " " + startTimeAMPM);
DateTime endTime = Convert.ToDateTime(endTimeHH + ":" + endTimeMM + " " + endTimeAMPM);
DateTime breakTime = Convert.ToDateTime(breakTimeHH + ":" + breakTimeMM);
TimeSpan hours = endTime.Subtract(startTime);
hours = hours.Subtract(breakTime.TimeOfDay);
I referred some MSDN docs datetime functions in SQL server but couldn't find these functions which can give me time from input as 12:00 PM
However now I need to move this piece now into SQL server. How do I write it?
Example inputs are: '12:00 AM' - '11:15 AM' won't return 45 it will return 75 (it contains 15 as 25)
Here is one way to get what looks like a .NET TimeSpan:
declare #startTimeHH char(2) = '10',
#startTimeMM char(2) = '30',
#startTimeAMPM char(2) = 'AM',
#endTimeHH char(2) = '12',
#endTimeMM char(2) = '00',
#endTimeAMPM char(2) = 'PM',
#breakTimeHH char(2) = '01',
#breakTimeMM char(2) = '15',
#startTime DateTime,
#endTime DateTime,
#breakTime DateTime,
#result Time
set #startTime = cast ((#startTimeHH + ':' + #startTimeMM + ' ' + #startTimeAMPM) as Time);
set #endTime = cast ((#endTimeHH + ':' + #endTimeMM + ' ' + #endTimeAMPM) as Time);
set #breakTime = cast ((#breakTimeHH + ':' + #breakTimeMM) as Time);
set #result = #endTime - #startTime - #breakTime
select cast(#result as CHAR(8))
The result is 00:15:00
CREATE TABLE [dbo].#events (
[StartTime] time NULL,
[EndTime] time NULL )
INSERT INTO #events
VALUES
('08:00', '08:30'),
('08:30', '08:00'),
('09:00', '10:00'),
('15:00', '16:30')
select convert(time, dateadd(minute, datediff(minute, StartTime, EndTime), 0))
From #events
drop table #events
ResultSet
00:30:00.0000000
23:30:00.0000000
01:00:00.0000000
01:30:00.0000000
Use DateDiff function
DatePart will be handy, too
Here is some SQL that returns '45' (minutes)
DECLARE #Start DATETIME, #END DATETIME
SET #Start = '2009-05-02 10:00:50'
set #End = '2009-05-02 10:45:50'
-- FYI
SELECT #start, #end
-- returns 45
SELECT DateDiff(mi, #start, #end)

Categories