How to get Month from ISO Date and Week - sql

I'm looking for a way to convert an ISO date to Month and I also need to covert an ISO week to Month.
I need to do this in Excel and Access.
I found this formula for excel but when converting it to Access it does not work. Is there a simple way to accomplish this?
I found this Excel formula to convert ISO date to month (C2=date) and it works perfect:
=MONTH(DATE(YEAR(C2),MONTH(C2)+(WEEKDAY(C2,2)+(DAY(DATE(YEAR(C2),MONTH(C2)+1,0)))-(DAY(C2))<4),(((7-(WEEKDAY(C2,2)))+(DAY(C2)))>3)))
But when I modify it for an Access query it does not return the correct values:
Date_to_Month:MONTH(DATESERIAL(YEAR([WW_Index].[ISO_date]),MONTH([WW_Index].[ISO_date])+(WEEKDAY([WW_Index].[ISO_date],2)+(DAY(DATESERIAL(YEAR([WW_Index].[ISO_date]),MONTH([WW_Index].[ISO_date])+1,0)))-(DAY([WW_Index].[ISO_date]))<4),(((7-(WEEKDAY([WW_Index].[ISO_date],2)))+(DAY([WW_Index].[ISO_date])))>3)))
I also need to convert ISO week_year to Month. I found this formula but it does not work:
=MONTH(DATE(YEAR(C2),1,-2)-WEEKDAY(DATE(YEAR(C2),1,3))+D2*7)
Example: week 18, 2012 is the ISO week of Apr 30 through May 6, 2012. There is less that 4 April days in this week thus week 18, 2012 is in May.
Any help would be greatly appreciated.

I don't know access but you can do the first part (date to month) much more easily in excel with this formula
=MONTH(C2-WEEKDAY(C2-1)+4)
That should be easier to convert for access......
For the second part you are finding the Monday of the relevant week, hence you get the wrong month in some cases, the Thursday of the week (midpoint) should always be within the correct month so you can just add 3 to get that (-2 becomes 1), i.e.
=MONTH(DATE(YEAR(C2),1,1)-WEEKDAY(DATE(YEAR(C2),1,3))+D2*7)
I assume C2 is a date within the relevant year and D2 is the ISO week number
but probably better to have C2 containing the year, e.g. just 2013 and then you can use
=MONTH(DATE(C2,1,1)-WEEKDAY(DATE(C2,1,3))+D2*7)

Related

Convert a weeknumber to month and generate an chart

I have an sheet with the Table, having Column A in Calendar Week. I would like to generate an chart with x axis as month with the data available in the table.
Could anyone help me to code it ? I am struck how I can convert an weeknumber in the column to month.
Could anyone suggest, how I can generate a chart for these data with month in my x/axis. I am not getting an clue to do this. Any lead would be helpful.
This is a formula to convert the week number in cell A1 into month
=MONTH(DATE(2017,1,-2)-WEEKDAY(DATE(2017,1,3))+A1*7)
Note that you also need to know the year the week number refers to, because it can differ from year to year. In this example it is fixed to 2017.
Note that week number != week number.
There are different methods how week numbers are calculated.
This formula example is based on ISO week numbers, with a week starting on Monday and the week containing the 1st Thursday of the year is considered week 1. For example, in the year 2016, the first Thursday is January 7, and that is why week 1 begins on 4-Jan-2016.
Here is some info about week number calculation based on different week numbers: Week Numbers In Excel
You need to use the formula
=TEXT((((A1-1)*7)+DATE(2017,1,1)),"m")
This will turn the week number into a date, then extract the month number

SQL ORACLE Get week numbers from multiple datetime rows

I have 70.000 rows of data, including a date time column (YYYY-MM-DD HH24-MM-SS.).
I want to split this data into 3 separate columns; Hour, day and Week number.
The date time column name is 'REGISTRATIONDATE' from the table 'CONTRACTS'.
This is what I have so far for the day and hour columns:
SELECT substr(REGISTRATIONDATE, 0, 10) AS "Date",
substr(REGISTRATIONDATE, 11, 9) AS "Hour"
FROM CONTRACTS;
I have seen the options to get a week number for specific dates, this assignment concerns 70.000 dates so this is not an option.
You (the OP) still have to explain what week number to assign to the first few days in a year, until the first Monday of the year. Do you assign a week number for the prior calendar year? In a Comment I asked about January 1, 2017, as an example; that was a Sunday. The week from January 2 to January 8 of 2017 is "week 1" according to your definition; what week number do you assign to Sunday, January 1, 2017?
The straightforward calculation below assigns to it week number 0. Other than that, the computation is trivial.
Notes: To find the Monday of the week for any given date dt, we can use trunc(dt, 'iw'). iw stands for ISO Week, standard week which starts on Monday and ends on Sunday.
Then: To find the first Monday of the year, we can start with the date January 7 and ask for the Monday of the week in which January 7 falls. (I won't explain that one - it's easy logic and it has nothing to do with programming.)
To input a fixed date, the best way is with the date literal syntax: date '2017-01-07' for January 7. Please check the Oracle documentation for "date literals" if you are not familiar with it.
So: to find the week number for any date dt, compute
1 + ( trunc(dt, 'iw') - trunc(date '2017-01-07', 'iw') ) / 7
This formula finds the Monday of the ISO Week of dt and subtracts the first Monday of the year - using Oracle date arithmetic, where the difference between two dates is the number of days between them. So to find the number of weeks we divide by 7; and to have the first Monday be assigned the number 1, instead of 0, we need to add 1 to the result of dividing by 7.
The other issue you will have to address is to convert your strings into dates. The best solution would be to fix the data model itself (change the data type of the column so that it is DATE instead of VARCHAR2); then all the bits of data you need could be extracted more easily, you would make sure you don't have dates like '2017-02-29 12:30:00' in your data (currently, if you do, you will have a very hard time making any date calculations work), queries will be a lot faster, etc. Anyway, that's an entirely different issue so I'll leave it out of this discussion.
Assuming your REGISTRATIONDATE if formatted as 'MM/DD/YYYY'
the simples (and the faster ) query is based ond to to_char(to_date(REGISTRATIONDATE,'MM/DD/YYYY'),'WW')
(otherwise convert you column in a proper date and perform the conversio to week number)
SELECT substr(REGISTRATIONDATE, 0, 10) AS "Date",
substr(REGISTRATIONDATE, 11, 9) AS "Hour",
to_char(to_date(REGISTRATIONDATE,'MM/DD/YYYY'),'WW') as "Week"
FROM CONTRACTS;
This is messy, but it looks like it works:
to_char(
to_date(RegistrationDate,'YYYY-MM-DD HH24-MI-SS') +
to_number(to_char(trunc(to_date(RegistrationDate,'YYYY-MM-DD HH24-MI-SS'),'YEAR'),'D'))
- 2,
'WW')
On the outside you have the solution previous given by others but using the correct date format. In the middle there is an adjustment of a certain number of days to adjust for where the 1st Jan falls. The trunc part gets the first of Jan from the date, the 'D' gets the weekday of 1st Jan. Since 1 represents Sunday, we have to use -2 to get what we need.
EDIT: I may delete this answer later, but it looks to me that the one from #mathguy is the best. See also the comments on that answer for how to extend to a general solution.
But first you need to:
Decide what to do dates in Jan before the first Monday, and
Resolve the underlying problems in the date which prevent it being converted to dates.
On point 1, if assigning week 0 is not acceptable (you want week 52/53) it gets a bit more complicated, but we'll still be able to help.
As I see it, on point 2, either there is something systematically wrong (perhaps they are timestamps and include fractions of a second) or there are isolated cases of invalid data.
Either the length, or the format, or the specific values don't compute. The error message you got suggests that at least some of the data is "too long", and the code in my comment should help you locate that.

How can I Format the Date so that the fiscal week starts in December?

I want to format a date as follows: Y17W15, but there is no option to set the start of the year. However, there is no consistent way of calculating this. I cannot just subtract a month (other times I will need to show the month too), and I cannot just add 4 or 5 to the week field due to leap years, etc.
Our year starts on a Saturday that is closest to December 1. This means if November 30 is on a Saturday, the Fiscal Year will start on November 30.
Currently what I have is below, which works fine except it shows Y17W10. The easiest option in my head is to have a way to actually set the start of a fiscal year, but if I have to go through a bunch of if statements it's okay as long as it works.
MsgBox(Format(Now, """Y""yy""W""mm"""))
Thanks for your time!
I am aware that: Given a 4-5-4 calendar and a date, how do I determine what fiscal week that date falls in? exists but I am looking for an answer that isn't as hard-coded.
Michael

Datepart Week Sql (With 53 weeks for year)

I'm calculating the week for a specific date in SQL for example
'2016-01-20' (yyyy-mm-dd) but SQL returns week: 4, and that is wrong because this year the first week started on '2016-01-04' the result must be week: 3.
I think the issue is generatad because 2015 was a year with 53 weeks, any solution to that? Thank you and I'm sorry for my bad English
In tSQL the DATEPART() is returning the correct data based on US and Most of Europe as well as UK See here
You can use SET DATEFIRST to adjust the start position however.
The ISO 8601 definition for week 01 is the week with the year's first Thursday in it. I am using Intersystems cache which apparently does not account for that either. So I have used this to address that
CASE WHEN 7-datepart(dw,dateadd(dd,1,dateadd(yy,datediff(yy,0,getdate())-1,0))) < 2
THEN datepart(wk,getdate())-1 ELSE datepart(wk,getdate()) END as WeekNum

Access query (SQL) to return records sorted (grouped by) WEEKS

Greetings SQL gurus,
I don't know if you can help me, but I will try. I have several large databases grouped by year (each year in a different database). I want to be able to compare values from a particular week from one year to the next. For example, "show me week 17 of 2008 vs. week 17 of 2002."
I have the following definition of weeks that ideally I would use:
Only 52 weeks each year and 7 days a week (that only takes 364 days),
The first day of the first week starts from January 2nd - which means we do not use January 1st data, and
In leap year, the first day of the first week ALSO starts from the January 2nd plus we skip Feb. 29.
Any ideas?
Thanks in advance.
Best to avoid creating a table because then you have to update and maintain it to get your queries to work.
DatePart('ww',[myDate]) will give you the week number. You may run into some issues though deciding which week belongs to which year - for example if Jan 1 2003 is on Wednesday does the week belong as week 52 in 2002 or week 1 in 2003? Your accounting department will have a day of the week that is your end of week (usually Sat). I usually just pick the year that has the most days in it. DatePart will always count the first week as 1 and in the case of the example above the last week as 53. You may not care that much either way. You can create queries for each year
SELECT DatePart('ww',[myDate]) as WeekNumber,myYearTable.* as WeekNumber
FROM myYearTable
and then join the queries to get your data. You'll loose a couple days at the end of the year if one table has 52 weeks and one has 53 (most will show as 53). Or you can do it by your weekending day - this always gives you Saturday which would push a late week into the following year.
(7-Weekday([myDate]))+[myDate]
then
DatePart('ww',(7-Weekday([myDate]))+[myDate])
Hope that helps
To get the week number
'to get the week number in the year
select datepart( week, datefield)
'to get the week number in the month
select (datepart(dd,datefield) -1 ) / 7 + 1
You don't need to complicate things thinking about leap years, etc. Just compare weeks mon to sun
SInce you havea a specifc defintion of when the week starts that is differnt that the standard used by the db, I think a weeks table is the solution to your problem. For each year create a table that defines the dates contained in each week and the week number. Then by joining to that table as well as the relevant other tables, you can ask for just the data for week 17.
Table structure
Date Week
20090102 1
20090103 1
etc.
I needed to create a query that shows BOTH year AND week numbers, like 2014-52. The year shows correct when you use the Datepart() formula to convert week 53 to week 52 in the previous year, but shows the wrong year for the week that was week 1 previously that should be week 52 now. It show that week as 2015-52 instead of 2014-52.
Furthermore, it sorts the data wrong if you only use only the week number, eg:
2014-1,2014-11,2014-2
To overcome this I created the following query to insert a 0 and also to check for days in week 1 that should still fall under week 52.
ActualWeek: IIf(DatePart("ww",[SomeDate],1,3)=52 And DatePart("ww",[SomeDate])=1, DatePart("yyyy",[SomeDate],1,3)-1,DatePart("yyyy",[SomeDate],1,3)) & "-" & IIf(DatePart("ww",[SomeDate],1,3)<10,"0" & DatePart("ww",[SomeDate],1,3),DatePart("ww",[SomeDate],1,3))