简体   繁体   English

去年同一天的同一天

[英]Get same day of the same week last year

I'm looking for a way to get the same last year's day for a specific date. 我正在寻找一种方法来获得特定日期的去年同一天。

I have a table with date's and want in a second column the same day but last year's same day. 我有一张带日期的表格,并希望在同一天的第二列,但去年同一天。

Example: Date: Monday 01 June 2009 Last year Date: Monday 02 June 2008 示例:日期:2009年6月1日星期一去年日期:2008年6月2日星期一

So it has to be the same day of the same week but 1 year earlier. 因此它必须是同一周的同一天,但提前一年。

Is there a way of doing this? 有办法做到这一点吗?

Thanks for the help? 谢谢您的帮助?

Try: 尝试:

select add_months(sysdate, -12) + (to_char(sysdate, 'D') - to_char(add_months(sysdate, -12), 'D'))
from dual

Output: 输出:

6/10/2014 12:07:01 PM

Which is also a Tuesday like today. 这也是今天的星期二。

You can use this one: 你可以用这个:

SELECT 
    NEXT_DAY(ADD_MONTHS(DATE '2009-06-01', -12)-1, TO_CHAR(DATE '2009-06-01', 'fmDAY')) AS Last_year_day 
FROM dual;

Result: 结果:

2008-06-02

Of course, it always returns the next day, ie in worst case 6 days later. 当然,它总是在第二天返回,即在最差的情况下6天后返回。

Assume by "week" you mean the week as defined by ISO-8601, you can use a function which converts the week number to a date. 假设“周”表示ISO-8601定义的周,您可以使用将周数转换为日期的函数。

CREATE FUNCTION IsoWeekDate(iso_year IN INTEGER, iso_week IN INTEGER) RETURN DATE AS
BEGIN
   RETURN TRUNC(TO_DATE(iso_year || '0104', 'YYYYMMDD'), 'IW') + 7 * (iso_week - 1);
END IsoWeekDate;

Then you can do it like this: 然后你可以这样做:

SELECT 
   NEXT_DAY(IsoWeekDate(TO_CHAR(DATE '2009-06-01', 'IYYY')-1, TO_CHAR(DATE '2009-06-01', 'IW'))-1, TO_CHAR(DATE '2009-06-01', 'fmDAY'))
FROM YOUR_TABLE

Of course, you can write all in one in SQL, I split it only for better visibility. 当然,您可以在SQL中编写所有内容,我将其拆分以获得更好的可见性。

Note, for dates between 29th of December and 3rd of January you may get unexpected results when you use this approach, because a year can have 52 or 53 weeks and these dates can belong to previous, resp. 请注意,对于12月29日到1月3日之间的日期,当您使用此方法时,您可能会得到意想不到的结果,因为一年可以有52或53周,这些日期可以属于之前的,相应的。 next year. 明年。

SQL Fiddle SQL小提琴

Oracle 11g R2 Schema Setup : Oracle 11g R2架构设置

CREATE FUNCTION TO_ISO_WEEK_DATE(
  week        NUMBER,
  year        NUMBER
) RETURN DATE DETERMINISTIC
IS
BEGIN
  RETURN NEXT_DAY(
          TO_DATE( TO_CHAR( year, '0000' ) || '0104', 'YYYYMMDD' )
            - INTERVAL '7' DAY, 'MONDAY'
         )
         + ( week - 1 ) * 7;
END TO_ISO_WEEK_DATE;
/

CREATE FUNCTION SAME_DAY_AND_WEEK_OF_YEAR(
  dt   DATE,
  year NUMBER
) RETURN DATE DETERMINISTIC
IS
  p_week NUMBER(2,0) := TO_NUMBER( TO_CHAR( dt, 'IW' ) );
  p_day  VARCHAR2(9) := TO_CHAR( dt, 'DAY' );
BEGIN
  RETURN NEXT_DAY( TO_ISO_WEEK_DATE( p_week, year ) - 1, p_day );
END SAME_DAY_AND_WEEK_OF_YEAR;
/

Query 1 : 查询1

SELECT TO_CHAR( SYSDATE + LEVEL - 1, 'YYYY-MM-DD (IW-D)' ) AS "Date 2015",
       TO_CHAR( SAME_DAY_AND_WEEK_OF_YEAR( SYSDATE + LEVEL - 1, 2014 ), 'YYYY-MM-DD (IW-D)' ) AS "Date 2014",
       TO_CHAR( SAME_DAY_AND_WEEK_OF_YEAR( SYSDATE + LEVEL - 1, 2013 ), 'YYYY-MM-DD (IW-D)' ) AS "Date 2013",
       TO_CHAR( SAME_DAY_AND_WEEK_OF_YEAR( SYSDATE + LEVEL - 1, 2012 ), 'YYYY-MM-DD (IW-D)' ) AS "Date 2012",
       TO_CHAR( SAME_DAY_AND_WEEK_OF_YEAR( SYSDATE + LEVEL - 1, 2011 ), 'YYYY-MM-DD (IW-D)' ) AS "Date 2011"
FROM   DUAL
CONNECT BY LEVEL <= 7

Results : 结果

|         Date 2015 |         Date 2014 |         Date 2013 |         Date 2012 |         Date 2011 |
|-------------------|-------------------|-------------------|-------------------|-------------------|
| 2015-06-12 (24-6) | 2014-06-13 (24-6) | 2013-06-14 (24-6) | 2012-06-15 (24-6) | 2011-06-17 (24-6) |
| 2015-06-13 (24-7) | 2014-06-14 (24-7) | 2013-06-15 (24-7) | 2012-06-16 (24-7) | 2011-06-18 (24-7) |
| 2015-06-14 (24-1) | 2014-06-15 (24-1) | 2013-06-16 (24-1) | 2012-06-17 (24-1) | 2011-06-19 (24-1) |
| 2015-06-15 (25-2) | 2014-06-16 (25-2) | 2013-06-17 (25-2) | 2012-06-18 (25-2) | 2011-06-20 (25-2) |
| 2015-06-16 (25-3) | 2014-06-17 (25-3) | 2013-06-18 (25-3) | 2012-06-19 (25-3) | 2011-06-21 (25-3) |
| 2015-06-17 (25-4) | 2014-06-18 (25-4) | 2013-06-19 (25-4) | 2012-06-20 (25-4) | 2011-06-22 (25-4) |
| 2015-06-18 (25-5) | 2014-06-19 (25-5) | 2013-06-20 (25-5) | 2012-06-21 (25-5) | 2011-06-23 (25-5) |

Just add 364 whether it is a leap year or not eg 只需添加364,无论是否是闰年,例如

select
to_char(to_date('24/01/2016','dd/mm/yyyy'),'DAY DD/MM/YYYY') as CrossesLeapYear_PivotDate,
to_char(add_months(to_date('24/01/2016','dd/mm/yyyy'),12), 'DAY DD/MM/YYYY') as CrossesLeapYear_NextYearDate,
to_char(to_date('24/01/2016','dd/mm/yyyy') + 364, 'DAY DD/MM/YYYY') as CrossesLeapYear_SameNextYear,
to_char(to_date('24/01/2017','dd/mm/yyyy'),'DAY DD/MM/YYYY') as NoLeapYear_PivotDate,
to_char(add_months(to_date('24/01/2017','dd/mm/yyyy'),12), 'DAY DD/MM/YYYY') as NoLeapYear_NextYearDate,
to_char(to_date('24/01/2017','dd/mm/yyyy') + 364, 'DAY DD/MM/YYYY') as NoLeapYear_SameNextYear
from dual

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM