La cuenta regresiva del día laboral

17

Tuve una idea genial para facilitar la vida laboral: una cuenta regresiva para una fecha específica que solo cuenta los días laborables.


La tarea básica es crear una cuenta regresiva para una fecha específica que solo incluye los días laborables en la cuenta regresiva.

Como la jornada laboral cuenta lunes , martes , miércoles , jueves y viernes .

La entrada debe ser una fecha específica en el formato estándar europeo "no oficial" dd.MM.yyyyy debe ser hoy o un día en el futuro.

La salida solo debe ser el número de días restantes.

Como es el código más corto gana.


Caso de prueba:

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

Si me perdí algunas cosas en la pregunta, perdóname, es mi primera pregunta :)

EDITAR:

  • Puedes usar false como salida en lugar de 0 <, pero no es hermoso
  • No es necesario respetar el horario de verano
Hille
fuente
9
¿Hay alguna razón específica detrás de este formato de entrada europeo "no oficial" ? Nuestro consenso es permitir aportes flexibles siempre que sea posible.
Arnauld
66
¿Hay realmente algún punto en agregar el "desafío adicional" de un formato de fecha difícil de procesar? Eso simplemente parece injusto en idiomas wrt que tienen formatos de fecha flexibles ...
Quintec
3
@Hille No dije que era "difícil", simplemente es una molestia innecesaria, especialmente en el código de golf ... tenga en cuenta el enlace que Arnauld publicó arriba ... generalmente la entrada flexible es la norma ...
Quintec
66
Por cierto, notas que este es tu primer desafío; ¡Te invito a usar The Sandbox para perfeccionar antes de publicar un desafío a main! De lo contrario, buen trabajo, ¡y disfrutaré viendo un poco más de ti!
Giuseppe
77
No estoy realmente impresionado por el formato de entrada estricto, pero aparte de eso, es un buen desafío.
ElPedro

Respuestas:

18

05AB1E , 130 128 133 131 124 123 bytes

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

Estoy fuera de mí..

Para el lenguaje de golf 05AB1E no importa en absoluto si la entrada es con . o -. Sin embargo, 05AB1E no tiene ninguna función integrada para los objetos o cálculos de fecha. Lo único que incluye las fechas que tiene es el año / mes / día / horas / minutos / segundos / microsegundos de hoy.

Por eso, casi todo el código que ves son cálculos manuales para ir al día siguiente y calcular el día de la semana.

+5 bytes debido a una parte que olvidé en la fórmula de Zeller (año 1 para los meses de enero y febrero).

Pruébelo en línea o Pruébelo en línea con una fecha autoevaluada emulada de 'hoy' .

Explicación:

Muro de texto entrante.

En general, el código sigue el siguiente pseudocódigo:

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;es esta parte del programa 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;y 3) Start an infinite loop:son sencillos en el programa 05AB1E:

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

4) If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):es la primera parte difícil con cálculos manuales. Dado que 05AB1E no tiene fechas incorporadas, tendremos que calcular el día de la semana manualmente.

La fórmula general para hacer esto es:

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

Dónde para los meses de marzo a diciembre:

  • q es elday del mes ([1, 31])
  • m es el 1 indexadomonth ([3, 12])
  • K es el año del siglo (yearmod100 )
  • J es el siglo indexado 0 (year100)

Y para los meses de enero y febrero:

  • q es elday del mes ([1, 31])
  • m es el índice 1month+12 ([13, 14])
  • K es el año del siglo para el año anterior ((year1)mod100 )
  • J es el siglo indexado 0 para el año anterior (year1100)

Resultando en el día de la semana h , donde 0 = sábado, 1 = domingo, ..., 6 = viernes.
Fuente: congruencia de Zeller

Podemos ver esto en esta parte del programa 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;es sencillo de nuevo:

     # 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 linees nuevamente más complejo, porque tenemos que hacerlo manualmente. Entonces esto se expandirá al siguiente pseudocódigo:

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;

Fuentes:
Algoritmo para determinar si un año es bisiesto. (EDITAR: ya no es relevante, ya que utilizo un método alternativo para verificar los años bisiestos que ahorraron 7 bytes).
Algoritmo para determinar la cantidad de días en un mes.

6a) Integer isLeapYear = ...;se hace así en el programa 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`

También se utiliza en esta respuesta mía 05AB1E , por lo que se agregan algunos años de ejemplo para ilustrar los pasos.

6b) currentDate.month == 2 ?y 6c) 28 + isLeapYearse hacen así:

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) :y 6e) 31 - (currentDate.month - 1) % 7 % 2;se hacen así:

ë           # 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 hace así:

     # 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 hace así:

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:y 6i) nextDate.day = 1;se hacen así:

ë        # 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;y 6n) nextDate.year += 1;se hacen así:

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

Y finalmente a las 8) If(currentDate == parsed input-string):y 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
fuente
55
Eres un loco ... tienes un voto a favor.
AdmBorkBork
1
¿El programa 05AB1E más largo de la historia?
Luis Mendo
2
@LuisMendo Cerrar, pero me temo que tengo una respuesta 05AB1E que es aún más larga , y una que se acerca demasiado ... ;) Estoy seguro de que podré jugar unos pocos bytes aquí y allá y simplificar partes de la implementación del pseudocódigo del día siguiente. Se verá mañana por la mañana, pero acaba de regresar del deporte y se irá a la cama pronto.
Kevin Cruijssen
11

Excel 24 Bytes

Asume la entrada en la celda A1

=NETWORKDAYS(NOW()+1,A1)

Utiliza la función incorporada. Lamentablemente, la función incluye hoy y la fecha de finalización. Desde entonces, OP ha aclarado no contar hoy, así que agrego uno a NOW para no contar hoy.

Para abordar los comentarios sobre el formato de número, nuevamente, este es el estándar de Excel: ingrese la descripción de la imagen aquí

Keeta - reinstala a Mónica
fuente
Si bien esto funciona con valores de fecha, no puede tomar la entrada como se indica. Es decir (al menos en la versión estadounidense) 10.12.2018es una cadena cuando se mantiene en una celda en lugar de una fecha. La solución obvia, pero mucho tiempo para corregir esto sería cambiar A1a DATE(RIGHT(A1,4),MID(A1,4,2),LEFT(A1,2))en su solución
Taylor de Scott
desafortunadamente, la comunidad ha decidido que los idiomas deben ejecutarse en su configuración predeterminada para ser válidos (la única excepción que he visto es el idioma: IE, si su idioma admite inglés y español, puede usar cualquiera de los dos, pero esto debe tenerse en cuenta.) Además, OP (@hille) no ha declarado que el formato sea flexible, y de hecho ha declarado todo lo contrario (ver el segundo comentario sobre esta pregunta)
Taylor Scott,
2
El formato no es estándar, está basado en la configuración regional. Excel lee el formato de la HKCU\Control Panel\International\sDecimalcadena de registro. En una instalación predeterminada de Windows de EE. UU. Que es MM / dd / aaaa. En la mayoría de los países de la UE, este sería el valor predeterminado.
Erik A
@luisMendo Sí, eso funciona. No vi ninguna aclaración. Si hubiera sido no contar el último día, podría haber = NETWORKDAYS (NOW (), A1-1). Sabía que siempre sería el mismo número de bytes, sin importar qué aclaración.
Keeta - reinstalar a Mónica el
Me alegra que funcione. Quité el voto negativo
Luis Mendo
8

Java 10, 233 232 226 bytes

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 fecha siempre me recuerda cuán detallado es realmente Java ...

NOTA: Ahora hay dos respuestas Java más cortas (por debajo de 175 bytes), una con uso inteligente de métodos obsoletos de versiones anteriores de Java por @LukeStevens , y otra que usa la java.time.LocalDatenovedad desde Java 8 por @ OlivierGrégoire .

Pruébalo en línea.

Explicación:

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
fuente
Podrías hacer e=s.clone()?
Quintec
1
También podemos (supongo) hacer Calendar s=Calendar.getInstance(),e=s.getInstance(), que desafortunadamente termina siendo exactamente de la misma longitud.
Misha Lavrov
1
@MishaLavrov Ah, la estática de Checho no es necesaria. Era de una parte antigua del código donde también utilicé Cen otro lugar. Pude jugar al golf 1 byte usando var s=Calendar.getInstance();var e=s.getInstance();así que gracias. :)
Kevin Cruijssen
1
150 bytes , utilizando java.time.
Olivier Grégoire
1
¡Hecho! Está muy cerca en bytes de la otra respuesta, pero aún no la supera.
Olivier Grégoire
7

JavaScript (ES6), 116 103 bytes

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

Pruébalo en línea!

¿Cómo?

norte .

nortere.toJSON() método:

AAAA - MM - DD T hh : mm : ss.sss Z

YYYY-MM-DDreYYYY-MM-DDDD.MM.YYYY

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

D.getDay()0 06 60 06 6

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

86,400,000norte

Arnauld
fuente
6

MATL , 24 bytes

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

Pruébalo en línea!

No quiero tener ningún formato de entrada para que los lenguajes de golf de código específico tengan una gran ventaja

Tuviste éxito a medias :-)

Explicación

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
fuente
Si entendí el desafío correctamente, solo toma una entrada de fecha y la compara con la fecha de hoy. Por ejemplo, 16.10.2018hoy (lunes 01-10-2018) resultaría en 11, mañana en 10, etc.
Kevin Cruijssen
@KevinCruijssen Whoops. ¡Gracias! Corregido ahora
Luis Mendo
1
Y con el mismo número de bytes. :) Bien, +1 de mi parte.
Kevin Cruijssen
6

Wolfram Language (Mathematica) , 64 56 bytes

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

Pruébalo en línea!

DayCount[x,y,"Weekday"]cuenta el número de días laborables entre xy y.

Las entradas xy ypueden ser muchas cosas, incluida una fantasía DateObjectcomo la que devuelve Todayo una cadena en el formato (desafortunadamente)mm.dd.yyyy .

Mi intento anterior trató de convertir la dd.mm.yyyyentrada en unDateObject diciéndole a Mathematica cómo analizarla; la nueva solución simplemente reorganiza la cadena para poner el día y el mes en el orden que Mathematica espera.

Vale la pena señalar que la solución de 28 bytes DayCount[Today,#,"Weekday"]&no solo funciona perfectamente para un formato de entrada mes-día-año, sino que también maneja correctamente entradas no ambiguas de día-mes-año como31.12.2018 , que no podría significar "el día 12 del día 31 mes". Entonces es correcto más del 60% del tiempo :)

Misha Lavrov
fuente
5

R, 72 caracteres

Una variación en la respuesta proporcionada por @ngm que evita que el grepl guarde algunos caracteres y funciona en idiomas que no están en inglés.

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

Neal Fultz
fuente
1
Más corto y más general también. Buena respuesta y bienvenido al asilo.
ngm
1
Bienvenido a PPCG! puedes agregar un enlace TIO - es fácil y formatea la respuesta para ti :)
JayCe
5

Java (OpenJDK 8) , 174 166 165 bytes

Con un poco de inspiración de la respuesta de Kevin y un buen rastreo a través de la obsoleta API de fecha, he logrado obtener una solución Java más sucinta.

-8 bytes gracias al análisis de fechas inventivo de expresiones regulares de Kevin

-1 bytes gracias a la inteligente operación bit a 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;}

Pruébalo en línea!

Explicación

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
fuente
1
¡Buena respuesta! Uso inteligente de los varargs con d=d[0].splity el .parseformato obsoleto con formato predeterminado MM/dd/yyyy. Un pequeño error en tu publicación, lo tienes en import java.text.*;lugar de import java.util.*;en tu código y // Required import for both Calendar and Dateen tu explicación (aunque no lo uses Calendar).
Kevin Cruijssen
@KevinCruijssen ¡No tengo idea de por qué lo hice java.textpero lo arreglé ahora! ¡Gracias!
Luke Stevens
1
Aunque me gustó el d=d[0].splitcon los varargs, cambiar la entrada a una cadena normal, eliminar d=d[0].split("\\.");y cambiar d[1]+"/"+d[0]+"/"+d[2]para d.replaceAll("(..).(..).","$2/$1/") guardar 7 bytes .
Kevin Cruijssen
1
Y 1 byte más cambiando r+=new Date(s).getDay()%6<1?0:1,s+=864e5);a s+=864e5)r+=new Date(s).getDay()%6<1?0:1;. :)
Kevin Cruijssen
1
-1 byte:r-=-new Date(s).getDay()%6>>-1;
Nevay
4

Rojo , 72 bytes

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

Pruébalo en línea!

Toma la fecha en formato dd-mm-aaaa, por ejemplo 31-10-2018 (también funciona con 10-oct-2018)

Entrada estricta:

Rojo , 97 bytes

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]

Pruébalo en línea!

Prima:

Devuelve una lista de las fechas / días laborables de los días hábiles hasta la fecha indicada:

Rojo , 235 bytes

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

Pruébalo en línea!

Galen Ivanov
fuente
Agh, no es justo, en Python necesito gastar unos 72 bytes procesando este formato IO ...: P
Quintec
1
Por lo general, mis soluciones de Red se encuentran entre las más largas, pero afortunadamente Red maneja muy bien las fechas :)
Galen Ivanov el
1
90 bytes para procesar python ... ya terminé, lo dejé hasta que haya un formato de entrada más flexible: P
Quintec
3

Python 2 , 163 156 149 147 bytes

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

Pruébalo en línea!

-7 con gracias a @mypetlion

-7 más gracias a @ovs

+30 debido al formato de entrada muy restrictivo que solo noté justo antes de publicar mi código anterior que tomó la entrada como, por ejemplo (2018,11,1):-(

ElPedro
fuente
2
No hay necesidad de esto: (0,1)[t.weekday()<5]. Los booleanos de Python son una subclase de inty True, Falsese pueden usar en operaciones aritméticas como 1,0. Reemplácelo con c+=t.weekday()<5para guardar 7 bytes.
mypetlion
1
149 bytes como una lambda.
ovs
Gracias @mypetlion. No debería haberme perdido esa.
ElPedro
Gracias @ovs. Segunda vez que has ayudado recientemente. La última vez fue un muy impresionante -30. Estaba tratando de averiguar cómo llevar esto a una lambda.
ElPedro
3

Java (JDK 10) , 171 bytes

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

Pruébalo en línea!

Créditos

Olivier Grégoire
fuente
1
Puedes cambiar el (.*)\\.(.*)\\.(.*)a (..).(..).(.*).
Kevin Cruijssen
Sin replaceAllembargo, con su técnica, su respuesta también puede jugarse en 7 bytes, por lo que la suya es aún un poco más larga. ;)
Kevin Cruijssen
@KevinCruijssen ¡Gracias por la expresión regular! Y no se preocupe: no me importa tener una respuesta más larga;)
Olivier Grégoire
3

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

35 bytes menos gracias a Quintec y 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;}

Pruébalo en línea!

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
fuente
1
158 bytes con lambda
Quintec
1
139 bytes con condición if mejorada
Quintec
1
Dado que su método no es recursivo, no necesita agregarlo f=al conteo de bytes (y en TIO puede ponerlo en el encabezado), por lo que @Quintec declaró que es 139 bytes en lugar de 141 bytes. Además, puede cambiar if((d.getDay()+1)%7>1)n++;a n+=-~d.getDay()%7>1;al golf a 133 bytes .
Kevin Cruijssen
1
Aquí el consejo relevante por qué -~ies el mismo que(i+1) Además, si aún no lo ha visto, puede ser interesante leer los Consejos para jugar golf en JavaScript y los Consejos para jugar golf en <todos los idiomas> . :)
Kevin Cruijssen
1
Algunos consejos más para referencia futura.
Shaggy
3

Python3 y Numpy , 96 bytes

No podría ser más pequeño que la aburrida solución prefabricada ...

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

Pruébalo en línea!

Aaron
fuente
Debe entrar en Python 3;)
ElPedro
Según su importación, no está utilizando Python 3 , sino Python 3 con numpy .
Jonathan Frech
@ JonathanFrech, ¿debería estar en el título? otros que usan python también han usado una biblioteca ya que python no tiene ningún tipo de datos incorporado para fechas u horas.
Aaron
1
Esto depende de su definición de módulos integrados : los módulos como datetime son módulos de biblioteca estándar y, por lo tanto, los consideraría parte del lenguaje principal. Sin embargo, cuando uno usa módulos de terceros como numpy , uno mejora las capacidades del idioma y, por lo tanto, lo vería como otro idioma.
Jonathan Frech
2

PowerShell , 107 99 bytes

-8 bytes gracias a 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

Pruébalo en línea!

Realiza una expresión regular -spliten la entrada $args, almacena los valores en $days, $months y $yorejas, respectivamente. Luego, ingresa un forciclo, inicializando $aa la fecha de hoy. El bucle continúa mientras $aes -less than de nuestra fecha límite de entrada. Cada iteración estamos añadiendo 1da ysa $a, y comprobar si la corriente D*k(corto para DayOfWeek) está en el rango 1..5(es decir, de lunes a viernes). Ese resultado booleano se acumula $oy, una vez que estamos fuera del ciclo, ese valor se deja en la tubería y la salida es implícita.

AdmBorkBork
fuente
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 De hecho. Además, el punto for(...){...}y coma entre y $ose puede eliminar, ¡así que ahora estamos por debajo de 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))

Pruébalo en línea!

Toma una cadena, e, que representa la fecha de finalización en el formato "dd.MM.YYYY". Opcionalmente, también toma la fecha de inicio, pero se espera que sea datetime.date.

La fecha de inicio, s, está predeterminada a la fecha de hoy como un objeto datetime.date para ignorar la hora. La hora de finalización se analiza en un objeto datetime.datetime y luego se convierte en una fecha, ya que los objetos datetime.date no tienen un método de análisis y datetime no se puede agregar / restar de fechas. Se repite todos los días en (inicio, finalización) y agrega 1 al total si su número de día de la semana es <5. ([0-4] son ​​[Lun-Vie], [5-6] son ​​[Sáb-Dom]).

El análisis de fecha y hora es lo peor, chicos.

EDITAR: Robó el truco del mapa de ElPedro (int, thing) para guardar 4 bytes.

EDIT 2: BOOGALOO ELÉCTRICO: guardado 2 bytes al convertirlo en una función anónima. (¡Gracias Aaron!)

EDITAR 3: xrange -> rango. (¡Gracias de nuevo Aaron!)

Triggernometry
fuente
1
¡De nada! Buena respuesta :)
ElPedro
1
Es una convención que puede f=omitir las expresiones lambda aquí
Aaron
1
"El análisis de fecha y hora es lo peor, muchachos" Jajajaja siento mi dolor, aunque tuviste éxito donde fallé: P
Quintec
@ Aaron No estoy seguro si eso está bien con múltiples funciones o con declaraciones de importación, ¡gracias!
Triggernometry
1
También puede usar en rangelugar de xrangelo que debería funcionar bien.
Aaron
2

PHP, 66 bytes

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

salida vacía para 0; insertar +entre echoy $rpara arreglar.

Ejecutar como tubería con -nro probarlo en línea .


60 bytes con salida unaria:

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

PHP (con carbono ), 107 bytes

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

Fórmula IBM / Lotus Notes - 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

Toma información de un campo de fecha / hora i. El formato de entrada de ise establece en .separado, por lo que no es necesario convertir la entrada. Las notas pueden tomar una entrada de fecha con cualquier separador siempre que lo diga antes de lo que va a ser (¡espero que no sea trampa!). La fórmula está en el campo numérico calculado oen el mismo formulario.

Interesante aparte: desde entonces @Fory @Whilefueron introducidos en el lenguaje Formula en (creo) R6 por el gran Damien Katz los el único uso que he encontrado para ellos es el golf de código. Nunca los he usado en una aplicación de producción.

No hay TIO disponible para la fórmula, así que aquí hay una captura de pantalla tomada el 10/02/2018:

ingrese la descripción de la imagen aquí

ElPedro
fuente
1

K4 , 40 bytes

Solución:

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

Explicación:

Calcule la diferencia entre las fechas, use el módulo 7 para ignorar los fines de semana, resuma.

{+/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

Notas:

  • misma alternativa de byte al análisis de fecha: "D"$,/|"."\:x
callejero
fuente
1

C (sonido metálico) , 209 208 205 bytes

Banderas del compilador -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;}

Pruébalo en línea!

-1 byte gracias a @JonathanFrech

Logern
fuente
?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}

en q, cada fecha tiene un valor entero subyacente, basado en cuántos días han pasado desde el comienzo del milenio. Aplicando 'mod 7' a esto, obtienes valores únicos para cada día de la semana (0 para el sábado, 6 para el viernes). Entonces, cuando 2> x mod 7, no incremente el contador, para evitar contar los fines de semana.

EDITAR: formato de fecha estricto perdido, edición

EDIT2: Incluido

Thaufeki
fuente
1
Lo mejor que he encontrado es {sum 1<mod[d+til("D"$x 10 vs 67893401)-d:.z.d]7}para 48 bytes sin recurrir a los verbos K.
Callejero
Usar los índices de la lista es mucho más elegante que el reverso, y en lugar de usar un bucle, aplica el mod a la lista. Gran respuesta +1
Thaufeki