工作日倒计时


17

我只是有一个天才的想法,那就是使工作生活更轻松-倒计时到特定的日期,只计算工作日。


基本任务是创建一个到特定日期的倒计时,该日期仅包括倒计时中的工作日。

工作日为星期一星期二星期三星期四星期五

输入内容应为“非官方”欧洲标准格式的特定日期,dd.MM.yyyy并且必须为今天或将来的一天。

输出仅应为剩余天数。

因为它是所以最短的代码获胜。


测试用例:

  Today    |   Input    | Output
10.12.2018 | 17.12.2018 |    5
02.10.2018 | 16.10.2018 |   10

如果我错过了这个问题,请原谅我-这是我的第一个问题:)

编辑:

  • 您可以将其false用作输出而不是0 <-,但它并不漂亮
  • 无需遵守DST

9
这种“非官方的”欧洲输入格式背后有什么具体原因吗?我们的共识是在可能的情况下允许灵活的输入。
Arnauld

6
添加难以处理的日期格式的“额外挑战”真的有什么意义吗?这似乎不公平,具有灵活的日期格式的wrt语言...
Quintec '18

3
@Hille我不是说这很“困难”,这只是不必要的麻烦,尤其是在代码高尔夫球中……请注意Arnauld在上面发布的链接...通常是灵活的输入是规范...
Quintec

6
顺便说一句,您注意到这是您的第一个挑战。我邀请您在对main发起挑战之前使用Sandbox进行优化!否则,做得很好,我很乐意看到您的更多信息!
朱塞佩

7
严格的输入格式并没有给您留下深刻的印象,但除此之外,这是一个很好的挑战。
ElPedro '18 -10-1

Answers:


18

05AB1E130个 128 133 131 124 123 字节

žežfžg)V0[Y`UÐ3‹12*+>13*5÷s3‹Xα©т%D4÷®т÷©4÷®·()ćsO7%2@+Y`т‰0Kθ4ÖUD2Qi\28X+ë<7%É31α}‹iY¬>0ëY1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝVYI'.¡Q#

我疯了..

对于高尔夫语言05AB1E,输入是否带有.或都没有关系-。但是,05AB1E没有任何内置对象可用于Date对象或计算。关于日期的唯一内置函数是今天的年/月/日/小时/分钟/秒/微秒。

因此,因此,您看到的几乎所有代码都是手动计算,可以转到第二天,并计算星期几。

由于我在Zeller的公式中忘记了一部分,所以增加了5个字节(1月和2月为1年)。

在线尝试以模拟的自指定日期“ today” 在线尝试

说明:

文本墙传入。

通常,该代码遵循以下伪代码:

1   Date currentDate = today;
2   Integer counter = 0;
3   Start an infinite loop:
4*    If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):
5       Counter += 1;
6*    currentDate += 1; // Set currentDate to the next day in line
7     If(currentDate == parsed input-string):
8       Stop the infinite loop, and output the counter

1)Date currentDate = today;是05AB1E程序的这一部分:

že          # Push today's day
  žf        # Push today's month
    žg      # Push today's year
      )     # Wrap them into a single list
       V    # Pop and store this list in variable `Y`

2)Integer counter = 0;和3)Start an infinite loop:在05AB1E程序中很简单:

0     # Push 0 to the stack
 [    # Start an infinite loop

4)If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):是手工计算的第一部分。由于05AB1E没有内置日期,因此我们必须手动计算星期几。

通用的公式是:

h=(q+13(m+1)5+K+K4+J42J)mod7,

3月到12月的几个月:

  • qday该月的([1, 31]
  • m是1索引的month[3, 12]
  • K是本世纪的年份(yearmod100
  • J是0索引世纪(year100

一月和二月:

  • qday该月的([1, 31]
  • m是1的索引month+12[13, 14]
  • K是上一年的世纪((year1)mod100
  • J是上一年的0索引世纪(year1100

结果在星期几h,其中0 =星期六,1 =星期日,...,6 =星期五。
资料来源:Zeller的全等

我们可以在05AB1E程序的这一部分中看到这一点:

Y             # Push variable `Y`
 `            # Push the day, month, and year to the stack
  U           # Pop and save the year in variable `X`
   Ð          # Triplicate the month
    3        # Check if the month is below 3 (Jan. / Feb.),
              # resulting in 1 or 0 for truthy/falsey respectively
      12*     # Multiply this by 12 (either 0 or 12)
         +    # And add it to the month
              # This first part was to make Jan. / Feb. 13 and 14

>             # Month + 1
 13*          # Multiplied by 13
    5÷        # Integer-divided by 5
s3           # Check if the month is below 3 again (resulting in 1 / 0)
   Xα         # Take the absolute difference with the year
     ©        # Store this potentially modified year in the register
      т%      # mYear modulo-100
D4÷           # mYear modulo-100, integer-divided by 4
®т÷©4÷        # mYear integer-divided by 100, and then integer-divided by 4
®·(           # mYear integer-divided by 100, doubled, and then made negative
)             # Wrap the entire stack into a list
 ć            # Extract the head (the counter variable that was also on the stack)
  s           # Swap so the calculated values above are as list at the top
   O          # Take the sum of this entire list
    7%        # And then take modulo-7 to complete the formula,
              # resulting in 0 for Saturday, 1 for Sunday, and [2, 6] for [Monday, Friday]

2@            # Check if the day is greater than or equal to 2 (so a working day)

5)Counter += 1;又直截了当:

     # The >=2 check with `2@` results in either 1 for truthy and 0 for falsey
+    # So just adding it to the counter variable is enough

6)currentDate += 1; // Set currentDate to the next day in line再复杂一点,因为我们必须手动进行。因此,它将扩展为以下伪代码:

a   Integer isLeapYear = ...;
b   Integer daysInCurrentMonth = currentDate.month == 2 ?
c                                 28 + isLeapYear
d                                :
e                                 31 - (currentDate.month - 1) % 7 % 2;
f   If(currentDate.day < daysInCurrentMonth):
g     nextDate.day += 1;
h   Else:
i     nextDate.day = 1;
j     If(currentDate.month < 12):
k       nextDate.month += 1;
l     Else:
m       nextDate.month = 1;
n       nextDate.year += 1;

资料来源:
确定一年是否为a年的算法。(编辑:不再相关,因为我使用另一种方法来检查节省了7个字节的leap年。)
用于确定一个月中天数的算法。

Integer isLeapYear = ...;在05AB1E程序中这样完成6a):

Y             # Push variable `Y`
 `            # Push the days, month and year to the stack
  т‰          # Divmod the year by 100
    0K        # Remove all items "00" (or 0 when the year is below 100)
      θ       # Pop the list, and leave the last item
       4Ö     # Check if this number is visible by 4
         U    # Pop and save the result in variable `X`

我的05AB1E答案中也使用了,因此添加了一些示例年份来说明步骤。

6b) currentDate.month == 2 ?和6c)28 + isLeapYear的操作如下:

D            # Duplicate the month that is now the top of the stack
 2Q          # Check if it's equal to 2
   i         # And if it is:
    \        #  Remove the duplicated month from the top of the stack
     28X+    #  Add 28 and variable `X` (the isLeapYear) together

6d) :和6e)31 - (currentDate.month - 1) % 7 % 2;的操作如下:

ë           # Else:
 <          #  Month - 1
  7%        #  Modulo-7
    É       #  Is odd (shortcut for %2)
     31     #  Push 31
       α    #  Absolute difference between both
}           # Close the if-else

6f)If(currentDate.day < daysInCurrentMonth):是这样完成的:

     # Check if the day that is still on the stack is smaller than the value calculated
 i    # And if it is:

6克) nextDate.day += 1;是这样完成的:

Y       # Push variable `Y`
 ¬      # Push its head, the days (without popping the list `Y`)
  >     # Day + 1
   0    # Push index 0

        # (This part is done after the if-else clauses to save bytes)
}}      # Close the if-else clauses
  ǝ     # Insert the day + 1 at index 0 in the list `Y`
   V    # Pop and store the updated list in variable `Y` again

6小时) Else:nextDate.day = 1;然后像这样完成和6i):

ë        # Else:
 Y       #  Push variable `Y`
  1      #  Push a 1
   ¾     #  Push index 0
    ǝ    #  Insert 1 at index 0 (days part) in the list `Y`

6j) If(currentDate.month < 12):

D           # Duplicate the list `Y`
 Ås         # Pop and push its middle (the month)
   D12     # Check if the month is below 12
       i    # And if it is:

6k) nextDate.month += 1;

>       # Month + 1
 1      # Push index 1

        # (This part is done after the if-else clauses to save bytes)
}}      # Close the if-else clauses
  ǝ     # Insert the month + 1 at index 1 in the list `Y`
   V    # Pop and store the updated list in variable `Y` again

6l)Else:,6m)nextDate.month = 1;和6n)nextDate.year += 1;然后像这样完成:

ë        # Else:
 \       #  Delete the top item on the stack (the duplicated month)
  1      #  Push 1
   D     #  Push index 1 (with a Duplicate)
    ǝ    #  Insert 1 at index 1 (month part) in the list `Y`

 ¤       #  Push its tail, the year (without popping the list `Y`)
  >      #  Year + 1
   2     #  Index 2

         # (This part is done after the if-else clauses to save bytes)
}}       # Close the if-else clauses
  ǝ      # Insert the year + 1 at index 2 in the list `Y`
   V     # Pop and store the updated list in variable `Y` again

最后在8)If(currentDate == parsed input-string):和9)处Stop the infinite loop, and output the counter

Y          # Push variable `Y`
 I         # Push the input
  '.¡     '# Split it on dots
     Q     # Check if the two lists are equal
      #    # And if they are equal: stop the infinite loop
           # (And output the top of the stack (the counter) implicitly)

5
您是个疯子...赞成。
AdmBorkBork

1
最长的05AB1E程序?
路易斯·门多

2
@LuisMendo关闭,但恐怕我有一个05AB1E回答自己,甚至更长,而一个自带方式太近.. ;)我敢肯定,我就可以打高尔夫球的几个字节的这里那里简化第二天执行部分伪代码。明天早上看,但是刚从运动中回来,很快就会上床睡觉。
凯文·克鲁伊森

11

Excel 24字节

假设在单元格A1中输入

=NETWORKDAYS(NOW()+1,A1)

使用内置功能。不幸的是,该功能包括今天和结束日期。此后,OP澄清说不算今天,所以我现在加一个,以便今天不算。

同样,为了解决有关数字格式的注释,这是Excel标准: enter image description here


尽管此方法适用于日期值,但无法如所述接受输入。也就是说(至少在美国版本中)10.12.2018是保存在单元格中而不是日期时的字符串。纠正此问题的显而易见但很长的解决方案是更改A1DATE(RIGHT(A1,4),MID(A1,4,2),LEFT(A1,2))您的解决方案
Taylor Scott

不幸的是,社区决定必须使用默认设置来运行语言才有效(我见过的一个例外是语言-IE,如果您的语言同时支持英语和西班牙语,则您可以随时使用其中一种,但是此外,OP(@hille)并未声明格式具有灵活性,而实际上却表示相反(请参阅此问题的第二条评论)
Taylor Scott

2
该格式不是标准格式,它是基于语言环境的。Excel从HKCU\Control Panel\International\sDecimal注册表字符串读取格式。在默认的美国Windows安装下,其格式为MM / dd / yyyy。在大多数欧盟国家,这将是默认设置。
Erik A

@luisMendo是的,可以。我没有任何澄清。如果不是最后一天,我可以= NETWORKDAYS(NOW(),A1-1)。我知道无论进行哪种澄清,字节数总是相同的。
Keeta-恢复莫妮卡

很高兴。我删除了下票
Luis Mendo


8

爪哇10,233个 232 226字节

import java.util.*;d->{int r=0;var s=Calendar.getInstance();s.setTime(new Date());var e=s.getInstance();for(e.setTime(new java.text.SimpleDateFormat("dd.MM.yyyy").parse(d));!s.after(e);s.add(5,1))if(s.get(7)%7>1)r++;return r;}

日期总是让我想起Java到底是多么的冗长。

注:现在有两个较短的Java答案(低于175个字节),一个智能的使用从早期的Java版本不赞成的方法通过@LukeStevens,以及一个使用java.time.LocalDate这新的从Java 8通过@OlivierGrégoire

在线尝试。

说明:

import java.util.*;            // Required import for both Calendar and Date
d->{                           // Method with String parameter and integer return-type
  int r=0;                     //  Result-integer, starting at 0
  var s=Calendar.getInstance();//  Create a Calendar instance for the start-date
  s.setTime(new Date());       //  Set the start date to today
  var e=s.getInstance();       //  Create a Calendar instance for the end-date
  for(e.setTime(               //  Set the end date to:
        new java.text.SimpleDateFormat("dd.MM.yyyy")
                               //   Create a formatter for the "dd.MM.yyyy" format
         .parse(d));           //   And parse the input-String to a Date
      !s.after(e)              //  Loop as long as we haven't reached the end date yet
      ;                        //    After every iteration:
       s.add(5,1))             //     Increase the start-date by 1 day
    if(s.get(7)%7>1)           //   If the day of the week is NOT a Saturday or Sunday:
                               //   (SUNDAY = 1, MONDAY = 2, ..., SATURDAY = 7)
      r++;                     //    Increase the result-sum by 1
  return r;}                   //  Return the result-sum

你可以e=s.clone()吗?
Quintec '18

1
我们也可以(我假设)这样做Calendar s=Calendar.getInstance(),e=s.getInstance(),不幸的是最终它的长度完全一样。
米莎·拉夫罗夫

1
@MishaLavrov啊,静态C确实不是必需的。它来自代码的旧部分,我也在C其他地方使用过。能够通过使用高尔夫球打1个字节,var s=Calendar.getInstance();var e=s.getInstance();所以谢谢。:)
Kevin Cruijssen


1
做完了!它的字节数与其他答案非常接近,但尚未击败它。
奥利维尔·格雷戈尔

7

的JavaScript(ES6),116个 103字节

f=(d,n=+new Date)=>(D=new Date(n)).toJSON()<d.split`.`.reverse().join`-`&&(D.getDay()%6>0)+f(d,n+864e5)

在线尝试!

怎么样?

n

nD.toJSON()方法:

YYYY - MM - DD T hhmmss.sss Z

YYYY-MM-DDdYYYY-MM-DDDD.MM.YYYY

d.split`.`.reverse().join`-`

D.getDay()0606

(D.getDay() % 6 > 0) + f(d, n + 864e5)

86,400,000n


6

MATL,24字节

46tQZt24&YO:Z':X-9XO83-z

在线尝试!

我不想使用任何输入格式,因此特定的代码高尔夫球语言具有很大的优势

您成功了一半:-)

说明

46      % Push 46 (ASCII for '.')
tQ      % Duplicate, add 1: gives 47 (ASCII for '/')
Zt      % Implicit input. Replace '.' by '/' in the input string
24&YO   % Convert string with date format 24 ('dd/mm/yyyy') to serial date number.
        % This is an integer representing day starting at Jan-1-0000
:       % Inclusive range from 1 to that
Z'      % Push current date and time as a serial number. Integer part is day;
        % decimal part represents time of the day
:       % Inclusive range from 1 to that
X-      % Set difference. Gives serial numbers of days after today, up to input
9XO     % Convert each number to date format 9, which is a letter for each day
        % of the week: 'M', 'T', 'W', 'T', ' F', 'S', 'S'
83-     % Subtract 83 (ASCII for 'S')
z       % Number of nonzeros. Implicit display

如果我正确理解了挑战,则只需输入一个日期并将其与今天的日期进行比较。例如,16.10.2018会今日(星期一01-10-2018)结果11,明天10
凯文Cruijssen

@KevinCruijssen哎呀。谢谢!已更正
Luis Mendo '18

1
并且具有相同的字节数。:)很好,我+1。
凯文·克鲁伊森

6

Wolfram语言(Mathematica)64 56字节

DayCount[Today,""<>#~StringTake~{{4,6},3,-4},"Weekday"]&

在线尝试!

DayCount[x,y,"Weekday"]计算x和之间的工作日数y

输入xy可以是很多东西,包括DateObjectToday,,或格式的字符串(很不幸)之类的花哨的东西。mm.dd.yyyy

我之前的尝试试图将dd.mm.yyyy输入转换为DateObject通过告诉Mathematica如何解析的。新的解决方案只是按照Mathematica期望的顺序重新排列字符串以放置日期和月份。

值得注意的是,该28字节的解决方案DayCount[Today,#,"Weekday"]&不仅完美地适用于一个月-日-年-年的输入格式,而且还正确地处理了诸如此类的明确的日-月-年的输入31.12.2018,这不可能表示“第31天的第12天”月”。因此,超过60%的时间是正确的:)



5

R,72个字符

@ngm提供的答案的一种变体,避免了grepl保存一些字符并在非英语语言环境中工作的情况。

sum(strftime(seq(Sys.Date(),as.Date(scan(,""),"%d.%m.%Y"),1),'%u')<6)+1


1
更短更通用。好的答案,欢迎庇护。
ngm

1
欢迎来到PPCG!您可以添加一个TIO链接 -这很容易,并且可以为您设置答案的格式:)
JayCe

5

的Java(OpenJDK的8) 174个 166 165字节

在Kevin的回答中得到了一些启发,并通过不推荐使用的Date API进行了很好的跟踪,我设法获得了更加简洁的Java解决方案。

-8个字节,得益于Kevin的创造性正则表达式日期解析

-1字节归功于Nevay的聪明按位运算

import java.util.*;d->{long r=0,s=new Date().getTime(),e=Date.parse(d.replaceAll("(..).(..).","$2/$1/"));for(;s<=e;s+=864e5)r-=-new Date(s).getDay()%6>>-1;return r;}

在线尝试!

说明

import java.util.*;                         // Required import for Date 
long r=0,                                   // Initialise result variable
     s=new Date().getTime(),                // Current date in millis
     e=Date.parse(
         d.replaceAll("(..).(..).","$2/$1/")// Use regex to convert to MM/dd/yyyy
     );                                     // Parse date arg using deprecated API
for(;s<=e;                                  // Loop while current millis are less than date arg (e.g. date is before)       
    s+=864e5)                               // Add 86400000 ms to current date (equiv of 1 day)
    r-=-new Date(s).getDay()%6>>-1;        // If day is Sunday (0) or Saturday (6) don't increment, else add 1
return r;                                   // When loop finished return result

1
好答案!巧妙地使用varargs d=d[0].split和不赞成.parse使用默认格式MM/dd/yyyy格式。您的帖子中有一个小错误,您的代码import java.text.*;而不是import java.util.*;代码以及// Required import for both Calendar and Date解释(即使您不使用Calendar)也有。
凯文·克鲁伊森

@KevinCruijssen不知道为什么我java.text现在要解决!谢谢!
路加·史蒂文斯

1
尽管我喜欢d=d[0].splitvarargs,但是将输入更改为常规String,然后删除d=d[0].split("\\.");并更改d[1]+"/"+d[0]+"/"+d[2]d.replaceAll("(..).(..).","$2/$1/") 保存7个字节
凯文·克鲁伊森

1
并通过更改为1个字节。:)r+=new Date(s).getDay()%6<1?0:1,s+=864e5);s+=864e5)r+=new Date(s).getDay()%6<1?0:1;
Kevin Cruijssen

1
-1个字节:r-=-new Date(s).getDay()%6>>-1;
Nevay

4

红色,72字节

func[a][b: now/date s: 0 until[if b/weekday < 6[s: s + 1]a < b: b + 1]s]

在线尝试!

采用dd-mm-yyyy格式的日期,例如31-10-2018(也适用于2018年10月10日)

严格输入:

红色,97字节

func[a][a: do replace/all a".""-"b: now/date s: 0 until[if b/weekday < 6[s: s + 1]a < b: b + 1]s]

在线尝试!

奖金:

返回截至给定日期的工作日的日期/工作日列表:

红色,235字节

f: func [ a ] [
    b: now/date
    d: system/locale/days
    collect [ 
        until [ 
            if b/weekday < 6 [ 
                keep/only reduce [ b ":" d/(b/weekday) ]
            ]
            a < b: b + 1
        ]
    ]
]

在线尝试!


啊,不公平,在python中,我需要花费大约72个字节来处理这种IO格式...:P
Quintec '18

1
通常,我的Red解决方案是使用时间最长的解决方案,但是幸运的是Red处理的日期非常好:)
Galen Ivanov

1
90个字节过程蟒蛇......我完了,我不干了,直到有更灵活的输入格式:P
Quintec


3

Python 2中163个 156 149 147字节

lambda s:sum((date.today()+timedelta(x)).weekday()<5for x in range((date(*map(int,(s.split(".")[::-1])))-date.today()).days))
from datetime import*

在线尝试!

-7感谢@mypetlion

多亏了@ovs -7个

+30是由于输入格式非常严格,我只是在发布之前的代码之前才注意到它,例如(2018,11,1):-(


2
无需这样做:(0,1)[t.weekday()<5]。Python的布尔是的一个子类int,并True, False可以在算术运算中使用1,0。替换为c+=t.weekday()<5以节省7个字节。
mypetlion '18 -10-1

1
149个字节作为lambda。
ovs '18 -10-1

谢谢@mypetlion。我不应该错过那个。
ElPedro '18 -10-1

谢谢@ovs。您最近第二次提供帮助。上一次是非常令人印象深刻的-30。正在尝试找出如何将其转化为lambda。
ElPedro '18 -10-1

3

Java(JDK 10),171字节

s->{int c=0;for(var t=java.time.LocalDate.now();!t.parse(s.replaceAll("(..).(..).(.*)","$3-$2-$1")).equals(t);t=t.plusDays(1))c-=t.getDayOfWeek().getValue()/6-1;return c;}

在线尝试!

学分


1
您可以将更(.*)\\.(.*)\\.(.*)改为(..).(..).(.*)
凯文·克鲁伊森

使用您的replaceAll技术,他的答案也可以提高7个字节,因此您的答案仍然略长。;)
Kevin Cruijssen

@KevinCruijssen感谢您的正则表达式!不用担心:我不介意更长的回答;)
OlivierGrégoire18年

3

的JavaScript(Node.js的)168个 160 139 133字节的

减少了35个字节,这要归功于QuintecKevin Cruijssen

D=>{var i=D.split('.'),n=0;for(var d=new Date();d<=new Date(i[2],i[1]-1,i[0]);d.setDate(d.getDate()+1))n+=-~d.getDay()%7>1;return n;}

在线尝试!

D=>{
  var i=D.split('.'),                 // Splits the date string by .
      n=0;                            // Counter variable
  for(var d=new Date();               // For the actual date
      d<=new Date(i[2],i[1]-1,i[0]);      // As long as the date is less or equal the requested date
      d.setDate(d.getDate()+1))           // Count the date one up
    n+=-~d.getDay()%7>1;                // If the date is not a Sunday or Saturday
  return n;                           // Return the counter variable
}

1
带有lambda的158个字节
Quintec,

1
139个字节,如果条件得到改善
Quintec '18年

1
由于您的方法不是递归的,因此您无需将其添加f=到字节数中(并且在TIO上可以将其放在标头中),这就是为什么@Quintec声明它是139个字节而不是141个字节的原因。此外,您可以更改if((d.getDay()+1)%7>1)n++;n+=-~d.getDay()%7>1;高尔夫球它133个字节
凯文·克鲁伊森

1
这里的相关提示与为什么-~i也相同(i+1)。如果您还没有看到,那么阅读JavaScript 技巧<all language>技巧可能会很有趣。:)
Kevin Cruijssen

1
其他一些技巧,供将来参考。
毛茸茸的

3

Python3Numpy,96字节

我无法比无聊的预制解决方案小...

from numpy import*
d=datetime64
lambda s:busday_count(d('today'),d(f'{s[6:]}-{s[3:5]}-{s[:2]}'))

在线尝试!


必须进入Python 3;)
ElPedro

根据您的导入,您不是使用Python 3,而是使用numpy的Python 3
乔纳森·弗雷希

@JonathanFrech应该在标题中吗?其他使用python的人也使用了库,因为python没有用于日期或时间的内置数据类型。
亚伦

1
这取决于您对内置函数的定义-像datetime这样的模块是标准库模块,因此我将它们视为核心语言的一部分。但是,当使用诸如numpy之类的第三方模块时,它会增强该语言的功能,因此我将其视为另一种语言。
乔纳森·弗雷希

2

的PowerShell107 99字节

-8字节感谢mazzy

$d,$m,$y=$args-split'\.';for($a=date;$a-lt(date "$y-$m-$d");$a=$a|% *ys 1){$o+=($a|% D*k)-in1..5}$o

在线尝试!

执行一个正则表达式-split的输入$args,存储该值代入$dAYS,$months,和$y耳,分别。然后,进入一个for循环,初始化$a为今天的日期。距我们输入的目标日期$a-l很久,循环继续进行t。每次迭代时,我们都将1da 添加ys$a,并检查当前值D*k(的缩写DayOfWeek)是否在范围内1..5(即星期一至星期五)。该布尔结果被累加到$o循环中,一旦我们离开循环,该值将留在管道上,并且输出是隐式的。


100个字节?$d,$m,$y=$args-split'\.';for($a=date;$a-lt(date "$y-$m-$d");$a=$a|% *ys 1){$o+=($a|% D*k)-in1..5};$o
MAZZY

1
@mazzy确实。另外,可以删除for(...){...}和之间的分号$o,因此我们现在不到100!
AdmBorkBork,

2

Python 2中147 143 141 140个字节

from datetime import*
lambda e,s=date.today():sum((s+timedelta(x+1)).weekday()<5for x in range((date(*map(int,e.split(".")[::-1]))-s).days))

在线尝试!

接受字符串e,以格式“ dd.MM.YYYY”表示结束日期。(可选)也采用开始日期,但是应该是datetime.date。

开始日期s默认为今天的日期,作为datetime.date对象,以忽略时间。结束时间将解析为datetime.datetime对象,然后转换为日期,因为datetime.date对象没有解析方法,并且无法将datetime添加到日期或从中减去。每天在(开始,结束)中进行迭代,如果其工作日数小于5,则将总数加1。([0-4]是[Mon-Fri],[5-6]是[Sat-Sun])。

伙计们,日期时间解析是最糟糕的。

编辑:偷了ElPedro的map(int,thing)技巧来保存4个字节。

编辑2:ELECTRIC BOOGALOO:通过使其成为匿名函数节省了2个字节。(感谢亚伦!)

编辑3:xrange->范围。(再次感谢亚伦!)


1
You're welcome! Nice answer :)
ElPedro

1
It is convention you can leave off the f= from lambda expressions here
Aaron

1
"Datetime parsing is the worst, you guys" Hahahaha feel my pain, you succeeded where I failed though :P
Quintec

@Aaron I'm never sure if that's okay with multiple functions or with import statements, thanks!
Triggernometry

1
You can also use range rather than xrange it should still work just fine.
Aaron

2

PHP, 66 bytes

for($t=time();$t<strtotime($argn);)$r+=date(N,$t+=86400)<6;echo$r;

empty output for 0; insert + between echo and $r to fix.

Run as pipe with -nr or try it online.


60 bytes with unary output:

for($t=time();$t<strtotime($argn);)echo date(N,$t+=86400)<6;

1

PHP (with Carbon), 107 bytes

function a($d){return Carbon\Carbon::parse($d)->diffInDaysFiltered(function($e){return!$e->isWeekend();});}

1

IBM/Lotus Notes Formula - 99 bytes

d:=i;c:=0;@While(d>@Today;@Set("c";c+@If(@Weekday(d)=1:7;0;1));@Set("d";@Adjust(d;0;0;-1;0;0;0)));c

Takes input from a date/time field i. The input format of i is set to . separated so there is no need to convert the input. Notes can take a date input with any separator as long as you tell it before what it is going to be (hope that's not cheating!). Formula is in computed numeric field o on the same form.

Interesting aside: Ever since @For and @While were introduced into the Formula language in (I think) R6 by the great Damien Katz the only use I have found for them is code golfing. I have never used them in a production app.

There is no TIO available for formula so here is a screenshot taken on 02.10.2018:

enter image description here



1

K4, 40 bytes

Solution:

{+/1<.q.mod[d+!(."."/:|"."\:x)-d:.z.d]7}

Explanation:

Calculate the difference between the dates, use modulo 7 to ignore weekends, sum up.

{+/1<.q.mod[d+!(."."/:|"."\:x)-d:.z.d]7} / the solution
     .q.mod[                         ]7  / modulo with 7
                                 .z.d    / UTC date
                               d:        / save as d
                              -          / subtract from
               (             )           / do this together
                       "."\:x            / split input on "."
                      |                  / reverse
                 "."/:                   / join back with "."
                .                        / take the value
              !                          / range 0..the difference
            d+                           / add today's date to range
   1<                                    / is 1 less than the modulo (ie is this mon-fri)?
 +/                                      / sum up

Notes:

  • same byte alternative to the date parsing: "D"$,/|"."\:x

1

C (clang), 209 208 205 bytes

Compiler flags -DU=u=localtime(&b) -DW=tm_wday -DY=tm_year -DT=tm_yday (52 bytes).

#import<time.h>
i;f(char*a){long b;struct tm t,*u;time(&b);U;strptime(a,"%d.%m.%Y",&t);for(i=0;u->T^t.T|u->Y^t.Y;u->W&&u->W^6&&i++,b+=86400,U);return i;}

Try it online!

-1 byte thanks to @JonathanFrech


?i++:0 -> &&++i.
Jonathan Frech

0

q, 52 79 bytes

{x:"D"$"."sv reverse"."vs x;i:0;while[x-.z.d;$[2>x mod 7;x-:1;[i+:1;x-:1]]];:i}

in q, each date has an underlying integer value, based on how many days have passed since the start of the millenium. Applying 'mod 7' to this, you get unique values for each day of the week (0 for Saturday, 6 for Friday). So when 2 > x mod 7, don't increment the counter, to avoid counting weekends.

EDIT: Missed strict date format, editing

EDIT2: Included


1
Best I've come up with is {sum 1<mod[d+til("D"$x 10 vs 67893401)-d:.z.d]7} for 48 bytes without resorting to K verbs.
streetster

Using the list indices is a lot more elegant than reverse, and rather than using a loop, applying mod to the list. Great answer +1
Thaufeki
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.