bash shell脚本中的一年

hjzp0vay  于 7个月前  发布在  Shell
关注(0)|答案(2)|浏览(91)

我想在bash脚本中计算一年中的周数。一周从星期日开始。对于日历年2019,应相应地计算53个日历周。
日历周1从2018年12月30日星期日开始。
日历周53从2019年12月29日星期日开始。
shell脚本给出的结果为52. %U week number of year, with Sunday as first day of week (00..53)

#!/bin/bash

week=$(date --date='2019-12-31' +%U)
echo $week

字符串

lztngnrs

lztngnrs1#

你说的“一年中的周数”是什么意思?
它是由那一年的日期组成的星期数吗?(51-52)
它是一年中超过一半的天数的周数(52-53,ISO定义,如果周从星期一开始)吗?
它是那一年中包含 * 任何 * 日期的周数吗?(53-54)
根据你的选择,你会得到三个不同的答案。这些选项都有不同的“周数”,但即使在每个选项中,你也必须选择周是从周日还是周一开始,以及第一周是第0周还是第1周。
请注意,如果你计算跨年的周数,只有中间的选项会得到正确的答案;第一个选项会忽略重叠两年的周数,而第三个选项会将这些周数包括两次。
听起来你想要第三个选择(给定年份中有 any 天的周数),其中周从星期日开始。这几乎是date +%U,除了1月的第一个星期日之前的几天被视为第0周而不是第1周的一部分,所以周的总数几乎总是比12月31日的周数多一个。(当一年从星期日开始时,没有额外的一周),您可以轻松检查以确保添加是必要的:

countWeeks() {
    local year=$1

    local lastweek=$(date +%U -d "$year-12-31")
    local firstweek=$(date +%U -d "$year-01-01")
    # Note: the above is for GNU date(1); for BSD/macOS:
    # local lastweek=$(date -j +%U "12311200$year")
    # local firstweek=$(date -j +%U "01011200$year")
   
    if (( firstweek == 0 )); then
       (( lastweek += 1 ))
    fi
    printf '%d\n' "$lastweek"    
}

字符串
这将得到所需的结果:

$ y=2019
$ printf '%d has %d weeks\n' "$y" "$(countWeeks "$y")"
2019 has 53 weeks


我不知道这有多大用处;在一个给定的世纪内,按照这种计算方法,每28年中有27年将有53周,其余的--如2000年和2028年--将有54周。
1百年闰年规则将数字从27/28整体提升到387/400。

vlju58qv

vlju58qv2#

这可能是你想要的,使用GNU date:

y=2017; date -d "$y-12-31 -$(date -d "$y-12-31" +'%w') day" '+%U'

字符串
它使用date -d "$y-12-31" +'%w'计算出一年中最后一天的工作日编号(从Sun=0开始),然后从一年中的最后一个日期中减去该天数,该日期支持我们打印%U的日期,直到第一个星期日,如果它不是星期日,即它将打印一年中最后一个星期日的星期编号。
这里有一个测试:

$ for (( y=2010; y<=2020; y++ )) do
    date -d "$y-12-31 -$(date -d "$y-12-31" +'%w') day" '+%U %F %A'
done
52 2010-12-26 Sunday
52 2011-12-25 Sunday
53 2012-12-30 Sunday
52 2013-12-29 Sunday
52 2014-12-28 Sunday
52 2015-12-27 Sunday
52 2016-12-25 Sunday
53 2017-12-31 Sunday
52 2018-12-30 Sunday
52 2019-12-29 Sunday
52 2020-12-27 Sunday


如果这不能达到你想要的效果,那么请编辑你的问题,告诉我们一两年内它失败的地方,以及为什么这是错误的方法。

相关问题