深圳全飞鸿

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 720|回复: 9
打印 上一主题 下一主题

关于WW周别的计算

[复制链接]

800

主题

1379

帖子

7704

积分

版主

Rank: 7Rank: 7Rank: 7

积分
7704
跳转到指定楼层
楼主
发表于 2021-3-4 17:13:23 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
mysql关于周的几个函数:
  1. select WEEKDAY(str_to_date('20210104','%Y%m%d'))
  2. union
  3. select WEEK(str_to_date('20210104','%Y%m%d'),0)
  4. union
  5. select WEEK(str_to_date('20210104','%Y%m%d'),1)
  6. union
  7. select WEEKDAY(str_to_date('20210103','%Y%m%d'))
  8. union
  9. select DATE_FORMAT(str_to_date('20210101','%Y%m%d'),'%Y-%u')
  10. union
  11. select DATE_FORMAT(str_to_date('20210101','%Y%m%d'),'%Y-%U')
  12. union
  13. select WEEKOFYEAR(str_to_date('20210101','%Y%m%d'))
复制代码


结果:


首先,WEEKOFYEAR确实不太合理,因为2021-01-01的结果是53


再看WEEK,主要是一个星期是从周一开始,还是从周日开头的,有一个mode参数可以控制!




客户的计算要求:


WEEKDAY的值是0~6  



  1. DELIMITER $

  2. DROP FUNCTION IF EXISTS `smt`.`DATE_IW`$

  3. CREATE DEFINER=`root`@`%` FUNCTION `DATE_IW`(
  4.       dt  date
  5.    ) RETURNS varchar(3) CHARSET utf8
  6.     NO SQL
  7. BEGIN
  8.       
  9.         declare tmp varchar(5);
  10.         declare ywd11 datetime;
  11.         declare ww int;

  12.   set ywd11:= str_to_date(concat(year(dt),'-01-01'),'%Y-%m-%d');

  13.         set ww:= WEEK(dt,1);
  14.         if(WEEKDAY(ywd11)<>0) then
  15.                 set ww:=ww+1;
  16.         end if;

  17.   return  lpad(ww,2,'0');

  18. END$

  19. DELIMITER ;
复制代码

回复

使用道具 举报

800

主题

1379

帖子

7704

积分

版主

Rank: 7Rank: 7Rank: 7

积分
7704
沙发
 楼主| 发表于 2021-7-7 11:27:48 | 只看该作者



回复 支持 反对

使用道具 举报

800

主题

1379

帖子

7704

积分

版主

Rank: 7Rank: 7Rank: 7

积分
7704
板凳
 楼主| 发表于 2021-7-7 11:33:32 | 只看该作者

2021_philips_calendar_a4.pdf
回复 支持 反对

使用道具 举报

800

主题

1379

帖子

7704

积分

版主

Rank: 7Rank: 7Rank: 7

积分
7704
地板
 楼主| 发表于 2023-2-10 12:04:44 | 只看该作者
华为年周码的定义

回复 支持 反对

使用道具 举报

228

主题

466

帖子

2184

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2184
5#
发表于 2024-10-24 15:13:15 | 只看该作者
本帖最后由 syant 于 2024-10-24 15:14 编辑

关于WEEKOFYEAR

在MySQL中,WEEKOFYEAR()函数用于返回一年中的第几周。这个函数的计算规则基于ISO 8601标准,该标准定义了一周从周一开始,并且第一周是包含至少四天的那一周。
具体来说,WEEKOFYEAR()函数的计算规则如下:
  • 一年的第一周是包含该年的第一个周四的那周。
  • 如果1月1日是周五、周六或周日,那么第一周将是包含1月4日(即第一个周四)的那周。
  • 对于其他日期,WEEKOFYEAR()将返回该日期所在的周数。
例如:
  1. SELECT WEEKOFYEAR('2021-01-01'); -- 返回52,因为2021年的第一周是从2020年12月27日开始的。
  2. SELECT WEEKOFYEAR('2021-01-04'); -- 返回1,因为这一天是2021年的第一周的一部分。
复制代码

此外,WEEKOFYEAR()函数还可以接受一个可选的模式参数,用来指定周的起始日和是否考虑周为7天还是自然周。模式参数可以是以下值之一:
  • 0: 周日作为一周的第一天,不使用ISO 8601标准(默认)。
  • 1: 周一作为一周的第一天,不使用ISO 8601标准。
  • 2: 周日作为一周的第一天,使用ISO 8601标准。
  • 3: 周一作为一周的第一天,使用ISO 8601标准。
例如:
  1. <font color="rgb(198, 120, 221)">SELECT</font> WEEKOFYEAR(<font color="rgb(152, 195, 121)">'2021-01-01'</font>, <font color="rgb(209, 154, 102)">3</font>); <font color="rgb(127, 138, 159)"><i>-- 返回52,使用ISO 8601标准,以周一为一周的开始。</i></font>
复制代码
这些规则确保了WEEKOFYEAR()函数能够根据不同的需求灵活地计算一年中的周数。

回复 支持 反对

使用道具 举报

228

主题

466

帖子

2184

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2184
6#
发表于 2024-10-25 09:23:24 | 只看该作者

回复 支持 反对

使用道具 举报

228

主题

466

帖子

2184

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2184
7#
发表于 2024-10-25 10:03:22 | 只看该作者

  1. <?php
  2. // 输入日期
  3. $date = '2023-10-05';

  4. // 创建DateTime对象
  5. $dt = new DateTime($date);

  6. // 设置ISO日期
  7. $dt->setISODate($dt->format('o'), $dt->format('W'));

  8. // 输出结果
  9. echo "The first day of the ISO week for $date is: " . $dt->format('Y-m-d') . "\n";
  10. ?>
复制代码


回复 支持 反对

使用道具 举报

228

主题

466

帖子

2184

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2184
8#
发表于 2024-10-25 11:13:52 | 只看该作者
  1. select '2019-12-27' DT, YEAR('2019-12-27'),DATE_FORMAT('2019-12-27', '%Y'),WEEK('2019-12-27',2), DAYOFWEEK('2019-12-27'), WEEKOFYEAR('2019-12-27')
  2. union
  3. select '2019-12-28',YEAR('2019-12-28'),DATE_FORMAT('2019-12-28', '%Y'),WEEK('2019-12-28',2), DAYOFWEEK('2019-12-28'), WEEKOFYEAR('2019-12-28')
  4. union
  5. select '2019-12-29',YEAR('2019-12-29'),DATE_FORMAT('2019-12-29', '%Y'),WEEK('2019-12-29',2), DAYOFWEEK('2019-12-29'), WEEKOFYEAR('2019-12-29')
  6. union
  7. select '2019-12-30',YEAR('2019-12-30'),DATE_FORMAT('2019-12-30', '%Y'),WEEK('2019-12-30',2), DAYOFWEEK('2019-12-30'), WEEKOFYEAR('2019-12-30')
  8. union
  9. select '2019-12-31',YEAR('2019-12-31'),DATE_FORMAT('2019-12-31', '%Y'),WEEK('2019-12-31',2), DAYOFWEEK('2019-12-31'), WEEKOFYEAR('2019-12-31')
  10. union
  11. select '2020-01-01',YEAR('2020-01-01'),DATE_FORMAT('2020-01-01', '%Y'),WEEK('2020-01-01',2), DAYOFWEEK('2020-01-01'), WEEKOFYEAR('2020-01-01')
  12. union
  13. select '2020-01-02',YEAR('2020-01-02'),DATE_FORMAT('2020-01-02', '%Y'),WEEK('2020-01-02',2), DAYOFWEEK('2020-01-02'), WEEKOFYEAR('2020-01-02')
  14. union
  15. select '2020-01-03',YEAR('2020-01-03'),DATE_FORMAT('2020-01-03', '%Y'),WEEK('2020-01-03',2), DAYOFWEEK('2020-01-03'), WEEKOFYEAR('2020-01-03')
  16. union
  17. select '2020-01-04',YEAR('2020-01-04'),DATE_FORMAT('2020-01-04', '%Y'),WEEK('2020-01-04',2), DAYOFWEEK('2020-01-04'), WEEKOFYEAR('2020-01-04')
复制代码

回复 支持 反对

使用道具 举报

228

主题

466

帖子

2184

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2184
9#
发表于 2024-10-25 14:29:09 | 只看该作者
https://www.php.net/manual/zh/datetime.format.php

format 参数字符串可以识别以下字符
[td]
format 字符
说明
返回值示例
------
d月份中的第几天,有补零的两位数字01 到 31
D文字表示星期几,三个字母Mon 到 Sun
j月份中的第几天,没有补零1 到 31
l(小写 'L')完整文本表示星期几Sunday 到 Saturday
NISO 8601 数字表示星期几1(星期一)到 7(星期天)
S月份中的第几天英文后缀,两个字符st、nd、rd 或 th。可以和 j 一起使用
w数字表示星期几0(星期天)到 6(星期六)
z一年中的第几天(从 0 开始)0 到 365
------
WISO 8601 格式当年中的第几周,每周从周一开始示例:42(当年的第 42 周)
------
F月份的完整文本表示,比如 January 或者 MarchJanuary 到 December
m月份的数字表示,补零01 到 12
M简短文本表示月份,三个字母Jan 到 Dec
n数字表示几月份,不补零1 到 12
t指定月份的天数28 到 31
------
L是否是闰年如果是闰年为 1,否则为 0。
oISO 8601 数字年份表示。这和 Y 值相同,但如果 ISO 周数(W)属于上一年或者下一年,则用那一年。示例:1999 或 2003
X年份的展开全数字表示,至少四位,- 表示公元前,+ 表示公元。示例:-0055、+0787、 +1999、+10191
x如果需要,年份可以展开全数字表示,如果可能的话,也可以用标准的全数字(Y)表示。至少有四位数字。公元前以 - 为前缀,年份不小于 10000 时以 + 为前缀。示例:-0055, 0787, 1999, +10191
Y年份完整数字表示,至少四位,使用 - 表示公元前。示例:-0055、0787、 1999、2003、10191
y两位数的年份表示示例:99 或 03
时间
------
a小写的上午和下午am 或 pm
A大写的上午和下午AM 或 PM
BSwatch 互联网时间000 到 999
g不补零的小时(12 小时制)1 到 12
G不补零的小时(24 小时制)0 到 23
h补零的小时(12 小时制)01 到 12
H补零的小时(24 小时制)00 到 23
i补零的分钟00 到 59
s补零的秒00 到 59
u微秒。注意 date() 总是生成 000000,因为它需要一个 int 参数,而如果 DateTimeInterface 是使用微秒创建的,则 DateTimeInterface::format() 支持微秒。示例:654321
v毫秒。与 u 的说明相同。示例:654
时区
------
e时区标识符示例:UTC、GMT、Atlantic/Azores
I(大写 i)是否为夏令时如果是夏令时为 1,否则为 0。
O跟格林尼治时间(GMT)的差异,小时和分钟时间没有冒号示例:+0200
P跟格林尼治时间(GMT)的差异,小时和分钟时间有冒号示例:+02:00
p跟 P 相同,区别是使用 Z 替换 +00:00 返回(PHP 8.0.0 起可用)示例:Z 或 +02:00
T如果知道会返回时区缩写,否则返回 GMT 时差。示例:EST、MDT、+05
Z以秒为单位的时差。UTC 以西的时区为负的时差,以东为正的时差。-43200 到 50400
完整日期/时间
------
cISO 8601 日期2004-02-12T15:19:21+00:00
r» RFC 2822/» RFC 5322 格式化时间示例:Thu, 21 Dec 2000 16:01:07 +0200
U从 Unix 纪元(January 1 1970 00:00:00 GMT)到至今的秒数参见 time()

回复 支持 反对

使用道具 举报

228

主题

466

帖子

2184

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2184
10#
发表于 2024-12-28 20:37:44 | 只看该作者

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|nagomes  

GMT+8, 2025-5-4 21:11 , Processed in 0.040260 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表