几周


13

您的任务是输出一个数字。给定日期范围相交的ISO周数。引用Wikipedia:,An average year is exactly 52.1775 weeks long但这不是平均值。

输入由两个以空格分隔的ISO日期组成:

0047-12-24 2013-06-01

结束日期永远不会早于开始日期。为了简单起见,我们将使用外推的格里高利历。

测试用例:

Format: input -> output
2015-12-31 2016-01-01 -> 1    (both are within week 53 of 2015)
2016-01-03 2016-01-04 -> 2    (the 3rd is within week 53, and the 4th is in week 1)
2015-12-24 2015-12-24 -> 1    (this single day is of course within a single week)

您的解决方案应处理介于0001-01-01和之间的日期9999-12-31


2
输入可以是字符串数组,而不是单个空格分隔的字符串吗?或者,两个日期可以是函数的两个参数吗?
门把手

我认为您的意思是公历
布拉德·吉尔伯特b2gills 2015年

另外,星期几是从星期日还是星期一开始?根据您的第二个测试用例,它是星期一,但请确保。
门把手

@Doorknobice Wikipedia引用:“日期由ISO星期编号的年份指定,格式为YYYY,以ww开头的格式为w,并以字母“ W”为前缀,而星期几则是从1到7的数字d。 ,从星期一开始,以星期日结束”,因此按照ISO 8601
Tensibai

2
根据ISO标准,Weeks start with Monday.
菲利普Haglund

Answers:


2

Ruby 89 88 86字节

->s{a,b=s.split.map{|x|Time.gm *x.split(?-)}
n=1
(a+=86400).wday==1&&n+=1until a==b
n}

一个非常原始的解决方案:给定的第一个日期a和第二日期b,增量a,检查它是否是一个星期一(如果是这样,我们已经“翻身”,以新的一周),并停止一次ab

以问题中指定的确切格式进行输入:单个空格分隔的字符串。(它解析输入的方式很花哨:它使用Ruby的“ splat”运算符*。该运算符“扩展”数组或可枚举的数组,因此Time.gm *[2013, 06, 01]成为Time.gm 2013, 06, 01。)

从评论讨论中导入:

我们不在乎“一年中的几周”;我们只关心“整体周”。因此,一年是52周还是53周,没有任何区别。

只是为了避免将来对这是否能正确处理年份界限感到困惑- 根据Wikipedia的说法,所有星期始终在星期一开始,在星期日结束。

对于一些更花哨的技巧,这些都是等效的:

until a==b;a+=86400;n+=a.wday==1?1:0;end
[a+=86400,n+=a.wday==1?1:0]until a==b
n+=(a+=86400).wday==1?1:0 until a==b
(a+=86400).wday==1&&n+=1 until a==b
(a+=86400).wday==1&&n+=1until a==b

您不能保存1个字符替换a==ba<b吗?
2015年

1

VBA,125字节

需要2个函数输入作为字符串

Function u(k,j)
f=DateValue(k)
For i=0 To (DateValue(j)-f)
q=DatePart("ww",f+i,2,2)
If q<>j Then u=u+1
j=q
Next
End Function

可以肯定,这可以打高尔夫球。这每天在两个日期之间循环,并且每次ISO日期更改时都会递增计数器。

DatePart("ww",f+i,2,2)是VBA中的ISO周编号,前2位表示Monday (complies with ISO standard 8601, section 3.17)。然后第二个2表示Week that has at least four days in the new year (complies with ISO standard 8601, section 3.17)

140个字节(带单个输入)

Function g(k)
y=Split(k)
f=DateValue(y(0))
For i=0 To (DateValue(y(1))-f)
q=DatePart("ww",f+i,2,2)
If q<>j Then g=g+1
j=q
Next
End Function

1

R,76个字节

d=as.Date(scan("","raw"));sum(strftime(seq(d[1],d[2],"day")[-1],"%w")==1)+1

在与@Doorknob交谈之后,最终就像计算星期一一样容易。

seq 允许创建日期向量(两个日期之间的每一天),并将strftime转换为“一周中的天数”,现在将其计数为1,以获取更改星期的时间并将其加1考虑上周。

另一种循环方法:

R,85个字节

n=1;d=as.Date(scan("","raw"));z=d[1];while(z<d[2]){n=n+(strftime(z<-z+1,"%w")==1)};n

1
关于第二种方法,如果第一个日期不是星期一,则只应在星期一总数中加1。
DavidC

@DavidCarraher谢谢,阅读您的回答使我认为我可以消除射程的第一天,从而解决问题:)
Tensibai 2015年

0

Mathematica 135 79 96 84 74字节

与@Doorknob的建议一致,

  • 生成范围内的所有日期

  • 计算(不包括)中的星期一数(ISOWeekDay==“ 1” ),并且DateRanged

  • 添加1到总数中。


Count[DateString[#,"ISOWeekDay"]&/@Rest@(DateRange@@StringSplit@#),"1"]+1&

Count[DateString[#,"ISOWeekDay"]&/@Rest@(DateRange@@StringSplit@#),"1"]+1&
/@ {"2015-12-31 2016-01-01", "2016-01-04 2016-01-05","2016-01-03 2016-01-04", 
"2015-12-24 2015-12-24", "1876-12-24 2016-01-01"}

{1,1,2,1,7255}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.