Obtenga la fecha del enésimo día de la semana en un año y mes determinados


17

Introducción

A menudo, las personas se refieren a las fechas como el "segundo viernes de agosto de 2018" o el "cuarto domingo de marzo de 2012". ¡Pero es difícil saber qué fecha es esa! Su tarea es escribir un programa que reciba un año, un mes, un día de la semana y un número entero, y generar esa fecha.

Desafío

  • Para obtener información, obtendrá un año, un mes, un día de la semana y un número.

  • Puede tomar la entrada en cualquier formato razonable, como usar una cadena para el día de la semana o usar un día de la semana indexado a cero, o incluso tomar el año y el mes en una sola cadena. Sin embargo, explique su formato de entrada en su respuesta.

  • El número entero que le indica a qué día de la semana en el mes apuntar será un número entero del 1 al 5. El número entero nunca se referirá a un día de la semana que no existe (por ejemplo, el quinto viernes de febrero de 2019, que no existe).

  • Los años siempre serán positivos.

  • Su salida puede estar en cualquier formato razonable, incluida la impresión de su fecha final. Sin embargo, explique su formato de salida en su respuesta.

  • Proporcionar el año y el mes en la salida es opcional. Además, puede suponer que la fecha es válida.

Ejemplo de entrada y salida

Considere esta entrada, con el formato tomando el año como un número de 4 dígitos, el mes como un entero, el día de la semana como una cadena y el número ordinal como un entero:

2019, 3, sábado, 2
2019, 12, domingo, 1
2019, 9 sábado, 1

Salida:

9 de marzo 1 de
diciembre
7 de septiembre

Este es el , por lo que gana la respuesta más corta


1
Pensé que podría usar GNU date, pero de manera divertida, el analizador tiene una ... interpretación interesante aquí.
Pomo de la puerta

¿Se puede indexar el número de la semana de mayo?
Jo King el

Claro, si se ajusta a su programa
Encarnación de la ignorancia

Caso de prueba sugerido: 2018, 12, domingo 1
Adám

Caso de prueba sugerido: el primer sábado de septiembre de 2019
Shaggy

Respuestas:


4

Plantilla MediaWiki, 19 bytes

{{#time:r|{{{1}}}}}

Este es un puerto MediaWiki Template ParserFunctions de esta respuesta PHP

Nota: #timeuse PHP strtotimeinternamente.


Entrada de muestra

{{#time: r | segundo sábado de marzo de 2019}}

Salida de muestra

Sáb, 09 mar 2019 00:00:00 +0000


3

Japt, 19 15 bytes

La entrada es: año, índice basado en 0 del mes, índice basado en 0 del día de la semana ( 0es domingo) y n.

_XµW¶Ze}f@ÐUVYÄ

Intentalo

                    :Implicit input of U=year, V=month, W=weekday & X=n
       }f           :Output the first element generated by the right function that returns
                    : falsey (0) when passed through the left function
         @          :Right function. Y=0-based index of current iteration
          ÐUVYÄ     :  new Date(U,V,Y+1)
_                   :Left function. Z=date being passed
 Xµ                 :  Decrement X by
   W¶               :   Test W for equality with
     Ze             :    Z.getDay()

2

C # (compilador interactivo de Visual C #) , 59 bytes

(y,m,d,w)=>1+(d-(int)new DateTime(y,m,1).DayOfWeek+7)%7+7*w

Pruébalo en línea!

-27 bytes gracias a @EmbodimentOfIgnorance!

Menos código de golf ...

// y: year
// m: month
// d: day of week (0 is Sunday)
// w: week number (0 based)
(y,m,d,w)=>
  // start on the first day of the month
  1+
  // determine the number of days to
  // the first occurrence of the
  // requested weekday
  (d-(int)new DateTime(y,m,1).DayOfWeek+7)%7+
  // add the number of requested weeks
  7*w

El valor de retorno es un entero para el día del mes de la fecha solicitada.


Si sólo se devolverá el día del mes, que se permite, se puede jugar golf esta a 59 bytes
Realización de la Ignorancia

Gracias por el consejo nuevamente - (eso es 2x hoy;) Actualizaré mis respuestas.
dana

2

SmileBASIC, 58 51 48 46 45 bytes

READ N,M$DTREAD M$OUT,,D,W?(5-W+D*2)MOD 7+N*7

La entrada tiene la forma: week,year/month/weekday

  • week: número de semana, indexado 0
  • year: año, 4 dígitos
  • month: mes (1 indexado), 2 dígitos 0acolchados
  • weekday: día de la semana (1 indexado, 1 = domingo), 2 dígitos 0rellenados

La salida es el día del mes, 0 indexado.
El segundo sábado de marzo de 2019 sería 1,2019/03/078(9 de marzo)

Sin golf

READ WEEK,M$
DTREAD M$ OUT ,,D,W
'Functions in SB can output multiple values using OUT.
'In this case, we don't need the first 2 values, so no variables are given.

PRINT (5-W+ D*2) MOD 7 +WEEK*7

Explicación

El formulario de entrada se eligió específicamente para que el año / mes / día de la semana se pueda pasar directamente a DTREAD, que es una función que analiza una YYYY/MM/DDcadena y devuelve el año / mes / día como números, así como el cálculo del día de la semana.

Sin embargo, DTREADtenga en cuenta que, donde se espera el día del mes, le daremos el día de la semana. Esto complica las cosas, pero también significa que hay menos valores de entrada y no necesitamos agregarlos /01al final de la cadena de fecha.

DTREADsalidas Wy D.
Wes el día de la semana y Des el día de la semana del Wdía del mes.
(Por lo tanto, si ingresa 7como el día de la semana, Dserá 7y Wserá el día de la semana el séptimo día del mes)

La expresión (5-W+D*2)MOD 7se utiliza para obtener la primera aparición del día de la semana de entrada, como un día del mes indexado en 0. (Me di cuenta de esto principalmente a través de prueba y error)

Después de eso, el programa simplemente agrega WEEK*7.


Realmente desearía que hubiera palabras separadas para "día de la semana" y "día del mes".


2

Perl 6 , 52 48 bytes

{1+($^c+4-Date.new($^a,$^b,1).daycount)%7+$^d*7}

Pruébalo en línea!

Bloque de código anónimo que toma datos como año, mes, día de la semana (domingo es 0) y número de semana (0 indexado). La salida es un objeto de fecha.

Vieja explicación:

{                                                  } # Anonymous code block
 (   Date.new(         ))   # Create a new date with
              $^a,$^b,1     # With year, month and the first day
  $_=                       # Save in the variable $_
                         +  # Add to this
                           $^c+4                     # The given day plus 4
                          (     -.daycount)          # The number of days since 17 Nov, 1858
                                           %7        # Modulo 7 to get the correct day
                                             +$^d*7  # Plus the 7 times the number of weeks

Creo que el número de la semana debe ser indexado 1
12Me21

@ 12Me21 La pregunta dice que la entrada es flexible, pero he preguntado si tomamos un número de semana como 0 indexado
Jo King

Esto no parece funcionar para otros meses. Creo que se necesita $^c+4-$!.daycount.
nwellnhof el

@nwellnhof Ah, debería haber pensado en eso en lugar de prueba y error, jajaja. Debería arreglarse ahora
Jo King

1

MATL , 28 27 bytes

'1 'ihYO31:q+t8XOi=!A)i)1XO

Esto usa tres entradas:

  • Cadena con mes y año: 'March 2019'
  • Cadena con tres letras, primero en mayúscula, que indica el día de la semana: ' Sat'
  • Número: 2.

La salida es una cadena con el día, mes y año separado con guiones: 09-Mar-2019.

Pruébalo en línea!

Explicación

Considere insumos 'March 2019', 'Sat', 2.

'1 '    % Push this string
        % STACK: '1 '
ih      % Input string: month and year. Concatenate
        % STACK: '1 March 2019'
YO      % Convert to serial date number
        % STACK: 737485
31:q+   % Create vector [0 1 2 ... 30] and add element-wise
        % STACK: [737485 737486 737487 ... 737515]
t8XO    % Duplicate. Convert to date format 'ddd': day of week in three letters. Gives
        % a 2D char array
        % STACK: [737485 737486 737487 ... 737515], ['Fri'; 'Sat'; 'Sun'; ...; 'Sun']
i=      % Input string: day of week in three letters. Compare element-wise with broadcast
        % STACK: [737485 737486 737487 ... 737515],
        % [0 0 0; 0 0 0; ...; 1 1 1; 0 0 0; ... 1 1 1; ...]
!A      % True for rows containing only 1
        % STACK: [737485 737486 737487 ... 737515], [0 0 ... 1 ... 0 ... 1 ...]
)       % Index: uses the second vector as a mask into the first
        % STACK: [737486 737493 737500 737507 737514]
i)      % Input number. Index
        % STACK: 737493
1XO     % Convert to date format 'dd-mmm-yyyy'. Implicit display
        % STACK: '09-Mar-2019'

1

Python 3 , 92 82 bytes

82 bytes gracias a @Jo King

lambda y,m,d,w:z(y,m)[w-(z(y,m)[0][d]>0)][d]
from calendar import*
z=monthcalendar

Pruébalo en línea!

Versión original, 92 bytes.

from calendar import*
def f(y,m,d,w):
 x=monthcalendar(y,m)
 if x[0][d]:w-=1
 return x[w][d]

Pruébalo en línea!

Toma el año como un entero, el mes como un entero indexado en 1, el día de la semana como un entero de índice 0 donde es lunes 0y domingo 6, y la semana del mes como un entero indexado en 1.

Cómo funciona:

# import monthcalendar
from calendar import*
# function with 4 inputs
def f(y,m,d,w):
 # get a 2-D array representing the specified month
 # each week is represented by an array
 # and the value of each element is its date of the month
 # Monday is the 0th element of each week, Sunday is the 6th element
 # days of the first week of the month before the 1st are 0s 
 x=monthcalendar(y,m)
 # if the first week of the month includes the desired day of week
 # convert the week of month to 0-index so that it takes into account the first week
 if x[0][d]:w-=1
 # return the weekday of the week number specified
 return x[w][d]

1

R , 72 69 bytes

function(y,m,d,n,D=as.Date(paste0(y,-m,-1))+0:31)D[weekdays(D)==d][n]

Pruébalo en línea!

Tomando entrada como:

  • Número de año
  • Número de mes (1-12)
  • Cadena de lunes a viernes en la configuración regional actual (TIO requiere un nombre en inglés con mayúscula)
  • Número ordinal (1 indexado)




0

Rojo , 64 60 bytes

func[y m d n][a: to-date[1 m y]d - a/10 - 7 % 7 +(n * 7)+ a]

Pruébalo en línea!

Toma el año, el mes y el día de la semana como números, indexados en 1, el lunes es el primer día de la semana.


eh, to-datees una cosa. tal vez esto sería útil en el desafío del formato de víspera de Navidad
solo ASCII el

@ Solo ASCII Solíamos usar nowpara ese desafío
Galen Ivanov el

1
sí, pero estaba pensando en métodos alternativos (es decir, el " Eve"método <repite fecha2-fecha1 veces> iirc)
solo ASCII

@ Solo ASCII>> 25-Dec-2019 - 1-1-2019 == 358
Galen Ivanov

0

APL (Dyalog Unicode) , SBCS de 36 bytes

Programa completo Solicita [year,month](enero es 1), luego para el día (domingo es 0), luego para n (primero es 1).

date⎕⊃d/⍨⎕=7|d←(⍳31)+days⎕⊣⎕CY'dfns'

Pruébalo en línea!

⎕CY'dfns'c o p y en la biblioteca dfns

 descartar el resultado de eso a favor de ...

 consola de solicitud de [year,month]números

days[c]  días [n] desde 31.12.1899 del 0 º de ese mes

(⍳31)+ añadir los i ntegers 1 ... 31 de este

d← tienda en d(por d números Ay)

7| resto de división cuando se divide por 7 (día de la semana con domingo siendo 0 debido a una buena época)

⎕= solicite la consola para el número del día de la semana y obtenga la máscara donde sea igual a los números del día de la semana

d/⍨ filtrar d con esa máscara

⎕⊃ solicite la consola para n y úsela para elegir de la lista de números de día

date[c]  sello de fecha y hora [n] (tiene ceros al final de horas, minutos, segundos, milisegundos)


Haga clic en [c] para el código y [n] para las notas.


0

JavaScript (ES6), 49 48 bytes

f=
(a,d,n)=>(d+6-new Date(...a,7).getDay())%7+n*7-6
<div oninput=o.textContent=f([+y.value,+m.value],+d.value,+n.value)>Year: <input id=y type=number value=2019><br>Month: <select id=m><option value=0>Jan<option value=1>Feb<option value=2>Mar<option value=3>Apr<option value=4>May<option value=5>Jun<option value=6>Jul<option value=7>Aug<option value=8>Sep<option value=9>Oct<option value=10>Nov<option value=11>Dec</select><br>Day: <select id=d><option value=0>Sun<option value=1>Mon<option value=2>Tue<option value=3>Wed<option value=4>Thu<option value=5>Fri<option value=6>Sat</select><br>Count: <input id=n type=number value=1 min=1 max=5><pre id=o>

Toma parámetros como f([year, month], day, number). Mes y día de la semana (comenzando el domingo) están indexados a cero. Editar: guardado 1 byte gracias a @Shaggy.


¿El día de la semana tiene el formato domingo-sábado o lunes-domingo?
Encarnación de la ignorancia el

@EmbodimentofIgnorance Lo siento, sabía que había olvidado algo. (El fragmento ahora usos seleccionar para que sea más fácil.)
Neil

@EmbodimentofIgnorance, el domingo es 0en JS.
Shaggy

Oh. No lo sabía, no estoy tan familiarizado con Javascript.
Encarnación de la ignorancia el


0

TSQL, 106 bytes

DECLARE @ datetime='2019',@m int=3,@w char(2)='saturday',@p int=2

SELECT dateadd(wk,datediff(d,x,dateadd(m,@m-1,@)-1)/7,x)+@p*7FROM(SELECT
charindex(@w,' tuwethfrsasu')/2x)x

Salida:

2019-03-09 00:00:00.000

Pruébalo


0

Kotlin , 131 84 bytes

47 bytes gracias al código y comentario de ASCII-only.

Entrada: año, mes Número, día de la semana Número, semana Número

Todos los enteros 1 al máximo en una sola línea. El número del día de la semana es el domingo del 1 al sábado del 7. El programa principal hace que el año pierda 1900 para la clase Fecha y el mes y el día de la semana se cambien para comenzar con cero en lugar de uno antes de llamar a la lambda. Puede ingresar sus argumentos en el cuadro de texto de entrada para probar sus propias fechas.

Salida: una instancia de clase de fecha. El programa principal muestra el resultado como: sáb mar 09 00:00:00 UTC 2019.

Hay una versión ampliada con comentarios que explican el código para aquellos que deseen obtener más información.

{y,m,d,w->val r=java.util.Date(y,m,7*w)
r.setDate(r.getDate()-(r.getDay()+7-d)%7)
r}

Pruébalo en línea!


1
74 - utiliza el mismo método que las respuestas de Scala y Groovy
solo ASCII el


1
Ya no es necesario el comando de importación, así que eso no es un problema: P
solo ASCII el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.