Odliczanie dnia pracy

17

Właśnie wpadłem na genialny pomysł na ułatwienie życia zawodowego - odliczanie do określonej daty, która liczy tylko dni robocze.


Podstawowym zadaniem jest utworzenie odliczania do określonej daty, która obejmuje tylko dni robocze w odliczaniu.

Ponieważ liczy się dzień roboczy poniedziałek , wtorek , środa , czwartek i piątek .

Dane wejściowe powinny być konkretną datą w „nieoficjalnym” europejskim formacie standardowym dd.MM.yyyyi muszą być dzisiaj lub dzień w przyszłości.

Wyjście powinno być tylko liczbą dni pozostałych.

Ponieważ jest to w wygrywa najkrótszy kod.


Przypadek testowy:

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

Jeśli pominąłem kilka rzeczy w pytaniu, proszę wybacz mi - to moje pierwsze pytanie :)

EDYTOWAĆ:

  • Możesz użyć falsejako wynik zamiast 0 <- ale to nie jest piękne
  • Nie ma potrzeby przestrzegania DST
Hille
źródło
9
Czy jest jakiś konkretny powód tego „nieoficjalnego” formatu wejściowego w Europie ? Naszym konsensusem jest umożliwienie elastycznego wprowadzania danych, gdy tylko jest to możliwe.
Arnauld
6
Czy naprawdę jest sens dodawania „dodatkowego wyzwania” trudnego do przetworzenia formatu daty? To po prostu wydaje się niesprawiedliwe języki wrt, które mają elastyczne formaty dat ...
Quintec
3
@Hille Nie powiedziałem, że to „trudne”, to po prostu niepotrzebny kłopot, szczególnie w golfie kodowym ... zwróć uwagę na link, który Arnauld zamieścił powyżej ... ogólnie elastyczne wejście jest normą ...
Quintec
6
Nawiasem mówiąc, zauważasz, że to twoje pierwsze wyzwanie; Zapraszam do skorzystania z The Sandbox w celu udoskonalenia przed wysłaniem wyzwania do głównego! W przeciwnym razie fajna robota, a ja z przyjemnością zobaczę trochę więcej od ciebie!
Giuseppe
7
Niezbyt pod wrażeniem ścisłego formatu wejściowego, ale poza tym dobre wyzwanie.
ElPedro

Odpowiedzi:

18

05AB1E , 130 128 133 131 124 123 bajtów

ž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#

Oszalałem..

Dla języka golfowego 05AB1E nie ma znaczenia, czy dane wejściowe są przy pomocy .czy -. Jednak 05AB1E nie ma żadnych wbudowanych obiektów Date ani obliczeń. Jedynym wbudowanym pod względem dat jest dzisiejszy rok / miesiąc / dzień / godziny / minuty / sekundy / mikrosekundy.

Z tego powodu prawie cały kod, który widzisz, to ręczne obliczenia umożliwiające przejście do następnego dnia i obliczanie dnia tygodnia.

+5 bajtów z powodu części, o której zapomniałem we wzorze Zellera (rok-1 dla miesięcy styczeń i luty) ..

Wypróbuj online lub Wypróbuj online z emulowaną, podaną przez siebie datą „dzisiaj” .

Wyjaśnienie:

Ściana tekstu przychodzącego.

Zasadniczo kod jest zgodny z następującym pseudokodem:

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;to ta część programu 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;i 3) Start an infinite loop:są proste w programie 05AB1E:

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

4) If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):to pierwsza trudna część z ręcznymi obliczeniami. Ponieważ 05AB1E nie ma wbudowanej daty, będziemy musieli ręcznie obliczyć dzień tygodnia .

Ogólny wzór na to:

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

Gdzie w miesiącach od marca do grudnia:

  • q jestday miesiąca ([1, 31])
  • m jest 1-indeksowanymmonth ([3, 12])
  • K jest rok w wieku (yearmod100 )
  • J to wiek z indeksowaniem 0 (year100)

A dla miesięcy styczeń i luty:

  • q jestday miesiąca ([1, 31])
  • m jest 1-indeksowanymmonth+12 ([13, 14])
  • K jest rok w wieku w poprzednim roku ((year1)mod100 )
  • J jest stuleciem zindeksowanym w poprzednim roku (year1100 )

Wynik w dniu tygodnia h , gdzie 0 = sobota, 1 = niedziela, ..., 6 = piątek.
Źródło: Zerger Zellera

Widzimy to w tej części programu 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;jest znowu prosty:

     # 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 linejest znowu bardziej skomplikowany, ponieważ musimy to zrobić ręcznie. Zostanie to rozwinięte do następującego pseudokodu:

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;

Źródła:
Algorytm określania, czy rok jest rokiem przestępnym. (EDYCJA: Nie ma już znaczenia, ponieważ używam alternatywnej metody do sprawdzania lat przestępnych, która pozwoliła zaoszczędzić 7 bajtów.)
Algorytm do określania liczby dni w miesiącu.

6a) Integer isLeapYear = ...;odbywa się w następujący sposób w programie 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`

Użyto również w mojej odpowiedzi 05AB1E , więc dodano kilka lat ilustrujących poszczególne kroki.

6b) currentDate.month == 2 ?i 6c) 28 + isLeapYearwykonuje się w następujący sposób:

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) :i 6e) 31 - (currentDate.month - 1) % 7 % 2;wykonuje się w następujący sposób:

ë           # 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):odbywa się w następujący sposób:

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

6g) nextDate.day += 1;wykonuje się w następujący sposób:

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:i 6i) nextDate.day = 1;wykonuje się w następujący sposób:

ë        # 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;i 6n) nextDate.year += 1;wykonuje się w następujący sposób:

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

I wreszcie o 8) If(currentDate == parsed input-string):i 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)
Kevin Cruijssen
źródło
5
Jesteś wariatem ... masz głos.
AdmBorkBork
1
Najdłuższy program 05AB1E?
Luis Mendo
2
@LuisMendo Close, ale obawiam się, że mam jedną odpowiedź 05AB1E, która jest jeszcze dłuższa , i ta, która jest zbyt blisko .. ;) Jestem pewien, że będę w stanie zagrać w golfa kilka bajtów tutaj i uprościć części implementacji pseudokodu następnego dnia. Będę wyglądał jutro rano, ale właśnie wróciłem ze sportu i wkrótce pójdę spać.
Kevin Cruijssen
11

Excel 24 bajtów

Zakłada dane wejściowe w komórce A1

=NETWORKDAYS(NOW()+1,A1)

Używa wbudowanej funkcji. Niestety funkcja obejmuje zarówno datę dzisiejszą, jak i datę końcową. Od tego czasu OP wyjaśniło, że nie należy dziś liczyć, więc dodam jeden do TERAZ, aby dzisiaj nie liczyć.

Aby odpowiedzieć na komentarze dotyczące formatu liczby, ponownie jest to standard Excel: enter image description here

Keeta - przywróć Monikę
źródło
Chociaż działa to z wartościami daty, nie pobiera danych wejściowych, jak podano. To znaczy (przynajmniej w wersji amerykańskiej) 10.12.2018jest ciągiem, gdy jest przechowywany w komórce, a nie w dacie. Oczywistym rozwiązaniem, ale długo, aby skorygować ten będzie zmieniać A1się DATE(RIGHT(A1,4),MID(A1,4,2),LEFT(A1,2))w roztworze
Taylor Scott
niestety społeczność zdecydowała, że ​​języki muszą być uruchamiane w ustawieniach domyślnych, aby były prawidłowe (jedynym wyjątkiem, który widziałem w tym przypadku, jest język - IE, jeśli twój język obsługuje zarówno angielski, jak i hiszpański, możesz z łatwością użyć jednego z nich, ale należy to zauważyć.) Ponadto OP (@hille) nie stwierdził, że format jest elastyczny, a wręcz przeciwnie (patrz drugi komentarz do tego pytania)
Taylor Scott,
2
Format nie jest standardowy, jest oparty na ustawieniach regionalnych. Excel odczytuje format z ciągu HKCU\Control Panel\International\sDecimalrejestru. W przypadku domyślnej instalacji systemu Windows w USA, czyli MM / dd / rrrr. W większości krajów UE byłoby to ustawienie domyślne.
Erik A
@luisMendo Tak, to działa. Nie widziałem żadnych wyjaśnień. Gdyby zamiast tego nie liczyć ostatniego dnia, mógłbym mieć = NETWORKDAYS (NOW (), A1-1). Wiedziałem, że zawsze będzie to ta sama liczba bajtów, bez względu na wyjaśnienie.
Keeta
Cieszę się, że to działa. Usunąłem głos negatywny
Luis Mendo
8

Java 10, 233 232 226 bajtów

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;}

Data zawsze przypomina mi, jak naprawdę pełna jest Java.

UWAGA: Istnieją teraz dwie krótsze odpowiedzi Java (poniżej 175 bajtów), jedna z inteligentnym użyciem przestarzałych metod z wcześniejszych wersji Java autorstwa @LukeStevens , a druga java.time.LocalDatez nowymi od Java 8 przez @ OlivierGrégoire .

Wypróbuj online.

Wyjaśnienie:

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
Kevin Cruijssen
źródło
Można zrobić e=s.clone()?
Quintec,
1
Możemy również (zakładam) zrobić Calendar s=Calendar.getInstance(),e=s.getInstance(), co niestety kończy się dokładnie taką samą długością.
Misha Lavrov
1
@MishaLavrov Ah, statyczne Crzeczywiście nie jest konieczne. To było ze starej części kodu, w której również użyłem Cgdzie indziej. Dzięki temu mogłem zagrać w golfa 1 bajt var s=Calendar.getInstance();var e=s.getInstance();. :)
Kevin Cruijssen
1
150 bajtów , używając java.time.
Olivier Grégoire,
1
Gotowy! Jest bardzo blisko bajtów do drugiej odpowiedzi, ale jeszcze jej nie pokonał.
Olivier Grégoire,
7

JavaScript (ES6), 116 103 bajtów

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

Wypróbuj online!

W jaki sposób?

n

nD.toJSON()

RRRR - MM - DD T gg : mm : ss.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

Arnauld
źródło
6

MATL , 24 bajty

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

Wypróbuj online!

Nie chcę mieć żadnego formatu wejściowego, aby określone języki kodu golfa miały dużą zaletę

W połowie się udało :-)

Wyjaśnienie

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
Luis Mendo
źródło
Jeśli poprawnie zrozumiałem wyzwanie, bierzesz tylko jedną datę i porównujesz ją z dzisiejszą datą. Na przykład, 16.10.2018czy dzisiaj (poniedziałek 01-10-2018) spowoduje 11, jutro 10itd.
Kevin Cruijssen
@KevinCruijssen Whoops. Dzięki! Poprawione teraz
Luis Mendo
1
I z tą samą liczbą bajtów. :) Fajnie, +1 ode mnie.
Kevin Cruijssen
6

Wolfram Language (Mathematica) , 64 56 bajtów

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

Wypróbuj online!

DayCount[x,y,"Weekday"]zlicza liczbę dni tygodnia między xiy .

Wejściami xi ymoże być wiele rzeczy, w tym fantazyjne, DateObjecttakie jak zwracane przez Today, lub ciąg znaków w formacie (niestety)mm.dd.yyyy .

Moja poprzednia próba przekształciła dane dd.mm.yyyywejściowe w DateObjectpowiedzenie Mathematica, jak je parsować; nowe rozwiązanie po prostu zmienia ciąg, aby ustawić dzień i miesiąc w kolejności zgodnej z oczekiwaniami Mathematica.

Warto zauważyć, że 28-bajtowe rozwiązanie DayCount[Today,#,"Weekday"]&nie tylko doskonale sprawdza się w przypadku formatu wejściowego miesiąc-dzień-rok, ale także poprawnie obsługuje jednoznaczne dane wejściowe dzień-miesiąc-rok, takie jak 31.12.2018, co nie mogło oznaczać „12 dnia 31-go” miesiąc". Więc to prawda przez ponad 60% czasu :)

Misza Ławrow
źródło
5

Perl 6 , 61 bajtów

{+grep 6>*.day-of-week,Date.today^..Date.new(|[R,] m:g/\d+/)}

Wypróbuj online!

nwellnhof
źródło
5

R, 72 znaki

Odmiana odpowiedzi udzielonej przez @ngm, która pozwala greplowi zaoszczędzić kilka znaków i działa w lokalizacjach innych niż angielski.

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

Neal Fultz
źródło
1
Krótszy i bardziej ogólny. Dobra odpowiedź i witamy w azylu.
ngm
1
Witamy w PPCG! możesz dodać link TIO - to proste i formatuje dla ciebie odpowiedź :)
JayCe
5

Java (OpenJDK 8) , 174 166 165 bajtów

Z odrobiną inspiracji z odpowiedzi Kevina i dobrym włokiem przez przestarzałe Date API, udało mi się uzyskać bardziej zwięzłe rozwiązanie Java.

-8 bajtów dzięki pomysłowej analizie wyrażeń regularnych Kevina

-1 bajty dzięki sprytnej bitowej operacji 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;}

Wypróbuj online!

Wyjaśnienie

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
Luke Stevens
źródło
1
Niezła odpowiedź! Inteligentne korzystanie z varargs zi d=d[0].splitprzestarzałym .parsedomyślnym formatem MM/dd/yyyyformatu. Jeden mały błąd w swoim poście, który masz import java.text.*;zamiast import java.util.*;w kodzie i // Required import for both Calendar and Datew wyjaśnieniu (nawet jeśli nie używasz Calendar).
Kevin Cruijssen
@KevinCruijssen Nie mam pojęcia, dlaczego już to java.textnaprawiłem! Dzięki!
Luke Stevens
1
Chociaż podobało mi się to d=d[0].splitz varargs, zmiana danych wejściowych na zwykły ciąg znaków, usunięcie d=d[0].split("\\.");i zmiana d[1]+"/"+d[0]+"/"+d[2]na d.replaceAll("(..).(..).","$2/$1/") zapisywanie 7 bajtów .
Kevin Cruijssen
1
I jeszcze 1 bajt , zmieniając r+=new Date(s).getDay()%6<1?0:1,s+=864e5);na s+=864e5)r+=new Date(s).getDay()%6<1?0:1;. :)
Kevin Cruijssen
1
-1 bajt:r-=-new Date(s).getDay()%6>>-1;
Nevay
4

Czerwony , 72 bajty

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

Wypróbuj online!

Przyjmuje datę w formacie dd-mm-rrrr, na przykład 31-10-2018 (działa również z 10-paź-2018)

Ścisłe wejście:

Czerwony , 97 bajtów

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]

Wypróbuj online!

Premia:

Zwraca listę dat / dni roboczych dni roboczych do podanej daty:

Czerwony , 235 bajtów

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

Wypróbuj online!

Galen Iwanow
źródło
Agh, nie fair, w pythonie muszę wydać około 72 bajtów na przetwarzanie tego formatu IO ...: P
Quintec
1
Zazwyczaj moje czerwone rozwiązania należą do najdłuższych, ale na szczęście Red bardzo dobrze radzi sobie z datami :)
Galen Iwanow
1
90 bajtów do przetworzenia pytona ... gotowe, wychodzę, dopóki nie jest bardziej elastyczny format wejściowy: P
Quintec
4

JavaScript, 87 85 bajtów

Zwraca falseza 0.

s=>([d,m,y]=s.split`.`,g=_=>new Date<(x=new Date(y,~-m,d--))&&(x.getDay()%6>0)+g())()

Wypróbuj online lub sprawdź następne 31 dni

Kudłaty
źródło
3

Python 2 , 163 156 149 147 bajtów

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

Wypróbuj online!

-7 dzięki dzięki @mypetlion

-7 więcej dzięki dzięki @ovs

+30 ze względu na bardzo restrykcyjny format wejściowy, który zauważyłem dopiero przed opublikowaniem mojego poprzedniego kodu, który pobierał dane jako np . (2018,11,1):-(

ElPedro
źródło
2
Nie potrzeba do tego: (0,1)[t.weekday()<5]. Booleany Pythona są podklasą inti True, Falsemogą być używane w operacjach arytmetycznych jako 1,0. Zamień go na, c+=t.weekday()<5aby zaoszczędzić 7 bajtów.
mypetlion
1
149 bajtów jako lambda.
ovs
Dzięki @mypetlion. Nie powinnam tego przegapić.
ElPedro
Dzięki @ovs. Za drugim razem pomogłeś ostatnio. Ostatni raz był bardzo imponujący -30. Próbowałem się dowiedzieć, jak to zrobić w lambda.
ElPedro
3

Java (JDK 10) , 171 bajtów

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;}

Wypróbuj online!

Kredyty

Olivier Grégoire
źródło
1
Można zmienić (.*)\\.(.*)\\.(.*)TO (..).(..).(.*).
Kevin Cruijssen
Dzięki twojej replaceAlltechnice jego odpowiedź może być golfa o 7 bajtów, więc twoja jest jeszcze nieco dłuższa. ;)
Kevin Cruijssen
@KevinCruijssen Dzięki za wyrażenie regularne! I nie martw się: nie mam nic przeciwko dłuższej odpowiedzi;)
Olivier Grégoire,
3

JavaScript (Node.js) , 168 160 139 133 bajtów

35 bajtów mniej dzięki Quintec i Kevin 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;}

Wypróbuj online!

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
}
Hille
źródło
1
158 bajtów z lambda
Quintec
1
139 bajtów z poprawionym warunkiem, jeśli
Quintec
1
Ponieważ twoja metoda nie jest rekurencyjna, nie musisz dodawać f=liczby do liczby bajtów (a w TIO możesz umieścić ją w nagłówku), dlatego @Quintec stwierdził, że ma 139 bajtów zamiast 141 bajtów. Ponadto, można zmienić if((d.getDay()+1)%7>1)n++;do n+=-~d.getDay()%7>1;golfa ją do 133 bajtów .
Kevin Cruijssen
1
Oto odpowiednia wskazówka, dlaczego -~ijest to samo, co(i+1) również. Jeśli jeszcze go nie widziałeś, wskazówki dotyczące gry w JavaScript w JavaScript i wskazówki dotyczące gry w <wszystkie języki> mogą być interesujące do przeczytania. :)
Kevin Cruijssen
1
Kilka dodatkowych wskazówek na przyszłość.
Kudłaty
3

Python3 i Numpy , 96 bajtów

Nie mogłem być mniejszy niż nudne gotowe rozwiązanie ...

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

Wypróbuj online!

Aaron
źródło
Musi dostać się do Pythona 3;)
ElPedro
Na podstawie importu nie używasz Python 3 , ale Python 3 z Numpy .
Jonathan Frech
@JonathanFrech powinien być w tytule? inni używający Pythona również używali biblioteki, ponieważ Python nie ma wbudowanego typu danych dla dat ani godzin.
Aaron
1
Zależy to od twojej definicji wbudowanych - moduły takie jak datetime są standardowymi modułami bibliotecznymi i dlatego policzyłbym je jako część podstawowego języka. Jednak, gdy używa się modułów innych firm, takich jak numpy , poprawia się możliwości tego języka i dlatego postrzegałbym go jako inny język.
Jonathan Frech
2

PowerShell , 107 99 bajtów

-8 bajtów dzięki 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

Wypróbuj online!

Wykonuje regex -splitna wejściu $args, przechowuje wartości do $dAys, $months i $yuszu, odpowiednio. Następnie wchodzi w forpętlę, inicjuje się $ado dzisiejszej daty. Pętla trwa, dopóki $anie -lupłynie tnasza docelowa data wejścia. Każda iteracja dodajemy 1da yssię $ai sprawdzenie czy prądu D*k(skrót DayOfWeek) mieści się w zakresie 1..5(czyli od poniedziałku do piątku). Ten wynik boolowski jest kumulowany $oi kiedy jesteśmy poza pętlą, ta wartość pozostaje w potoku, a dane wyjściowe są niejawne.

AdmBorkBork
źródło
100 bajtów? $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 Rzeczywiście. Dodatkowo średnik między for(...){...}i $omożna go usunąć, więc jesteśmy teraz poniżej 100!
AdmBorkBork
2

Python 2 , 147 143 141 140 bajtów

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

Wypróbuj online!

Pobiera ciąg e, który reprezentuje datę zakończenia w formacie „dd.MM.RRRR”. Opcjonalnie przyjmuje również datę początkową, ale oczekuje się, że będzie to data / godzina.

Data rozpoczęcia s jest domyślnie ustawiona na dzisiejszą datę jako obiekt datetime.date, aby nie uwzględniać czasu. Czas zakończenia jest analizowany w obiekcie datetime.datetime, a następnie konwertowany na datę, ponieważ obiekty datetime.date nie mają metody parsowania, a okresów danych nie można dodawać do / odejmować od dat. Iteruje przez każdy dzień w (początek, koniec] i dodaje 1 do sumy, jeśli jego liczba dni w tygodniu wynosi <5. ([0–4] to [pn – pt], [5–6] to [sob. – Niedz.]).

Przetwarzanie Datetime jest najgorsze.

EDYCJA: Mapa Stole ElPedro (int, rzecz) sztuczka, aby zapisać 4 bajty.

EDYCJA 2: ELEKTRYCZNY BOOGALOO: Zapisano 2 bajty, czyniąc z niego funkcję anonimową. (Dzięki Aaron!)

EDYCJA 3: xzakres -> zasięg. (Jeszcze raz dziękuję, Aaron!)

Triggernometria
źródło
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;
Titus
źródło
1

PHP (with Carbon), 107 bytes

function a($d){return Carbon\Carbon::parse($d)->diffInDaysFiltered(function($e){return!$e->isWeekend();});}
Daniel
źródło
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

ElPedro
źródło
1

Ruby, 81 bytes

->e{require'date';(Date.today...Date.strptime(e,'%d.%m.%Y')).count{|d|6>d.cwday}}

Try it online!

Idva
źródło
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
streetster
źródło
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

Logern
źródło
?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

Thaufeki
źródło
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