gnuplot:如何获得正确的周数?

the*_*ozh 5 gnuplot week-number

从这个问题起源的gnuplot为什么警告:不好的时候格式字符串,有在gnuplot的一周号码使用时间说明符的发现%W%U是错在某些情况下。

显然,周数有不同的定义。此外,一周开始时有不同的定义,例如星期日或星期一。常用的周数定义之一(但不在美国和其他一些国家/地区使用)是根据 ISO 8601 定义的。

代码:(说明错误的周数)

### wrong week numbering in gnuplot with %W and %U
reset session

StartDate = "24.12.2020"
myTimeFmt = "%d.%m.%Y"
SecondsPerDay = 3600*24

print "      date   %a  %w  %d   %j  %W  %U"
print "===================================="
do for [i=0:20] {
    t = strptime(myTimeFmt,StartDate) + i*SecondsPerDay
    myDate = strftime(myTimeFmt."  %a  %w  %d  %j  %W  %U", t)
    print sprintf("%s", myDate)
}
### end of code
Run Code Online (Sandbox Code Playgroud)

gnuplot 时间说明符:

%a abbreviated name of day of the week
%w day of the week, 0–6 (Sunday = 0)
%d day of the month, 01–31
%j day of the year, 1–366 
%W week of the year (week starts on Monday)
%U week of the year (week starts on Sunday)
Run Code Online (Sandbox Code Playgroud)

结果:

      date   %a  %w  %d   %j  %W  %U
====================================
24.12.2020  Thu  04  24  359  52  52
25.12.2020  Fri  05  25  360  52  52
26.12.2020  Sat  06  26  361  52  52
27.12.2020  Sun  00  27  362  52  53
28.12.2020  Mon  01  28  363  53  53
29.12.2020  Tue  02  29  364  53  53
30.12.2020  Wed  03  30  365  53  53
31.12.2020  Thu  04  31  366  53  53
01.01.2021  Fri  05  01  001  01  01   ???
02.01.2021  Sat  06  02  002  01  01   ???
03.01.2021  Sun  00  03  003  00  01   ???
04.01.2021  Mon  01  04  004  01  01
05.01.2021  Tue  02  05  005  01  01
06.01.2021  Wed  03  06  006  01  01
07.01.2021  Thu  04  07  007  01  01
08.01.2021  Fri  05  08  008  01  01
09.01.2021  Sat  06  09  009  01  01
10.01.2021  Sun  00  10  010  01  02
11.01.2021  Mon  01  11  011  02  02
12.01.2021  Tue  02  12  012  02  02
13.01.2021  Wed  03  13  013  02  02
Run Code Online (Sandbox Code Playgroud)

问题:是否有解决方法来解决此问题?

the*_*ozh 2

根据这里的描述: https: //en.wikipedia.org/wiki/ISO_week_date,我猜 ISO 8601 定义的本质是:

  1. 一周从星期一开始
  2. 第 01 周是一年中第一个星期四的那一周
  3. 一周属于一年中,其大部分天数位于
  4. 从星期四开始或结束的年份有 53 周,其他年份有 52 周

代码:

### correct week number according to ISO 8601
reset session

dow(t)      = int(tm_wday(t)) ? tm_wday(t) : 7                               # day of week 1=Mon, ..., 7=Sun
week(t)     = int((11 + tm_yday(t) - dow(t))/7)                              # "raw"week of year
wday(d,m,y) = tm_wday(strptime("%d.%m.%Y",sprintf("%02d.%02d.%04d",d,m,y)))  # week day of certain date
wpy(y)      = wday(1,1,y)==4 || wday(31,12,y)==4 ? 53 : 52                   # weeks per year
woy(t)      = week(t) < 1 ? wpy(tm_year(t)-1) : \
              week(t) > wpy(tm_year(t)) ? 1 : week(t)                        # week of year
yow(t)      = int(week(t) < 1 ? tm_year(t)-1 : week(t) > wpy(tm_year(t)) ? \
              tm_year(t)+1 : tm_year(t))                                     # year of week (could be previous, current or next)

StartDate = "24.12.2020"
myTimeFmt = "%d.%m.%Y"
SecondsPerDay = 3600*24

print "      date   %a DoW  %d   %j   YoW WoY"
print "======================================"
do for [i=0:20] {
    t = strptime(myTimeFmt,StartDate) + i*SecondsPerDay
    myDate = strftime(myTimeFmt."  %a", t)
    myDate2 = strftime("%d  %j", t)
    print sprintf("%s  %02d  %s  %04d-W%02d", myDate, dow(t), myDate2, yow(t), woy(t))
}
### end of code
Run Code Online (Sandbox Code Playgroud)

结果:

      date   %a DoW  %d   %j   YoW WoY
======================================
24.12.2020  Thu  04  24  359  2020-W52
25.12.2020  Fri  05  25  360  2020-W52
26.12.2020  Sat  06  26  361  2020-W52
27.12.2020  Sun  07  27  362  2020-W52
28.12.2020  Mon  01  28  363  2020-W53
29.12.2020  Tue  02  29  364  2020-W53
30.12.2020  Wed  03  30  365  2020-W53
31.12.2020  Thu  04  31  366  2020-W53
01.01.2021  Fri  05  01  001  2020-W53
02.01.2021  Sat  06  02  002  2020-W53
03.01.2021  Sun  07  03  003  2020-W53
04.01.2021  Mon  01  04  004  2021-W01
05.01.2021  Tue  02  05  005  2021-W01
06.01.2021  Wed  03  06  006  2021-W01
07.01.2021  Thu  04  07  007  2021-W01
08.01.2021  Fri  05  08  008  2021-W01
09.01.2021  Sat  06  09  009  2021-W01
10.01.2021  Sun  07  10  010  2021-W01
11.01.2021  Mon  01  11  011  2021-W02
12.01.2021  Tue  02  12  012  2021-W02
13.01.2021  Wed  03  13  013  2021-W02
Run Code Online (Sandbox Code Playgroud)

为了使用周数,例如作为时间轴标签,最好将其实现为%W. 无意中,SourceForge最近出现了一个错误报告。因此,我认为它很快就会在下一个版本中得到修复。

  • 是的,现在 gnuplot git 存储库中修复了 %W 格式。据我了解 ISO 8601“周日期”标准,您列出的四个属性都是基本定义“一年的第一周从最接近该年 1 月 1 日的星期一开始”的推论。 (3认同)