I want to write a procedure which will check whether entered date is a leap year or not.Kindly help me with this.
The following scalar function takes in a year and returns a bit flag indicating whether the passed in year is a leap year or not.
create function dbo.fn_IsLeapYear (#year int)
returns bit
as
begin
return(select case datepart(mm, dateadd(dd, 1, cast((cast(#year as varchar(4)) + '0228') as datetime)))
when 2 then 1
else 0
end)
end
go
Here are a few examples:
select dbo.fn_IsLeapYear(1900) as 'IsLeapYear?'
select dbo.fn_IsLeapYear(2000) as 'IsLeapYear?'
select dbo.fn_IsLeapYear(2007) as 'IsLeapYear?'
select dbo.fn_IsLeapYear(2008) as 'IsLeapYear?'
Explanation:
Giving the date as input to your custom sql function
The function takes in the year, appends '0228' to it (for February 28th) and adds a day.
If the month of the next day is a 2 (as extracted by the DATEPART function), then we're still in February so it must be a leap year! If not, it is not a leap year.
Related
I want to count say how many Mondays we have from 2022-02-01 - 2022-03-01. I found smth like this:
=SUMPRODUCT(WEEKDAY(B4:C4)=2) - B4 and C4 are the dates
But it returns 0. I assume it only checks if specific date is the specific day. Any ideas how I can do this but for a date range? So how count how many Mondays there are in February
I also found this
=NETWORKDAYS.INTL(B4;C4;"1000000")
but this returns 25
You can take advantage of the NETWORKDAYS.INTL function by using the string method to make all the days as weekend except for Monday.
The String method states:
weekends can be specified using seven 0’s and 1’s, where the first number in the set represents Monday and the last number is for Sunday. A zero means that the day is a work day, a 1 means that the day is a weekend. For example, “0000011” would mean Saturday and Sunday are weekends.
In this case since you only want to know the Mondays, the string would be "0111111" and the function would look like:
=NETWORKDAYS.INTL(StartDate,EndDate,"0111111")
I think this is right. It's counting inclusively so you would get five Mondays starting on Monday 7th Feb 2022 and ended on Monday 7th March 2022 for example.
=floor((B2-(A2+7-weekday(A2,12)))/7)+1
where A2 and B2 contain the start date end end date.
Obvs nul points for me again but for the record this could be generalised if you put the day number in C2 (e.g. 1 if you want to find Sundays, 2 for Mondays):
=floor((B2-(A2+7-weekday(A2,10+C2)))/7)+1
When I use the formula below the results of the EOMONTH function
returns the start of the next month for any month with 30 days instead of the last day of the specified month. The month and years are correct, so I'm pretty sure it's EOMONTH when used in another function.
For example,the results in B3 should be "11/31/1965" but it returns "12/1/1965".
=DATE(YEAR(B2),MONTH(B2)+6,DAY(TEXT(EOMONTH(MONTH(B2)+6,0))))
I have tried subtracting a day, but it returns the end-of-month -1 for months with 31 days (30). So I have the same problem in the other case.
I have also used IFS() to account for months with 30 days, and it miscalculates the date the same way.
=IFS( MONTH(B2)+6 = 4,DATE(YEAR(B2),MONTH(B2)+6,DAY(EOMONTH(MONTH(B2)+6,0))-2) ,
MONTH(B2)+6 =
6,DATE(YEAR(B2),MONTH(B2)+6,DAY(EOMONTH(MONTH(B2)+6,0))-2) ,
MONTH(B2)+6 =
9,DATE(YEAR(B2),MONTH(B2)+6,DAY(EOMONTH(MONTH(B2)+6,0))-2) ,
MONTH(B2)+6 =
11,DATE(YEAR(B2),MONTH(B2)+6,DAY(EOMONTH(MONTH(B2)+6,0))-2) ,
TRUE ,DATE(YEAR(B2),MONTH(B2)+6,DAY(EOMONTH(MONTH(B2)+6,0)) ) )
The EOMONTH function by itself where I just pass in the date as a string works correctly (column F).
Any Idea on what I'm doing wrong?
Thanks in advance.
Yes, as #player0 has explained, you can't just add something to a month and feed it into eomonth. Try putting
=eomonth(month(B2)+6,0)
into B3 (formatted as a date).
You get
1/31/1900
Why? month(b2)+6 gives 11 (which is just a number). Dates in google sheets are represented as days since 12/31/1899. So 11 formatted as a date gives 1/11/1900. Applying eomonth to that gives the last day of January 1900, which is the 31st. Feeding that into your formula would give 11/31/65, but that date doesn't exist, so you get 12/1/65.
If you want to go forward 6 months and then get the last day of the month, you need
=eomonth(date(year(B2),month(B2)+6,1),0)
You can also use the Edate function, which does not roll over into the first day of the next month:
=eomonth(edate(B2,6),0)
EOMONTH does not understand MONTH. instead, it converts it into date. to use EOMONTH you need to supply it with valid date
=EOMONTH(B2, 0)
I want to create a calendar like in the second image. But I can not figure out how to start the first column is a monday. So I fill it by 'hand' like in the first image.
I tried to create it automatic. Starting with the first day of the month and add one day the next columns like in the second picture:
How I want it to look like:
How it is currently looking:
Google sheets example
I was solving the same problem for my bussiness, and I think I got the answer.
Your first task is to determine the first "calendar monday" of the month.
First, build the first day of the corresponding month:
[B2] =DATE(YEAR(A1); MONTH(A1); 1)
Then, get the WEEKDAY of the corresponding first day. The second argument represents what day your week starts with:
If type is 1, days are counted from Sunday and the value of Sunday is 1, therefore the value of Saturday is 7.
If type is 2, days are counted from Monday and the value of Monday is 1, therefore the value of Sunday is 7.
If type is 3, days are counted from Monday and the value of Monday is 0, therefore the value of Sunday is 6.
In my case, we count the week starting from Monday. This means when the first day of the month lands on Monday, the return value will be 0.
[C2] =WEEKDAY(B2; 3)
The number you get represents how many days you need to substract from the initial date to get the first "calendar monday" of the month:
[D2] =B2 - C2
This date is what you are looking for. The final formula:
[A3] =DATE(YEAR(A1); MONTH(A1); 1) - WEEKDAY(DATE(YEAR(A1); MONTH(A1); 1); 3)
The rest of the days, simply add 1 to each preceding date.
[A4] =A3 + 1
[A5] =A4 + 1
And so on.
Secondly, set the Number Format on the calendar cells to just show the day.
Format -> Number -> More Formats -> More Date and Time Formats.
Select just the day from the drop down.
Finally, use conditional formatting to "hide" the values that don't match the initial date
Use a custom formula for the formatting, as follows:
=MONTH(A3) <> MONTH(A1)
Apply to the calendar range. This will format dates that don't belong to the current date, so make sure to paint that white.
And that's about it. Good luck!
I want to get first day of previous month in Dart as DateTime.
Below code is working correctly even for x = 1 (passing 0 as month)
print(new DateTime(2016,x-1,1));
but is it by design or I should not relay on it ?
It is by design.
The DateTime constructor you are using allows overflow and underflow on both days and months. A month value less than one means a month prior to January, which is a month in a previous year. Likewise a day value of less than one is a day in a previous month.
Informix is not my normal environment and the way it handles datetime values is throwing me for a loop. I can't imagine this is difficult, but for the life of me I'm not yet able to figure it out.
This is the SQL:
SELECT agentid,
extension As Ext,
resourcefirstname As FirstNm,
resourcelastname As LastNm,
Min(eventdatetime) As FirstIn
FROM agentstatedetail AS asdr Join
resource As r On asdr.agentid = r.resourceid
WHERE asdr.eventdatetime BETWEEN '2016-10-20 04:00:00' AND '2016-10-21 03:59:59'
AND eventtype = 3
AND assignedteamid = 14
Group By agentid, extension, resourcefirstname, resourcelastname
Order By Min(eventdatetime)
Everything works as is, but the dates in the Between clause are currently entered manually- not optimal. I just need some way to describe "yesterday at 4:00 AM" and "Today at 4:00 AM" Will somebody please clue me in?
Using Informix version 12.10.FC6DE, I can do this:
SELECT
TODAY::DATETIME YEAR TO SECOND AS today_zerohour
, TODAY::DATETIME YEAR TO SECOND - '20:00:00'::INTERVAL HOUR TO SECOND AS yesterday_dawn
, TODAY::DATETIME YEAR TO SECOND + '04:00:00'::INTERVAL HOUR TO SECOND AS today_dawn
FROM
systables
WHERE
tabid = 1;
And it returns:
today_zerohour yesterday_dawn today_dawn
2016-10-21 00:00:00 2016-10-20 04:00:00 2016-10-21 04:00:00
So, what is happening here:
The operator TODAY returns the system date as a DATE type. The DATE type does not have the precision I want (it only has year, month and day), so I cast the value (cast operator is ::) to a DATETIME with precision from year to second (the hour, minutes and seconds are set to zero):
TODAY::DATETIME YEAR TO SECOND
In Informix, for an addition or subtraction with a DATETIME value to return another DATETIME value, I need to add or subtract an INTERVAL value. So I created 2 INTERVAL values.
One INTERVAL of 20 hours to subtract from the today value (again the cast operator :: is used, this time to cast from a string to an INTERVAL):
'20:00:00'::INTERVAL HOUR TO SECOND
One INTERVAL of 4 hours to add to the today value:
'04:00:00'::INTERVAL HOUR TO SECOND