Obter a data do enésimo dia da semana em um determinado ano e mês

17

Introdução

Frequentemente, as pessoas se referem a datas como a "segunda sexta-feira em agosto de 2018" ou o "quarto domingo de março de 2012". Mas é difícil dizer que data é essa! Sua tarefa é escrever um programa que receba um ano, um mês, um dia da semana e um número inteiro e gerar essa data.

Desafio

  • Para entrada, você receberá um ano, um mês, um dia da semana e um número.

  • Você pode receber entradas em qualquer formato razoável, como usar uma sequência de caracteres para o dia da semana ou usar um dia da semana indexado a zero, ou ainda fazer o ano e o mês em uma única sequência. Porém, explique seu formato de entrada na sua resposta.

  • O número inteiro que informa qual dia da semana no mês a ser segmentado será um número inteiro de 1 a 5. O número inteiro nunca se refere a um dia da semana que não existe (por exemplo, a quinta sexta-feira de fevereiro de 2019, que não existe).

  • Os anos serão sempre positivos.

  • Sua saída pode estar em qualquer formato razoável, incluindo a impressão da data final. No entanto, explique seu formato de saída em sua resposta.

  • Fornecer o ano e o mês na saída é opcional. Além disso, você pode assumir que a data é válida.

Exemplo de entrada e saída

Considere esta entrada, com o formato sendo utilizado no ano como um número de 4 dígitos, o mês como um número inteiro, o dia da semana como uma sequência e o número ordinal como um número inteiro:

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

Resultado:

9 de março -
1 de
setembro - 7 de setembro

Este é o , por isso a resposta mais curta vence.

Modalidade de ignorância
fonte
1
Eu pensei que poderia usar o GNU date, mas divertidamente, o analisador tem uma ... interpretação interessante aqui.
Maçaneta da porta
O número da semana pode ser indexado em 0?
Jo King
Claro, se for adequado ao seu programa
Modalidade de Ignorância
Caso de teste sugerido: 12 de
dezembro de
Caso de teste sugerido: o primeiro sábado de setembro de 2019
Shaggy

Respostas:

4

Modelo do MediaWiki, 19 bytes

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

Esta é uma porta MediaWiki Template ParserFunctions da desta resposta PHP

Nota: #timeuse PHP strtotimeinternamente.


Entrada de amostra

{{#time: r | segundo sábado de março de 2019}}

Saída de amostra

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

tsh
fonte
3

Japonês, 19 15 bytes

A entrada é: ano, índice baseado em 0 do mês, índice baseado em 0 do dia da semana ( 0é domingo) e n.

_XµW¶Ze}f@ÐUVYÄ

Tente

                    :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()
Shaggy
fonte
2

C # (compilador interativo do Visual C #) , 59 bytes

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

Experimente online!

-27 bytes graças a @EmbodimentOfIgnorance!

Menos código de golfe ...

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

O valor de retorno é um número inteiro para o dia do mês da data solicitada.

dana
fonte
Se você retornar apenas o dia do mês, o que é permitido, você poderá jogar isso em até 59 bytes
Modalidade de Ignorância
Obrigado pela dica novamente - (isso é 2x hoje;) Atualizarei minhas respostas.
dana 2/01
2

SmileBASIC, 58 51 48 46 45 bytes

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

A entrada está no formato: week,year/month/weekday

  • week: número da semana, indexado 0
  • year: ano, 4 dígitos
  • month: mês (indexado 1), 2 dígitos 0 preenchido com
  • weekday: dia da semana (1 indexado, 1 = domingo), 2 dígitos 0 -Acolchoado

A saída é o dia do mês, 0 indexado.
O 2º sábado de março de 2019 seria1,2019/03/078 (9 de março)

Ungolfed

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

Explicação

O formulário de entrada foi escolhido especificamente para que o ano / mês / dia da semana pudesse ser passado diretamente para DTREAD, que é uma função que analisa uma YYYY/MM/DDstring e retorna o ano / mês / dia como números, além de calcular o dia da semana.

No entanto, observe que, onde DTREADespera o dia do mês, estamos oferecendo o dia da semana. Isso complica as coisas, mas também significa que há menos valores de entrada e não precisamos adicionar /01ao final da sequência de datas.

DTREADsaídas We D.
Wé o dia da semana e Dé o dia da semana do Wdia th do mês.
(Portanto, se você inserir 7como dia da semana, Dserá7 eW será o dia da semana em que o 7º dia do mês for)

A expressão (5-W+D*2)MOD 7 é usada para obter a 1ª ocorrência do dia da semana de entrada, como um dia do mês indexado a 0. (Eu descobri isso principalmente por tentativa e erro)

Depois disso, o programa apenas adiciona WEEK*7.


Eu realmente gostaria que houvesse palavras separadas para "dia da semana" e "dia do mês".

12Me21
fonte
2

Perl 6 , 52 48 bytes

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

Experimente online!

Bloco de código anônimo que recebe entrada como ano, mês, dia da semana (domingo é 0) e número da semana (0 indexado). Saída é um objeto de data.

Explicação antiga:

{                                                  } # 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
Brincadeira
fonte
Eu acho que o número da semana precisa ser 1 indexado
12Me21 02/01
@ 12Me21 A pergunta diz que a entrada é flexível, mas eu perguntei se nós aceitamos o número da semana como 0 indexado
Jo King
Isso não parece funcionar por outros meses. Eu acho que você precisa $^c+4-$!.daycount.
nwellnhof 2/01
@nwellnhof Ah, eu deveria ter pensado nisso em vez de tentativa e erro, lol. Deve ser corrigido agora
Jo King
1

MATL , 28 27 bytes

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

Isso usa três entradas:

  • String com mês e ano: 'March 2019'
  • Sequência de caracteres com três letras, primeira em maiúscula, indicando o dia da semana: 'Sat '
  • Número: 2.

A saída é uma string com dia, mês e ano separados com traços: 09-Mar-2019.

Experimente online!

Explicação

Considere entradas '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'
Luis Mendo
fonte
1

Python 3 , 92 82 bytes

82 bytes graças a @Jo King

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

Experimente online!

Versão 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]

Experimente online!

Toma o ano como um número inteiro, o mês como um número inteiro indexado a 1, o dia da semana como um número inteiro com índice 0, onde segunda-feira é 0e domingo é6 , e a semana do mês como um número inteiro indexado em 1.

Como 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]
Neil A.
fonte
1

R , 72 69 bytes

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

Experimente online!

Tomando entrada como:

  • Número do ano
  • Número do mês (1-12)
  • Seqüência de dias da semana no local atual (o TIO requer nome em inglês com letra maiúscula)
  • Número ordinal (1 indexado)
digEmAll
fonte
0

PHP , 46 , 43 , 31 bytes

<?=date(d,strtotime($argv[1]));

Experimente online!

O programa recebe como entrada uma string como "second saturday of March 2019"

O programa imprime o número do dia.

-12 bytes graças a Shaggy.

Кирилл Малышев
fonte
1
31 bytes
Shaggy
Além disso, acho que você não precisa ofda entrada.
Shaggy
@ Shagy, acho que estes são detalhes. Pode haver muitas opções.
Кирилл Малышев
0

Groovy , 46 bytes

{y,m,d,w->r=new Date(y,m,7*w)
r-(r.day+7-d)%7}

Experimente online!

Entrada como anos desde 1900, mês indexado a 0, dia indexado a 0 (domingo sendo 0) e número da semana

Somente ASCII
fonte
0

Scala , 86 bytes

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

Experimente online!

Somente ASCII
fonte
0

Vermelho , 64 60 bytes

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

Experimente online!

Toma o ano, o mês e o dia da semana como números, indexados 1, segunda-feira é o primeiro dia da semana.

Galen Ivanov
fonte
huh, to-dateé uma coisa. talvez isso seja útil no desafio do formato christmase eve
ASCII-only
@ Somente ASCII Usamos nowpara esse desafio
Galen Ivanov
1
Sim, mas eu estava pensando em métodos alternativos (ou seja, o " Eve"método <repetir data2-data1 vezes> iirc)
somente ASCII
@ Somente ASCII>> 25-Dec-2019 - 1-1-2019 == 358
Galen Ivanov
0

APL (Dyalog Unicode) , SBCS de 36 bytes

Programa completo. Solicita [year,month](janeiro é 1), depois dia (domingo é 0) e depois n (primeiro é 1).

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

Experimente online!

⎕CY'dfns'c o p y no NDR biblioteca

 descartar o resultado disso em favor de…

 console de prompt para [year,month]números

days[c]  dias [n] uma vez 1899/12/31 do 0 ° desse mês

(⍳31)+ Adicione o oi ntegers 1 ... 31 a esse

d← armazenar em d (para d números ay)

7| divisão restante ao dividir por 7 (dia da semana com domingo sendo 0 devido a uma boa época)

⎕= console imediato para o número do dia da semana e obtenha uma máscara igual aos números do dia da semana

d/⍨ filtro d com essa máscara

⎕⊃ console de prompt para ne use isso para escolher na lista de números de dias

date[c]  carimbo de data e hora [n] (possui zeros à direita por horas, minutos, segundos, milissegundos)


Clique em [c] para obter o código e em [n] para fazer anotações.

Adão
fonte
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). O mês e o dia da semana (começando no domingo) são indexados a zero. Edit: Salvo 1 byte graças a @Shaggy.

Neil
fonte
O dia da semana está no formato domingo-sábado ou segunda-feira-domingo?
Modalidade de ignorância
@EmbodimentofIgnorance Desculpe, eu sabia que tinha esquecido algo. (O trecho agora usa select para facilitar).
Neil
@EmbodimentofIgnorance, domingo é 0em JS.
Shaggy
Oh. Eu não sabia disso, não estou familiarizado com Javascript.
Modalidade de ignorância
48 bytes
Shaggy
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

Resultado:

2019-03-09 00:00:00.000

Experimente

t-clausen.dk
fonte
0

Kotlin , 131 84 bytes

47 bytes graças ao código e comentário do ASCII-only.

Entrada: year, monthNumber, weekdayNumber, weekNumber

Todos os números inteiros de 1 a máximo em uma única linha. O número do dia da semana é domingo de 1 a sábado de 7. O programa principal faz o ano perder 1900 para a classe Date e o mês e o dia da semana são alterados para começar com zero em vez de um antes de chamar a lambda. Você pode inserir seus argumentos na caixa de texto de entrada para tentar suas próprias datas.

Saída: uma instância da classe Date. O programa principal exibe o resultado como: Sat Mar 09 00:00:00 UTC de 2019.

Existe uma versão expandida com comentários explicando o código para aqueles que desejam aprender mais.

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

Experimente online!

JohnWells
fonte
1
74 - usa o mesmo método das respostas Scala e Groovy
somente ASCII
1
Corrigido, 84
somente ASCII em
1
Não há mais necessidade do comando de importação, portanto não há problema: P
somente ASCII