Uzyskaj datę n-tego dnia tygodnia w danym roku i miesiącu

17

Wprowadzenie

Często ludzie określają daty jako „drugi piątek sierpnia 2018 r.” Lub „czwartą niedzielę marca 2012 r.”. Ale trudno powiedzieć, która to data! Twoim zadaniem jest napisanie programu, który odbiera rok, miesiąc, dzień tygodnia i liczbę całkowitą, i wypisuje tę datę.

Wyzwanie

  • Do wprowadzenia otrzymasz rok, miesiąc, dzień tygodnia i liczbę.

  • Możesz przyjmować dane wejściowe w dowolnym rozsądnym formacie, np. Używając ciągu na dzień tygodnia lub używając tygodnia indeksowanego zerowo, a nawet wziąć rok i miesiąc w jednym ciągu. Jednak wyjaśnij swój format wejściowy w swojej odpowiedzi.

  • Liczba całkowita, która informuje, który dzień tygodnia w miesiącu, na który chcesz kierować, będzie liczbą całkowitą od 1 do 5. Liczba całkowita nigdy nie będzie oznaczać dnia tygodnia, który nie istnieje (np. Piąty piątek lutego 2019 r., Który nie istnieje).

  • Lata zawsze będą pozytywne.

  • Dane wyjściowe mogą mieć dowolny rozsądny format, w tym wydrukować datę końcową. Jednak proszę wyjaśnić swój format wyjściowy i swoją odpowiedź.

  • Podanie roku i miesiąca w danych wyjściowych jest opcjonalne. Możesz również założyć, że data jest ważna.

Przykład wejścia i wyjścia

Rozważ to wejście, przy czym format przyjmuje się w roku jako 4-cyfrową liczbę, miesiąc jako liczbę całkowitą, dzień tygodnia jako ciąg, a liczbę porządkową jako liczbę całkowitą:

2019, 3, sobota, 2
2019, 12, niedziela, 1
2019, 9 sobota, 1

Wynik:

9 marca 1
grudnia
7 września

To jest , więc wygrywa najkrótsza odpowiedź.

Wcielenie ignorancji
źródło
1
Myślałem, że mogę używać GNU date, ale zabawnie parser ma tutaj ... interesującą interpretację .
Klamka
Czy numer tygodnia może być indeksowany jako 0?
Jo King
Jasne, jeśli pasuje do twojego programu
Embodiment of Ignorance
Sugerowany przypadek testowy: 2018, 12, niedziela 1
Adám
Sugerowany przypadek testowy: pierwsza sobota września 2019 r.
Kudłaty

Odpowiedzi:

4

Szablon MediaWiki, 19 bajtów

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

To jest port ParserFunctions szablonu MediaWiki tej odpowiedzi PHP

Uwaga: #timeużywaj PHP strtotimewewnętrznie.


Przykładowe dane wejściowe

{{#time: r | druga sobota marca 2019 r.}}

Przykładowe dane wyjściowe

Sob., 09 marca 2019 00:00:00 +0000

tsh
źródło
3

Japt, 19 15 bajtów

Dane wejściowe to: rok, 0-miesięczny indeks miesiąca, 0-dniowy indeks tygodnia ( 0to niedziela) i n.

_XµW¶Ze}f@ÐUVYÄ

Spróbuj

                    :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()
Kudłaty
źródło
2

C # (interaktywny kompilator Visual C #) , 59 bajtów

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

Wypróbuj online!

-27 bajtów dzięki @EmbodimentOfIgnorance!

Kod mniej golfowy ...

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

Wartość zwracana jest liczbą całkowitą dla dnia miesiąca, w którym żądana jest data.

dana
źródło
Jeśli zwrócisz tylko dzień miesiąca, co jest dozwolone, możesz zagrać w golfa do 59 bajtów
Embodiment of Ignorance
Jeszcze raz dziękuję za wskazówkę - (dzisiaj to 2x;) Zaktualizuję moje odpowiedzi.
dana
2

SmileBASIC, 58 51 48 46 45 bajtów

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

Dane wejściowe mają postać: week,year/month/weekday

  • week: numer tygodnia, 0-indeksowany
  • year: rok, 4 cyfry
  • month: miesiąc (1 indeksowany), 2 cyfry - 0wypełnione
  • weekday: dzień tygodnia (1 indeksowany, 1 = niedziela), 2 cyfry - 0wypełnione

Wyjście to dzień miesiąca, zindeksowane 0.
Druga sobota marca 2019 r. To 1,2019/03/078(9 marca)

Bez golfa

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

Wyjaśnienie

Formularz wejściowy został specjalnie wybrany, aby rok / miesiąc / dzień tygodnia mógł zostać przekazany bezpośrednio do DTREAD, co jest funkcją analizującąYYYY/MM/DD ciąg znaków i zwraca rok / miesiąc / dzień jako liczby, a także oblicza dzień tygodnia.

Zauważ jednak, że tam, gdzie DTREADoczekuje się dnia miesiąca, podajemy go zamiast tego dnia tygodnia. To komplikuje rzeczy, ale oznacza również, że jest mniej wartości wejściowych i nie musimy dodawać /01na końcu łańcucha daty.

DTREADwyjścia Wi D.
Wjest Ddniem tygodnia i jest dniem tygodnia Wdnia miesiąca.
(Jeśli więc wpiszesz 7jako dzień tygodnia, Dbędzie 7i Wbędzie niezależnie od tego, w który dzień tygodnia jest siódmy dzień miesiąca)

Wyrażenie (5-W+D*2)MOD 7służy do uzyskania pierwszego wystąpienia wejściowego dnia tygodnia, jako dnia miesiąca indeksowanego według 0. (Wymyśliłem to głównie poprzez próbę i błąd)

Następnie program po prostu dodaje WEEK*7.


Naprawdę chciałbym mieć osobne słowa dla „dnia tygodnia” i „dnia miesiąca”.

12Me21
źródło
2

Perl 6 , 52 48 bajtów

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

Wypróbuj online!

Anonimowy blok kodu, który pobiera dane jako rok, miesiąc, dzień tygodnia (niedziela to 0) i numer tygodnia (indeksowane 0). Dane wyjściowe to obiekt daty.

Stare objaśnienie:

{                                                  } # 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
Jo King
źródło
Myślę, że numer tygodnia musi być zindeksowany 1
12Me21
@ 12Me21 Pytanie mówi, że dane wejściowe są elastyczne, ale zapytałem, czy mamy numer tygodnia zindeksowany jako 0
Jo King
To nie wydaje się działać przez inne miesiące. Myślę, że potrzebujesz $^c+4-$!.daycount.
nwellnhof
@nwellnhof Ah, powinienem pomyśleć o tym zamiast prób i błędów, lol. Należy naprawić teraz
Jo King
1

MATL , 28 27 bajtów

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

Wykorzystuje trzy wejścia:

  • Ciąg z miesiącem i rokiem: 'March 2019'
  • Ciąg z trzema literami, najpierw dużymi literami, wskazujący dzień tygodnia: „Sat '
  • Numer: 2 .

Dane wyjściowe to ciąg z dniem, rokiem i miesiącem oddzielone myślnikami: 09-Mar-2019 .

Wypróbuj online!

Wyjaśnienie

Rozważmy wejść '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
źródło
1

Python 3 , 92 82 bajty

82 bajty dzięki @Jo King

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

Wypróbuj online!

Wersja oryginalna, 92 bajty

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

Wypróbuj online!

Przyjmuje rok jako liczbę całkowitą, miesiąc jako liczbę całkowitą z 1 indeksem, dzień tygodnia jako liczbę całkowitą z zerowym indeksem, gdzie jest poniedziałek 0i niedziela 6, a tydzień miesiąca jako liczbę całkowitą z 1 indeksowanym.

Jak to działa:

# 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.
źródło
1

R , 72 69 bajtów

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

Wypróbuj online!

Przyjmowanie danych wejściowych jako:

  • Numer roku
  • Numer miesiąca (1-12)
  • Ciąg dnia tygodnia w bieżącym języku (TIO wymaga angielskiej nazwy z wielką literą)
  • Numer porządkowy (1-indeksowany)
digEmAll
źródło
0

PHP , 46 , 43 , 31 bajtów

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

Wypróbuj online!

Program otrzymuje jako wejście ciąg podobny do "second saturday of March 2019"

Program drukuje numer dnia.

-12 bajtów dzięki Shaggy.

Кирилл Малышев
źródło
1
31 bajtów
Kudłaty
Ponadto nie sądzę, że potrzebujesz ofwejścia.
Kudłaty
@Shaggy, myślę, że to są szczegóły. Może być wiele opcji.
Кирилл Малышев
0

Groovy , 46 bajtów

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

Wypróbuj online!

Wprowadzanie jako lata od 1900 r., Miesiąc indeksowany według 0, dzień indeksowany jako 0 (niedziela oznacza 0) i numer tygodnia

Tylko ASCII
źródło
0

Czerwony , 64 60 bajtów

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

Wypróbuj online!

Przyjmuje rok, miesiąc i dzień tygodnia jako liczby, indeksowane 1, poniedziałek jest pierwszym dniem tygodnia.

Galen Iwanow
źródło
huh, to-dateto coś. być może przydałoby się to w wyzwaniu formatu przedświątecznego
tylko ASCII,
@ Tylko ASCII Użyliśmy nowdo tego wyzwania
Galen Iwanow
1
tak, ale myślałem o metodach alternatywnych (a mianowicie <powtórz " Eve"datę2-data1 razy> metoda iirc)
tylko ASCII
@ Tylko ASCII>> 25-Dec-2019 - 1-1-2019 == 358
Galen Iwanow
0

APL (Dyalog Unicode) , 36 bajtów SBCS

Pełny program Monituje o [year,month](1 stycznia), następnie o dzień (niedziela to 0), a następnie o n (pierwszy to 1).

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

Wypróbuj online!

⎕CY'dfns'c o p y w bibliotece dfns

 odrzuć wynik tego na rzecz…

 szybka konsola dla [year,month]liczb

days[c]  dni [n] od 1899-12-31 z 0 tego miesiąca

(⍳31)+ Dodać I ntegers 1 ... 31 to, że

d← zapisz w d(dla numerów d )

7| pozostała część podziału przy dzieleniu przez 7 (dzień tygodnia z niedzielą 0 z powodu dobrej epoki)

⎕= podpowiedz konsolę o numerze dnia tygodnia i uzyskaj maskę, gdzie są równe liczbom dnia tygodnia

d/⍨ filtruj za dpomocą tej maski

⎕⊃ monit konsoli dla n i użyj go, aby wybrać z listy numerów dni

date[c]  datetime stamp [n] (ma zera końcowe dla godzin, minut, sekund, milisekund)


Kliknij [c] dla kodu i [n] dla notatek.

Adám
źródło
0

JavaScript (ES6), 49 48 bajtów

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>

Przyjmuje parametry jako f([year, month], day, number). Miesiąc i dzień tygodnia (od niedzieli) są zerowane. Edycja: Zapisano 1 bajt dzięki @Shaggy.

Neil
źródło
Czy dzień tygodnia ma format niedziela-sobota czy poniedziałek-niedziela?
Embodiment of Ignorance
@EmbodimentofIgnorance Przepraszamy, wiedziałem, że o czymś zapomniałem. (Snippet używa teraz select, aby ułatwić.)
Neil
@EmbodimentofIgnorance, niedziela jest 0w JS.
Kudłaty
O. Nie wiedziałem o tym, nie znam się na Javascript.
Embodiment of Ignorance
48 bajtów
Shaggy
0

TSQL, 106 bajtów

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

Wynik:

2019-03-09 00:00:00.000

Wypróbuj to

t-clausen.dk
źródło
0

Kotlin , 131 84 bajtów

47 bajtów dzięki kodowi i komentarzowi ASCII-only.

Dane wejściowe: rok, miesiącNumer, dzień tygodniaNumer, tydzieńNumer

Wszystkie liczby całkowite od 1 do maksimum w jednej linii. Numer dnia tygodnia to niedziela od 1 do soboty 7. Główny program powoduje, że rok traci 1900 dla klasy Data, a miesiąc i dzień tygodnia są przesunięte tak, aby zaczynały się od zera zamiast jednego przed wywołaniem lambda. Możesz wpisać argumenty w polu tekstowym, aby wypróbować własne daty.

Dane wyjściowe: instancja klasy Date. Główny program wyświetla wynik w następujący sposób: sob. Mar 09 00:00:00 UTC 2019.

Istnieje rozszerzona wersja z komentarzami wyjaśniającymi kod dla tych, którzy chcą dowiedzieć się więcej.

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

Wypróbuj online!

JohnWells
źródło
1
74 - używa tej samej metody, co odpowiedzi Scali i Groovy
tylko ASCII
1
Naprawiono, 84
tylko
1
Nie ma już potrzeby komendy importowania, więc to nie problem: P
tylko ASCII