Відлік робочого дня


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
Чи є якась конкретна причина цього "неофіційного" європейського формату введення? Наша консенсус полягає в тому, щоб дозволити гнучку інформацію, коли це можливо.
Арнольд

6
Чи дійсно є сенс додавати "додатковий виклик" важко обробляти формат дати? Це просто здається несправедливими мовами wrt, які мають гнучкі формати дати ...
Quintec

3
@Hille Я не казав, що це "важко", це просто зайві клопоти, особливо в коді-гольф ... Зверніть увагу на посилання, яке Арнольд розмістив вище ... як правило, гнучка введення - норма ...
Квінтек

6
До речі, ви зазначаєте, що це ваш перший виклик; Запрошую вас використати «Пісочницю» для доопрацювання, перш ніж надсилати виклик головному! Інакше приємна робота, і мені сподобається побачити ще трохи від вас!
Джузеппе

7
Насправді не вражений суворий формат введення, окрім гарного завдання.
ElPedro

Відповіді:


18

05AB1E , 130 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 або обчислень. Єдиний вбудований термін, який він має, - це рік / місяць / день / години / хвилини / секунди / мікросекунди.

Тож через це майже весь код, який ви бачите, - це ручні обчислення, щоб перейти на наступний день, і обчислювати день тижня.

+5 байт через частину, яку я забув у формулі Зеллера (рік-1 за січень та лютий).

Спробуйте в Інтернеті або Спробуйте в режимі он-лайн із емульованою самоназначеною датою "сьогодні" .

Пояснення:

Стіна вхідного тексту.

Загалом, код відповідає наступному псевдокоду:

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,

Де за місяці з березня по грудень:

  • q -day місяця ([1, 31])
  • m - 1-індексованийmonth ([3, 12])
  • K - рік століття (yearmod100 )
  • J - століття, що індексується 0 (year100)

А за січень та лютий:

  • q -day місяця ([1, 31])
  • m - 1-індексованийmonth+12 ([13, 14])
  • K - рік століття для попереднього року ((year1)mod100 )
  • J - століття, що індексується 0, за попередній рік (year1100)

У результаті цього дня тижня h , де 0 = субота, 1 = неділя, ..., 6 = п’ятниця.
Джерело: конгруенція Зеллера

Це ми бачимо в цій частині програми 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;

Джерела:
Алгоритм визначення того, чи є рік високосним. (EDIT: Більше не актуально, оскільки я використовую альтернативний метод для перевірки високосних років, в якому збережено 7 байт.)
Алгоритм визначення кількості днів у місяці.

6а) Integer isLeapYear = ...;робиться так у програмі 05AB1E:

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 ?і 6с) 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

6h) Else:і 6i) nextDate.day = 1;виконуються так:

ë        # 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:

6 к) 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 байт

Передбачає введення в комірку А1

=NETWORKDAYS(NOW()+1,A1)

Використовує вбудовану функцію. На жаль, ця функція включає як сьогодні, так і дату закінчення. З тих пір ОП уточнила, що сьогодні не рахуватись, тому я додаю її СЕЙЧАС, щоб не рахувати сьогодні.

Знову ж таки, щоб звернутися до коментарів щодо формату номера, це стандарт Excel: введіть тут опис зображення


Незважаючи на те, що це працює зі значеннями дати, він не може взяти введення, як зазначено. Тобто (принаймні, в американській версії) 10.12.2018це рядок, коли вона тримається в комірці, а не датою. Очевидне , але Довгострокове рішення , щоб виправити це було б змінити , A1щоб DATE(RIGHT(A1,4),MID(A1,4,2),LEFT(A1,2))у вашому рішенні
Тейлор Скотт

на жаль, громада вирішила, що мови повинні працювати за їх типовими налаштуваннями, щоб вони були дійсними (єдиний виняток, який я бачив, це мова - IE, якщо ваша мова підтримує і англійську, і іспанську, ви можете легко використовувати будь-яку, але це потрібно зазначити.) Далі, ОП (@hille) не заявляє, що формат є гнучким, а фактично заявив зовсім протилежне (див. другий коментар до цього питання)
Тейлор Скотт

2
Формат не стандартний, він заснований на локальній основі. Excel зчитує формат із HKCU\Control Panel\International\sDecimalрядка реєстру. У США за замовчуванням установка Windows, що становить MM / dd / yyyy. У більшості країн ЄС це буде дефолтом.
Ерік A

@luisMendo Так, це працює. Я не побачив якихось пояснень. Якби раніше не рахувався останній день, я міг би мати = NETWORKDAYS (ЗАРАЗ (), A1-1). Я знав, що це завжди буде однакова кількість байтів, незалежно від пояснення.
Keeta - відновити Моніку

Радий, що працює. Я вилучив голову
Луїс Мендо

11

R , 76 байт

Будь ласка, подивіться і на цю відповідь на 72 байт R, яка також не залежить від місцевості.

sum(!grepl("S",weekdays(seq(Sys.Date(),as.Date(scan(,""),"%d.%m.%Y"),1))))+1

Спробуйте в Інтернеті!

weekdaysдає текст днів тижня, тому ми підраховуємо дні в послідовності між сьогоднішнім та вхідним, які не містять S, і додаємо один до результату.


8

Java 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()?
Квінтек

1
Ми також можемо (я припускаю) це зробити Calendar s=Calendar.getInstance(),e=s.getInstance(), що, на жаль, виходить точно такої ж довжини.
Міша Лавров

1
@MishaLavrov Ага, статика Cсправді не потрібна. Це було зі старої частини коду, де я також використовував Cдесь ще. Уміли гольфу на 1 байт, користуючись var s=Calendar.getInstance();var e=s.getInstance();тим спасибі. :)
Кевін Кройсейсен

1
150 байт , використовуючи java.time.
Олів'є Грегоар

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()

РРРР - ММ - ДД Т год / год : мм : сссс 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,000н


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і т.д.
Кевін Круїссен

@KevinCruijssen Whoops. Спасибі! Виправлено зараз
Луїс Мендо

1
І з тим самим числом байтів. :) Приємно, +1 від мене.
Кевін Кройсейсен

6

Мова Вольфрама (Mathematica) , 64 56 байт

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

Спробуйте в Інтернеті!

DayCount[x,y,"Weekday"]підраховує кількість буднів між xі y.

Входи xі yможуть бути багато речей, в тому числі фантазії , DateObjectяк один повернутий Todayабо рядок у форматі (на жаль) mm.dd.yyyy.

Моя попередня спроба спробувала перетворити dd.mm.yyyyвхід в a DateObject, розповівши Mathematica, як його розібрати; нове рішення просто переставляє рядок, щоб розмістити день і місяць у порядку, який очікує Mathematica.

Варто зазначити, що 28-байтне рішення DayCount[Today,#,"Weekday"]&не тільки чудово працює для формату введення місяць-день-рік, але й правильно обробляє однозначні введення в день-місяць-рік, такі як 31.12.2018, що не могло означати "12-й день 31-го місяць ». Так що це правильно більше 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 байт

Маючи трохи натхнення у відповіді Кевіна та гарному проході через застарілий API API, мені вдалося отримати більш лаконічне рішення Java.

-8 байт завдяки винахідливому розбору дати Кегена за даними підсумкових термінів

-1 байт завдяки розумній операції Невая

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
Гарна відповідь! Розумне використання варагів із формою 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].splitз вараггами, змінюючи вхід на звичайний рядок, видаляючи 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;
Невай

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 (також працює з 10 жовтня-2018)

Суворий вхід:

Червоний , 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

1
Зазвичай мої рішення Red є одними з найдовших, але, на щастя, Red дуже добре справляється з датами :)
Гален Іванов

1
90 байт для обробки python ... Я закінчив, я покину, поки не з’явиться більш гнучкий формат введення: 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

-7 більше завдяки спасибі @ovs

+30 через дуже обмежувальний формат введення, який я помітив лише перед тим, як я розмістив свій попередній код, який приймав введення, наприклад (2018,11,1):-(


2
Не потрібно для цього: (0,1)[t.weekday()<5]. Булеви Python є підкласом intта True, Falseможуть бути використані в арифметичних операціях як 1,0. Замініть його, c+=t.weekday()<5щоб зберегти 7 байт.
mypetlion

1
149 байт як лямбда.
ов

Дякую @mypetlion Я не повинен був пропустити цього.
ElPedro

Дякую @ovs. Вдруге ви допомогли нещодавно. Минулого разу було дуже вражаюче -30. Намагався розібратися, як це перетворити на лямбда.
ElPedro

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 байтах, тому ваша ще трохи довша. ;)
Кевін Круїссен

@KevinCruijssen Дякую за регекс! І не хвилюйтеся: я не проти мати довшу відповідь;)
Олів'є Грегоар

3

JavaScript (Node.js) , 168 160 139 133 байт

На 35 байт менше завдяки Квінтеку та Кевіну Крейссен

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
158 байт з лямбда
Квінтек

1
139 байт з поліпшеною умовою
Квінтек

1
Since your method isn't recursive, you don't need to add the f= to the byte-count (and on TIO you can put it in the header), which is why @Quintec stated it's 139 bytes instead of 141 bytes. In addition, you can change if((d.getDay()+1)%7>1)n++; to n+=-~d.getDay()%7>1; to golf it to 133 bytes.
Kevin Cruijssen

1
Here the relevant tip why -~i is the same as (i+1) Also, if you haven't seen it yet, Tips for golfing in JavaScript and Tips for golfing in <all languages> might be interesting to read through. :)
Kevin Cruijssen

1
A few more tips for future reference.
Shaggy

3

Python3 & Numpy, 96 bytes

I couldn't get smaller than the boring pre-made solution...

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

Try it online!


Must get into Python 3 ;)
ElPedro

Based on your import, you are not using Python 3, but rather Python 3 with numpy.
Jonathan Frech

@JonathanFrech should that be in the title? others using python also have used a library as python has no builtin datatype for dates or times.
Aaron

1
This depends on your definition of builtin -- modules like datetime are standard library modules and thus I would count them as being part of the core language. However, when one uses third-party modules like numpy, one enhances the language's capabilities and therefore I would see it as another language.
Jonathan Frech

2

PowerShell, 107 99 bytes

-8 bytes thanks to 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

Try it online!

Performs a regex -split on the input $args, stores the values into $days, $months, and $years, respectively. Then, enters a for loop, initializing $a to today's date. The loop continues while $a is -lessthan our input target date. Each iteration we're adding 1 days to $a, and checking whether the current D*k (short for DayOfWeek) is in the range 1..5 (i.e., Monday to Friday). That Boolean result is accumulated into $o and once we're out of the loop that value is left on the pipeline and output is implicit.


100 bytes? $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 Indeed. Plus, the semicolon between for(...){...} and $o can be removed, so we're now below 100!
AdmBorkBork

2

Python 2, 147 143 141 140 bytes

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))

Try it online!

Takes a string, e, which represents the end date in the format "dd.MM.YYYY". Optionally also takes the start date, but this is expected to be a datetime.date.

The start date, s, is defaulted to today's date as a datetime.date object in order to disregard time. The end time is parsed into a datetime.datetime object then converted to a date, since datetime.date objects do not have a parse method and datetimes cannot be added to/subtracted from dates. Iterates through every day in (start, end] and adds 1 to the total if its weekday number is < 5. ([0-4] are [Mon-Fri], [5-6] are [Sat-Sun]).

Datetime parsing is the worst, you guys.

EDIT: Stole ElPedro's map(int,thing) trick to save 4 bytes.

EDIT 2: ELECTRIC BOOGALOO: Saved 2 bytes by making it an anonymous function. (Thanks Aaron!)

EDIT 3: xrange -> range. (Thanks again Aaron!)


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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.