查找一年中每个月的最后一个星期日


21

在140个字符内已知F#解决方案,这是Rosetta代码问题。

输入年份的标准输出或字符串变量中的必需结果2014

2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28

根据要求,在1900年:

1900-01-28 1900-02-25 1900-03-25 1900-04-29 1900-05-27 1900-06-24 1900-07-29 1900-08-26 1900-09-30 1900-10-28 1900-11-25 1900-12-30

和2000:

2000-01-30 2000-02-27 2000-03-26 2000-04-30 2000-05-28 2000-06-25 2000-07-30 2000-08-27 2000-09-24 2000-10-29 2000-11-26 2000-12-31

之所以如此,是因为大多数语言中的日期似乎都带来了尴尬。除了允许日期库,我希望能看到它们!但是,如果在基本语言之外,请在帖子名称中声明(例如C#+ Jon Skeet的NodaTime)。

说明:

  • 年份范围1900至3015
  • 阳历日历
  • 如果其他方面不重要,则英国/伦敦的常规做法。
  • 使用命令行开关或stdin的程序很好,将结果生成到stdout
  • 取年份值并返回字符串的函数也很好。

不包括标准漏洞。期待APL,J,K解决方案,并看到一些新的日期库。


@ Sp3000-1752可能特别尴尬:-)
吱吱作响的ossifrage

@MartinBüttner:请使用日期库,已编辑问题,要求人们声明他们使用的语言。
Phil H

1
您应该指定有效输入的年份范围,以及有关采用格里高利历法的注意事项。(即,如果年份范围包括1930年之前的年份,则您应该指定在整个范围中使用公历,而与语言环境无关;或者输出可能会因语言环境而异;或者您应给出一个截止日期,在此之前则应使用儒略历(Julian calendar),并在转换后的三年内使用测试用例)。
彼得·泰勒

1
@squeamishossifrage:我将其限制为1900年和Gregorian,因为我宁愿避免建立规范的研究项目...
Phil H

1
@Adám:很抱歉让您等了这么长时间:)确实可以。
Phil H

Answers:


1

带有 来自dfns的cal的Dyalog APL,19 个字节

迟到总比不到好!

提示输入年份,以yyyy md格式返回日期列表。

⎕{⍺⍵,2↑⊢⌿cal⍺⍵}¨⍳12

提示输入数字,并将其设为

{... 匿名函数(在下面找到)应用于每个

⍳12 数字从1到12(月)

上面的匿名函数如下:

⍺⍵, 前置左右参数(即年份和月份)为

2↑ 的前两个字符

⊢⌿ 最底行

cal 的日历

⍺⍵ 左参数和右参数(年和月)

在线TryAPL:

  1. 单击此处导入cal及其依赖项后,返回此页面。

  2. 单击此处运行测试用例。


很好。希望有一个APL库能够理解日期的含义,但是cal是合理的!
Phil H

@PhilH 日期日期
亚当

1
@PhilH还有MiServer 的Dates命名空间
2013年

1
@PhilH和Dyalog APL的二元图元,+ - < = 与.Net日期对象一起使用
2013年

7

Ruby,91 + 6 = 97

#!ruby -prdate
$_=(Date.new(y=$_.to_i)...Date.new(y+1)).select(&:sunday?).chunk(&:mon).map{|k,v|v[-1]}*' '

效果很好。select(&:sunday?)很漂亮,而且令人惊讶的是,*' '它本身进行了所有格式化。


不错的把戏!您可以使用chunk代替来保存三个字符group_by
Cristian Lupascu 2014年

所以我可以,很好。
histocrat

6

Bash 4.x + Ncal,57

如果换行符可以用空格代替,那么我们可以-necho语句中删除开关和尾随空格。而且我想如果没有shebang仍然可以使用,所以我也删除了它:

for i in {01..12};{ echo "$1-$i-`ncal $i $1|tail -c-3`";}

原始脚本(73个字节):

#!/bin/bash
for i in {01..12};{ echo -n "$1-$i-`ncal $i $1|tail -c-3` ";}

用法:

$ bash sundays.sh 2014
2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-31
2014-09-28
2014-10-26
2014-11-30
2014-12-28
$

注意: 4.0之前的Bash版本将省略月份中的前导零。更改{01..12}为可以通过添加5个字符来解决此问题`seq -w 1 12)`。另外,tail -c-3在某些系统上可能会引起问题,这些系统的输出ncal包含尾随空格,但是我不知道会发生什么。


1
区别真的与达尔文有关,而不仅仅是Bash版本吗?已在Bash 4.0中添加(尽管稍后会有一些错误)。无论如何,仍然可以使用`…`而不是好习惯来保留1个字符$(…)
manatwork 2014年

嗯,可能是。达尔文说它正在使用3.2.53版本;Debian正在使用4.1.5。
吱吱作响的ossifrage

@manatwork PS刚注意到您对反提要的评论。很好,谢谢!
吱吱作响的ossifrage 2014年

我认为您不需要#!/bin/bash为了打高尔夫球而数数。
Digital Trauma 2014年

@DigitalTrauma很好。看来我也可以使用换行符代替空格。现在减少到57个字节:-)
吱吱作响的ossifrage

6

IBM DFSORT,11 3行,每行71、72或80个字符

 OPTION COPY 
 OUTFIL REPEAT=12,OVERLAY=(5:SEQNUM,2,ZD,5,2,1,8,Y4T,LASTDAYM,TOJUL=Y4T*
 ,9,7,Y4T,ADDDAYS,+1,TOJUL=Y4T,1:16,7,Y4T,PREVDSUN,TOGREG=Y4T(-),12X) 

列式输出格式的两个答案经受了时间的考验。在某种程度上,这给了我一个“循环”,因为在OUTFIL REPEAT =上多次复制了当前记录。

另一种获取价值的方法似乎更长,但更短,因为我无法找出任何无条件的方法来处理第二年的第12条记录,并使其成为有条件的手段,包括IFTHEN=(WHEN=,两次和其他一些东西。在回旋处获得收益(月初是最简单的方法),在回旋处损失严重(特殊语法要求)。

这使用一个内置函数(DFSORT中的所有函数都是内置函数)来查找每月的最后一天。然后添加一天(函数)到下个月的第一天,并使用PREVDSUN函数获得前一个星期日(与以前一样,它总是上个月的最后一个星期日)。

将年份(输入)转换为有效日期时,将使用两位数的序列号表示月份,并且也将复制该值的日期,因为起始点与有效期一样长,最初在该月的最后一天之后:5,2比短C'01'

详细信息如下:

选项复制-将输入文件复制到输出

OUTFIL-允许具有不同选择和格式的多个输出文件生成格式化的报告。由于使用,优先于较短的优先INREC使用REPEAT=

REPEAT = 12-每个记录产生12个副本。在此示例中,由于SEQNUM,只能有一个输入记录(与以前的版本不同)。

5:-从记录的第5列开始。

SEQNUM,2,ZD-序列号,默认以一位和两位数字开头,“带区号的十进制”(对于无符号,它们将与字符相同)。

1,8-将长度8的字节1复制到当前位置(9)。这是因为Y4T需要看到8,否则将使用其他日期格式。

Y4T-ccyymmdd格式的日期(由于紧靠其前面的8)。

LASTDAYM-月份的最后一天(也可以是星期,季度和年份)。

TOJUL =-输出日期函数的日期转换(TOJUL比TOGREG小1个字符)

9,7-现在是7长,Y4T将为CCYYDDD。

ADDDAYS-增加天数,如果进入下个月/年,则自动调整(也可以是ADDMONS和ADDYEARS)

PREVDSUN-朱利安日期到来,上一个星期日位于,TOGREG使用“-”分隔符获取正确的输出格式(可以是任何您喜欢的分隔符)

12倍-清除空白,使我们能够以如此短的方式进行处理

以上是2014年的输出:

2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-31
2014-09-28
2014-10-26
2014-11-23
2014-12-28

需要一些信息来告诉SORT该怎么做。没有默认值。OPTION COPY是最短的,SORT FIELDS=COPY等效但更长。

这次所做的工作本身OUTFIL(允许使用REPEAT)。工作代码可以是160(2 * 80),144(2 * 72),140(72 + 69)或138(70 + 68)中的任何一个(不包括前导空格,强制连续空格和尾随空格)。

考虑到接收者必须知道他们在做什么,我想我可以说DFSORT代码列出了从1900年开始的任何一年的每个月的最后一个星期日(将从0001年开始,但是我避免这样做,因为可以)(最多9999)(尽管DFSORT支持高达9999的年份,但由于第12个日期进入下一年,所以以前的解决方案在9999年不起作用)。

如果有特别合适的内置函数,为什么代码那么长?

字段定义是短暂的。字段仅定义为数据(记录)中的特定位置,可以立即使用。换句话说,字段不是这样定义的,而是为每次使用而定义的,仅用于使用。日期函数需要知道使用哪种(许多)日期格式作为源,并且输出必须采用日期格式,因此必须指定日期格式。

现在我们有朱利安约会... TBC?


 OPTION COPY 
 INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8*
 ,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4,14:C'3',22:C'4',30:C'5',38:C'6',*
 46:C'7',54:C'8',62:C'9',69:C'10',77:C'11',85:C'12',127:X,89,8,Y4T,PREV*
 DSUN,TOGREG=Y4T(-),116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-),105:X,73,8,Y4*
 T,PREVDSUN,TOGREG=Y4T(-),94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-),83:X,57,*
 8,Y4T,PREVDSUN,TOGREG=Y4T(-),72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-),61:X*
 ,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-),50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-),*
 39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-),28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T*
 (-),17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-),1:1,8,Y4T,PREVDSUN,TOGREG=Y4T*
 (-),11:X,18,120,6X) 

需要一些 JCL

//LASTSUNG EXEC PGM=SORT 
//SYSOUT   DD SYSOUT=* 
//SORTOUT  DD SYSOUT=* 
//SYSIN    DD * 

和一个输入文件(JCL的另一行和三个流内数据项):

//SORTIN DD *
2014 
1900 
2000 

产生:

2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28
1900-01-28 1900-02-25 1900-03-25 1900-04-29 1900-05-27 1900-06-24 1900-07-29 1900-08-26 1900-09-30 1900-10-28 1900-11-25 1900-12-30
2000-01-30 2000-02-27 2000-03-26 2000-04-30 2000-05-28 2000-06-25 2000-07-30 2000-08-27 2000-09-24 2000-10-29 2000-11-26 2000-12-31

实际可以使用到9999年。

DFSORT是IBM的大型机排序产品。数据是可以操纵的,但是由于排序是关键,并且排序通常规模大且运行时间长,DFSORT控制卡没有循环结构,因此我们无法将SORT放入循环中。使诸如高尔夫之类的任务变得有些困难。

之所以发布答案,是因为DFSORT具有PREVDday功能。因此,一个月内的最后一个星期日很容易。它是上个月的星期日(PREVDSUN)至下个月的第一天。

在一个“操作数”(覆盖)中执行该操作也很有趣,有点像在一个sprintf或多个操作中进行。

这里是无高尔夫球的:

 OPTION COPY 

 INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8, 
         1,8,1,8,1,8,1,8, 
         1,8,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4, 
         14:C'3',22:C'4',30:C'5',38:C'6',46:C'7',54:C'8',
         62:C'9',69:C'10',77:C'11',85:C'12', 
        127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
        116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
        105:X,73,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         83:X,57,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         61:X,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
          1:1,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         11:X,18,120,6X) 

虽然不是很滥用,但尝试将所有这些都塞进一个OVERLAY并不常见,并且似乎需要一些不必要的东西才能将它们全部塞入一个OVERLAY。这里有打高尔夫球的空间,但是由于最多只能打掉一条线,所以我不会动心。

将为每条记录处理INREC。

OVERLAY允许更改现有记录的内容。如果记录在过程中超出其长度,则不存在问题。

1,4是即将到来的年份。它上面附加了一个字面0020,然后连续的1,8重复11次以得到96个字节的长卡盘,

扩展的当前记录的第12年添加了1,其月份设置为1(1月)。

剩余的10个月更改为3到11。

然后以相反的顺序(由于OVERLAY)出现了12种此类事物:

127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-),

n:是记录中的列号。X插入一个空格。89,8从该列/长度中获取数据,Y4T将其视为CCYYMMDD日期,PREVDSUM计算出前一个星期日,TOGREG = Y4T(-)将其输出为公历CCYY-MM-DD日期。

如果OVERLAY的特定部分的源和目标破坏性地重叠,则会使您感到垃圾,因此最终的11:X,18,120,6X)重新排列和掩盖了一些混乱。

可以在以下位置找到手册和文件:http : //www-01.ibm.com/support/docview.wss?uid=isg3T7000080,其中包含900页以上的《 DFSORT应用程序编程指南》。

与所有IBM产品一样,所有手册都是免费提供的(极少量的非常昂贵的手册除外,全世界只有很少一部分人会假装理解)。

所有DFSORT控制卡都必须以空白开头。列72仅用于继续(任何非空白都可以,但是*是常规的)。列72后跟一个序列号区域,该序列号区域被忽略,使每个记录为80个字节。

也许还会有另外两种解决方案。


5

Bash,63个字节

for i in {01..12};{  date -v30d -v${i}m  -v2014y  -vsun +%Y-%m-%d;}

输出:

2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-24
2014-09-28
2014-10-26 
2014-11-30
2014-12-28

for i in {1..12};{ date -v30d -v${i}m -v$1y -v0w +%Y-%m-%d;}-60字节
Digital Trauma 2014年

-v参数去date是针对BSD日期。因此,这适用于OSX,但不适用于大多数Linux-也许应该在答案中说明。
Digital Trauma 2014年

@DigitalTrauma,可在Mac和我的Linux上使用。
michael501

4

Python 2-189字节

y=input()
for m in range(12):
 d=[31-(1322>>m&1),28+(y%400<1or 1>y%4<y%100)][m==1];Y=y-(m<2);Z=Y%100;C=Y/100
 while(d+13*((m-2)%12+4)/5+Z+Z/4+C/4-2*C)%7-1:d-=1
 print"%d-%02d-%d"%(y,m+1,d),

通过STDIN输入日期。

还有更多的高尔夫运动可以做。该程序有些落伍,只是为了好玩:

  • 没有导入,特别是不使用任何内置的日期函数
  • 使用Zeller的全等来计算星期几

笔记

  • 1322是一个魔术查询表,用于确定一个非二月的时间是30天还是31天
  • 没有zfill需要几年由于输入范围,也不日内他们将永远是超过20

Python 2-106个字节

不那么有趣的解决方案:

from calendar import*
y=input();m=1
while m<13:w,n=monthrange(y,m);print"%d-%02d-%d"%(y,m,n-(n+w)%7),;m+=1

calendar.monthrange返回两个数字:月份从(w)开始的工作日和月份()的天数n。由于存在问题,解决方案有点违反直觉-返回的工作日从星期一开始,而不是星期日从0开始!但是,这被n基于1 的事实所抵消。


1
一个非常愚蠢的Pyth答案:$from calendar import monthrange as gt$V12AGH>QhN%"%d-%02d-%d"(QhN-H%+GH7
FryAmTheEggman 2014年

3

JavaScript的(ES6)155 145

编辑固定时区问题如果进行递归,则可以缩短。也许。

F=y=>{
  for(n=i=o=[];!o[11];)
    d=new Date(Date.UTC(y,0,++i)),m=d.getMonth(),
    d.getDay()||(m!=n&&o.push(p.toISOString().slice(0,10)),p=d,n=m);
  return o.join(' ')
}

您可以使用new Date(y,0,++i,9)。此外,这对于2100年及以上的leap年失败,因为JS没有有关这些leap年的信息,因此,根本没有Feb 292100及以上的leap年。
Optimizer

@Optimizer不是JS:2100、2200、2300不是leap年。JS知道2014年是a年。至于使用9小时,我无法验证,但我想如果您例如在墨尔本就
行不通

啊..从来不知道我们每400年会减少3天。关于9 -我改变了我的时区从-1000(夏威夷)于1100(墨尔本),并new Date(2014,0,26,9)是一个星期天给予正确的ISO字符串,以及getDay()作为0
Optimizer

3

JavaScript中,ES6,222个219 199字节

在rosetta Wiki中没有看到任何JavaScript答案。

开始了:

S=Y=>{for(l=[],p=new Date(Y,i=0);i<365+!(Y%4);)if(!(d=new Date(Y,0,++i,9)).getDay()){p.getMonth()-d.getMonth()&&l.push(p);p=new Date(d)}return[...l,p].map(x=>x.toISOString().split("T")[0]).join(" ")}

这将创建一个函数S,该函数返回具有所需输出的字符串。该功能还可以解决of年问题。

由于使用了ES6,因此只能在最新的Firefox中使用。

多亏了Apsillers提供的技巧,使技巧减少到200个字节

在下面找到堆栈版本的非公开版本,您可以在此处自行运行:

S=Y=>{
  for(l=[],p=new Date(Y,i=0);i<365+!(Y%4);)
    if(!(d=new Date(Y,0,++i,9)).getDay()){
      p.getMonth()-d.getMonth()&&l.push(p);
      p=new Date(d)
    }
  return[...l,p].map(x=>x.toISOString().split("T")[0]).join(" ")
}

alert(S(parseInt(prompt())))


您可以使用+ prompt()而不是parseInt并删除一些字节
Jacob Jacob 2014年

@Jacob该提示未添加到字节数中。
Optimizer

OIC。我应该读过这个问题……
雅各布

@apsillers感谢一吨!解决了该问题,并根据您的建议减少了很多。
Optimizer

输入2100输出2100-01-31 2100-02-28 2100-03-28 2100-04-25 2100-05-30 2100-06-27 2100-07-25 2100-08-29 2100-09-26 2100-10-31 2100-11-28 2100-12-26 2101-01-02错误。
Qwertiy 2014年

3

Rebol-120116 80 79 76

d: do join"1-1-"input print collect[for m 2 13 1[d/2: m keep d - d/weekday]]


取消高尔夫+一些注释:

d: do join "1-1-" input         ;; golfy way to create Rebol date! datatype 1-Jan-(year)

print collect [
    for m 2 13 1 [              ;; loop thru months 2 to 13!
        d/2: m                  ;; move to (1st of) next month
        keep d - d/weekday      ;; collect/keep last sunday of month
    ]
]

Rebol控制台中的周日计算示例:

>> ; get last sunday of Jan 2014

>> d: 1-1-2014
== 1-Jan-2014

>> d/month: d/month + 1
== 2

>> d
== 1-Feb-2014

>> d/weekday
== 6

>> d - d/weekday
== 26-Jan-2014

>> ; above is last sunday of Jan 2014
>> ; and when pass end of year (ie. month 13!)

>> d/month: 13
== 13

>> d
== 1-Jan-2015

潜力87:d:1-1-1 d /年:输入打印是否收集[重复m 12 [d /月:m +1保持d-d /工作日]]
rgchris

@rgchris谢谢克里斯。能够刮掉另外7个字符。
draegtun 2015年

不错!这很不好,但是从来没有真正将FOR视为捷径。
rgchris 2015年

2

CJam,122个 102字节

30li:X400%){[1387Yb30f+~28I!I4%!I100%e&|g+\]W%{\_2$>7*-\7%7\m1$+}/}fI;]12/W=12,{101+s1>}%]z{X+W%'-*S}/

这不使用任何形式的日期库。我认为它也可以打很多球。

在这里测试。


3
我太激动了,以至于CJam的答案不是一次在代码高尔夫挑战赛中的最佳答案。我可以开心地死。.今天是一个美好的一天(直到打到6字节为止,显然是这样)
Brandon

@布兰登:这就是我认为这很有趣的原因。真希望看到一些奇妙的库可以使此操作变得容易,但到目前为止令人失望。
Phil H

1

R,128个字符

P=paste;f=format;a=strptime(P(1:366,scan()),"%j %Y");cat(sort(sapply(split(a,f(a,"%B")),function(x)P(tail(x[f(x,"%u")==7],1)))))

带换行符:

P=paste
f=format
a=strptime(P(1:366,scan()),"%j %Y")
cat(sort(sapply(split(a,f(a,"%B")),function(x)P(tail(x[f(x,"%u")==7],1)))))

1

C#255

不打高尔夫球

static void Main(string[] a)
    {
        int y = Int32.Parse(Console.ReadLine());
        DateTime d = new DateTime(y, 1, 1);
        while (d.Year == y)
        {
            if (d.DayOfWeek == DayOfWeek.Sunday && d.Day>(DateTime.DaysInMonth(y,d.Month)-7))
                Console.WriteLine(d.ToShortDateString());
            d = d.AddDays(1);
        }
        Console.ReadKey();
    }

编辑:修改为仅打印最后一个星期日:)


不是必需的输出格式。+这是代码高尔夫
edc65

1

q,67

{({{1<>x mod 7}-[;1]/x}')14h$1_til[13]+13h$"D"$(($)x),".01.01"}

在q中没有可用的日期库吗?
Phil H

1

“哦,不,他又来了!”

Java- 259246字节

void g(int y){for(int i=;i<12;i++){GregorianCalendar c=new GregorianCalendar(y,i,0);c.set(c.DAY_OF_WEEK,c.SUNDAY);c.set(c.DAY_OF_WEEK_IN_MONTH,-1);System.out.print(y+"-"+String.format("%02d",(c.get(c.MONTH)+1))+"-"+(c.get(c.DAY_OF_MONTH))+" ");}}

非高尔夫版本:

void g(int y){
    for (int i = 0; i < 12;i++) {
        GregorianCalendar c = new GregorianCalendar(y, i, 0);
        c.set(c.DAY_OF_WEEK, c.SUNDAY);
        c.set(c.DAY_OF_WEEK_IN_MONTH, -1);
        System.out.print(y+"-"+String.format("%02d",(c.get(c.MONTH)+1))+"-"+(c.get(c.DAY_OF_MONTH))+" ");
    }
}

用法:

import java.util.GregorianCalendar;
import java.util.Scanner;

public class LastSundayInYear {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Year?");
        int year = scanner.nextInt();
        LastSundayInYear sunday = new LastSundayInYear();
        sunday.g(year); 
    }

    void g(int y){
        for (int i = -1; ++i < 12;) {
            GregorianCalendar c = new GregorianCalendar(y, i, 0);
            c.set(c.DAY_OF_WEEK, c.SUNDAY);
            c.set(c.DAY_OF_WEEK_IN_MONTH, -1);
            System.out.print(y+"-"+String.format("%02d",(c.get(c.MONTH)+1))+"-"+(c.get(c.DAY_OF_MONTH))+" ");
        }
    }
}

输出:

2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28

还有一个“让我们把Java答复只是为了踢”答案。那好吧。但是,至少,由于您不愿意回答我的问题,因此,我将尽力让您感到无聊,并解释我的理由。

该方法g接收所需的年份,并为每个月创建一个GregorianCalendar对象(月份从0到11)。然后,第一个c.set将星期几设置为星期日,而第二个则声明我们想要该月的最后一周-如官方文档所示。该System.out.println指出,周日的日期打印(如果我们这样做的权利,这一年将被打印成c.get(c.YEAR),但使用y再次关闭13个字符刮),当月必须进行格式化,以从一月添加一个前导零至九月(和值会增加,因为这里的月份表示为0-11),并且会打印最后一个星期日的日期。并在其他十一个月中重复此过程。


0

C#,212,237

string x(int y){var s="";var t="";var d=new DateTime(y,1,1);for(;;){if(d.Year!=y){return s;}t=(d.DayOfWeek==DayOfWeek.Sunday)?t=string.Format("{0}-{1}-{2} ",d.Year,d.Month,d.Day):t;s=(d.AddDays(1).Month!=d.Month)?s+=t:s;d=d.AddDays(1);}}

带换行符

string x(int y)
    {
        var s = "";
        var t = "";
        var d = new DateTime(y,1,1);
        for (;;)
        {
            if (d.Year != y) {
                return s;
            }
            t = (d.DayOfWeek == DayOfWeek.Sunday) ? t = string.Format("{0}-{1}-{2} ", d.Year, d.Month, d.Day) : t;
            s=(d.AddDays(1).Month!=d.Month)?s+=t:s;
            d=d.AddDays(1);
        }
    }

2014年的产出

"2015-1-25 2015-2-22 2015-3-29 2015-4-26 2015-5-31 2015-6-28 2015-7-26 2015-8-30 2015-9-27 2015-10-25 2015-11-29 2015-12-27"

不是必需的输出格式
edc65

在那里,固定。更好?
达伦·布雷恩

0

C#171

函数返回一个字符串。

string S(int y){var r="";for(int m=1;m<13;++m){var d=new System.DateTime(y,1,1).AddMonths(m).AddDays(-1);r+=y+string.Format("-{0:00}-{1} ",m,d.Day-d.DayOfWeek);}return r;}

不打高尔夫球

string S(int y)
{
    var r="";
    for (int m=1;m<13;++m)
    {
        var d = new System.DateTime(y, 1, 1).AddMonths(m).AddDays(-1);
        r += y + string.Format("-{0:00}-{1} ", m, d.Day - d.DayOfWeek);
    }
    return r;
}

0

C#194

使用Linq:

string d(int y){return string.Join(" ",Enumerable.Range(1,12).Select(m=>new DateTime(y,m,DateTime.DaysInMonth(y,m))).Select(d=>d.AddDays(-(int)d.DayOfWeek)).Select(d=>d.ToString("yyy-MM-dd")));}

不打高尔夫球

string d(int y)
{
    return string.Join(" ",Enumerable.Range(1,12)
        .Select(m => new DateTime(y, m, DateTime.DaysInMonth(y, m)))
        .Select(d => d.AddDays(-(int)d.DayOfWeek))
        .Select(d => d.ToString("yyy-MM-dd")));
}

输出量

2013-01-27 2013-02-24 2013-03-31 2013-04-28 2013-05-26 2013-06-30 2013-07-28 2013-08-25 2013-09-29 2013-10-27 2013-11-24 2013-12-29

0

Mathematica-171

包裹在一个匿名函数中,返回字符串

StringJoin[Last@#~DateString~{"Year","-","Month","-","Day"," "}&/@GatherBy[Select[DateRange[DateObject[{#}],DateObject[{#+1}]],DayName@#==Sunday&],DateValue[#,"Month"]&]]&

第一次数学高尔夫。我觉得它可能会大大减少。


0

VB-192

Function z(y)
For i = 1 To 11
a = 0
s = IIf(i <> 11, DateSerial(y, i + 1, 1), DateSerial(y + 1, 1, 1))
While Weekday(s - a) <> 1
a = a + 1
Wend
r = r + Str(s - a) + " "
Next
z = r
End Function

可能会更糟^^

我的第二次也是最后一次(不要认为我可以缩小它)

142

Function z(y)
Dim m(12)
For i = 1 To 366
s = DateSerial(y, 1, 1) + i
If Weekday(s) = 1 Then m(Month(s)) = s
Next
z = Join(m, " ")
End Function

0

红宝石76

使用命令行参数ruby sundays.rb 1900。使用日期库。

require'date';puts (1..12).map{|m|d=Date.new($*[0].to_i,m,-1);d-d.wday}*" "
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.