Le compte à rebours de la journée de travail


17

Je viens d'avoir une idée géniale pour rendre la vie professionnelle plus facile - un compte à rebours pour une date spécifique qui ne compte que les jours ouvrables.


La tâche de base consiste à créer un compte à rebours à une date spécifique qui inclut uniquement les jours ouvrables dans le compte à rebours.

Comme la journée de travail compte lundi , mardi , mercredi , jeudi et vendredi .

L'entrée doit être une date spécifique dans le format standard européen "non officiel" dd.MM.yyyyet doit être aujourd'hui ou un jour dans le futur.

Le résultat ne doit être que le nombre de jours restants.

Comme c'est du de le plus court gagne.


Cas de test:

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

Si j'ai raté certaines choses dans la question, veuillez me pardonner - c'est ma première question :)

ÉDITER:

  • Vous pouvez utiliser falsecomme sortie au lieu de0 <- mais ce n'est pas beau
  • Pas besoin de respecter l'heure d'été

9
Y a-t-il une raison particulière derrière ce format d'entrée européen "non officiel" ? Notre consensus est de permettre une contribution flexible dans la mesure du possible.
Arnauld

6
Est-il vraiment utile d'ajouter le "défi supplémentaire" d'un format de date difficile à traiter? Cela semble tout simplement injuste dans les langues qui ont des formats de date flexibles ...
Quintec

3
@Hille je n'ai pas dit que c'était "dur", c'est juste un tracas inutile, surtout dans le code-golf ... notez le lien qu'Arnauld a posté ci-dessus ... l'entrée généralement flexible est la norme ...
Quintec

6
Soit dit en passant, vous notez que c'est votre premier défi; Je vous invite à utiliser The Sandbox pour le raffinement avant de poster un défi à main! Sinon, beau travail, et j'apprécierai d'en voir plus de vous!
Giuseppe

7
Pas vraiment impressionné par le format d'entrée strict mais à part ça un bon défi.
ElPedro

Réponses:


18

05AB1E , 130 128 133 131 124 124 123 octets

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

Je suis hors de mon esprit..

Pour la langue de golf 05AB1E, peu importe que l'entrée soit avec .ou- . Cependant, 05AB1E n'a pas de commandes intégrées pour les objets Date ou les calculs. Le seul élément intégré concernant les dates dont il dispose est l'année / mois / jour / heures / minutes / secondes / microsecondes d'aujourd'hui.

Donc à cause de cela, la quasi-totalité du code que vous voyez sont des calculs manuels pour aller au lendemain et calculer le jour de la semaine.

+5 octets en raison d'une partie que j'ai oubliée dans la formule de Zeller (année 1 pour les mois de janvier et février) ..

Essayez-le en ligne ou essayez-le en ligne avec une date émulée auto-spécifiée de «aujourd'hui» .

Explication:

Mur de texte entrant.

En général, le code suit le pseudo-code suivant:

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;fait partie du programme 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;et 3) Start an infinite loop:sont simples dans le programme 05AB1E:

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

4) If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):est la première partie difficile avec des calculs manuels. Comme 05AB1E n'a pas de date intégrée, nous devrons calculer le jour de la semaine manuellement.

La formule générale pour ce faire est:

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

Où pour les mois de mars à décembre:

  • q est leday du mois ([1, 31])
  • m est le 1-indexé month ( [3, 12])
  • K est l'année du siècle ( yearmod100 )
  • J est le siècle indexé sur 0 ( year100)

Et pour les mois janvier et février:

  • q est leday du mois ( [1, 31])
  • m est le m indexémonth+12 ([13, 14])
  • K est l'année du siècle pour l'année précédente ((year1)mod100 )
  • J est le siècle indexé sur 0 pour l'année précédente (year1100)

Il en résulte le jour de la semaine h , où 0 = samedi, 1 = dimanche, ..., 6 = vendredi.
Source: congruence de Zeller

Nous pouvons le voir dans cette partie du programme 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;est à nouveau simple:

     # 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 lineest encore plus complexe, car nous devons le faire manuellement. Donc, cela sera étendu au pseudo-code suivant:

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;

Sources:
algorithme pour déterminer si une année est une année bissextile. (EDIT: n'est plus pertinent, car j'utilise une méthode alternative pour vérifier les années bissextiles qui ont économisé 7 octets.)
Algorithme pour déterminer le nombre de jours dans un mois.

6a) Integer isLeapYear = ...;se fait comme ceci dans le programme 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`

Également utilisé dans ma réponse 05AB1E , il y a donc quelques années d'exemple qui sont ajoutées pour illustrer les étapes.

6b) currentDate.month == 2 ?et 6c) 28 + isLeapYearse font comme ceci:

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) : et 6e) 31 - (currentDate.month - 1) % 7 % 2;se font comme ceci:

ë           # 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):se fait comme ceci:

     # 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; se fait comme ceci:

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: et 6i) se nextDate.day = 1;font alors comme ceci:

ë        # 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; et 6n) se nextDate.year += 1;font alors comme ceci:

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

Et enfin à 8) If(currentDate == parsed input-string):et 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
Vous êtes un fou ... ayez un vote positif.
AdmBorkBork

1
Le plus long programme 05AB1E de tous les temps?
Luis Mendo

2
@LuisMendo Fermer, mais je crains d'avoir une réponse 05AB1E moi-même encore plus longue et une réponse beaucoup trop proche .. ;) Je suis sûr que je pourrai jouer quelques octets ici et là et simplifier parties de l'implémentation de pseudo-code du lendemain. Regardera demain matin, mais vient de rentrer du sport et se couchera bientôt.
Kevin Cruijssen du

11

Excel 24 octets

Suppose l'entrée dans la cellule A1

=NETWORKDAYS(NOW()+1,A1)

Utilise la fonction intégrée. Malheureusement, la fonction comprend à la fois aujourd'hui et la date de fin. Depuis, OP a précisé de ne pas compter aujourd'hui, donc j'en ajoute un à MAINTENANT pour ne pas compter aujourd'hui.

Pour répondre aux commentaires sur le format du nombre, encore une fois, c'est la norme Excel: entrez la description de l'image ici


Bien que cela fonctionne avec les valeurs de date, il ne prend pas en compte les entrées comme indiqué. Autrement dit (au moins dans la version américaine) 10.12.2018est une chaîne lorsqu'elle est conservée dans une cellule plutôt qu'une date. La solution évidente , mais longtemps pour corriger ce serait de changer A1à DATE(RIGHT(A1,4),MID(A1,4,2),LEFT(A1,2))votre solution
Taylor Scott

malheureusement, la communauté a décidé que les langues doivent être exécutées sous leurs paramètres par défaut pour être valides (la seule exception que j'ai constatée est la langue - IE, si votre langue prend en charge l'anglais et l'espagnol, vous pouvez facilement utiliser l'une ou l'autre, mais cela doit être noté.) De plus, OP (@hille) n'a pas déclaré que le format est flexible, et a en fait déclaré le contraire (voir le deuxième commentaire sur cette question)
Taylor Scott

2
Le format n'est pas standard, il est basé sur les paramètres régionaux. Excel lit le format dans la HKCU\Control Panel\International\sDecimalchaîne de registre. Sur une installation US Windows par défaut, c'est MM / jj / aaaa. Dans la plupart des pays de l'UE, ce serait la valeur par défaut.
Erik A

@luisMendo Oui, cela fonctionne. Je n'ai vu aucune clarification. Si cela n'avait pas dû compter le jour dernier, j'aurais pu = NETWORKDAYS (NOW (), A1-1). Je savais que ce serait toujours le même nombre d'octets, quelle que soit la clarification.
Keeta - réintègre Monica

Heureux que ça marche. J'ai supprimé le downvote
Luis Mendo


8

Java 10, 233 232 226 octets

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

La date me rappelle toujours à quel point Java est verbeux.

REMARQUE: il existe désormais deux réponses Java plus courtes (inférieures à 175 octets), l' une avec une utilisation intelligente des méthodes obsolètes des versions Java antérieures de @LukeStevens , et l' autre utilisant la java.time.LocalDatenouveauté depuis Java 8 de @ OlivierGrégoire .

Essayez-le en ligne.

Explication:

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

Pourriez-vous faire e=s.clone()?
Quintec

1
Nous pouvons aussi (je suppose) faire Calendar s=Calendar.getInstance(),e=s.getInstance(), ce qui finit malheureusement par être exactement de la même longueur.
Misha Lavrov

1
@MishaLavrov Ah, la statique Cn'est en effet pas nécessaire. Il provenait d'une ancienne partie du code où je l'ai également utilisé Cailleurs. J'ai pu jouer au golf 1 octet en utilisant var s=Calendar.getInstance();var e=s.getInstance();donc merci. :)
Kevin Cruijssen

1
150 octets , en utilisant java.time.
Olivier Grégoire

1
Terminé! Il est très proche en octets de l'autre réponse, mais ne le bat pas encore.
Olivier Grégoire

7

JavaScript (ES6), 116 103 octets

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

Essayez-le en ligne!

Comment?

n

nD.toJSON()

AAAA - MM - JJ T hh : 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


6

MATL , 24 octets

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

Essayez-le en ligne!

Je ne veux pas avoir de format d'entrée afin que les langues de golf de code spécifiques aient un gros avantage

Vous avez à moitié réussi :-)

Explication

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

Si j'ai bien compris le défi, vous ne prenez qu'une seule entrée de date et la comparez à la date d'aujourd'hui. Par exemple, 16.10.2018aujourd'hui (lundi 01-10-2018) se traduirait-il par 11, demain à 10, etc.
Kevin Cruijssen

@KevinCruijssen Oups. Merci! Corrigé maintenant
Luis Mendo

1
Et avec le même nombre d'octets. :) Sympa, +1 de ma part.
Kevin Cruijssen

6

Wolfram Language (Mathematica) , 64 56 octets

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

Essayez-le en ligne!

DayCount[x,y,"Weekday"]compte le nombre de jours de semaine entre xety .

Les entrées xet ypeuvent être beaucoup de choses, y compris une fantaisie DateObjectcomme celle retournée par Today, ou une chaîne au format (malheureusement)mm.dd.yyyy .

Ma tentative précédente a essayé de transformer l' dd.mm.yyyyentrée en unDateObject en disant à Mathematica comment l'analyser; la nouvelle solution réorganise simplement la chaîne pour mettre le jour et le mois dans l'ordre que Mathematica attend.

Il convient de noter que la solution de 28 octets fonctionne DayCount[Today,#,"Weekday"]&non seulement parfaitement pour un format d'entrée mois-jour-année, mais gère également correctement les entrées jour-mois-année sans ambiguïté telles que 31.12.2018, ce qui ne pourrait pas signifier "le 12e jour du 31" mois". C'est donc correct plus de 60% du temps :)



5

R, 72 caractères

Une variation de la réponse fournie par @ngm qui évite au grepl de sauvegarder quelques caractères et fonctionne dans des environnements locaux non anglais.

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


1
Plus court et plus général aussi. Belle réponse et bienvenue à l'asile.
ngm

1
Bienvenue chez PPCG! vous pouvez ajouter un lien TIO - c'est facile et formate la réponse pour vous :)
JayCe

5

Java (OpenJDK 8) , 174 166 165 octets

Avec un peu d'inspiration dans la réponse de Kevin et un bon vieux chalut à travers l'API Date obsolète, j'ai réussi à obtenir une solution Java plus succincte.

-8 octets grâce à l'analyse inventive des dates d'expressions regex de Kevin

-1 octets grâce au fonctionnement intelligent au niveau du bit de 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;}

Essayez-le en ligne!

Explication

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
Bonne réponse! Utilisation intelligente des varargs avec les d=d[0].splitet obsolètes .parseavec le format par défaut MM/dd/yyyy. Une petite erreur dans votre message, vous en avez import java.text.*;au lieu de import java.util.*;dans votre code, et // Required import for both Calendar and Datedans votre explication (même si vous ne l'utilisez pas Calendar).
Kevin Cruijssen

@KevinCruijssen Aucune idée pourquoi je l'avais java.textmais réparé maintenant! Merci!
Luke Stevens

1
Bien que j'aimais le d=d[0].splitavec les varargs, changer l'entrée en une chaîne régulière, la supprimer d=d[0].split("\\.");et la changer d[1]+"/"+d[0]+"/"+d[2]pour d.replaceAll("(..).(..).","$2/$1/") économiser 7 octets .
Kevin Cruijssen

1
Et 1 octet de plus en changeant r+=new Date(s).getDay()%6<1?0:1,s+=864e5);pour s+=864e5)r+=new Date(s).getDay()%6<1?0:1;. :)
Kevin Cruijssen

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

4

Rouge , 72 octets

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

Essayez-le en ligne!

Prend la date au format jj-mm-aaaa, par exemple 31-10-2018 (fonctionne également avec 10-oct-2018)

Entrée stricte:

Rouge , 97 octets

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]

Essayez-le en ligne!

Prime:

Renvoie une liste des dates / jours ouvrables des jours ouvrables jusqu'à la date donnée:

Rouge , 235 octets

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

Essayez-le en ligne!


Agh, pas juste, en python, je dois dépenser environ 72 octets pour traiter ce format d'E / S ...: P
Quintec

1
Habituellement, mes solutions Red sont parmi les plus longues, mais heureusement, Red gère très bien les dates :)
Galen Ivanov

1
90 octets pour traiter python ... j'ai terminé, je quitte jusqu'à ce qu'il y ait un format d'entrée plus flexible: P
Quintec


3

Python 2 , 163 156 149 149 147 octets

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

Essayez-le en ligne!

-7 avec merci à @mypetlion

-7 de plus grâce à @ovs

+30 en raison du format d'entrée très restrictif que je n'ai remarqué que juste avant de poster mon code précédent qui prenait par exemple (2018,11,1):-(


2
Pas besoin de ceci: (0,1)[t.weekday()<5]. Les booléens Python sont une sous-classe de intet True, Falsepeuvent être utilisés dans des opérations arithmétiques comme 1,0. Remplacez-le par c+=t.weekday()<5pour économiser 7 octets.
mypetlion

1
149 octets en lambda.
1er

Merci @mypetlion. Je n'aurais pas dû rater ça.
ElPedro

Merci @ovs. Deuxième fois que vous avez aidé récemment. La dernière fois, c'était un très impressionnant -30. J'essayais de trouver comment intégrer cela dans un lambda.
ElPedro

3

Java (JDK 10) , 171 octets

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

Essayez-le en ligne!

Crédits


1
Vous pouvez changer le (.*)\\.(.*)\\.(.*)en (..).(..).(.*).
Kevin Cruijssen du

Avec votre replaceAlltechnique, sa réponse peut également être jouée de 7 octets, donc la vôtre est encore légèrement plus longue. ;)
Kevin Cruijssen

@KevinCruijssen Merci pour l'expression régulière! Et pas de soucis: ça ne me dérange pas d'avoir une réponse plus longue;)
Olivier Grégoire

3

JavaScript (Node.js) , 168 160 139 139 133 octets

35 octets de moins grâce à Quintec et 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;}

Essayez-le en ligne!

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 octets avec lambda
Quintec

1
139 bytes with improved if condition
Quintec

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.