Que semana es

8

El día de la semana y el mes del año parecen llamar mucho la atención, pero a nadie parece importarle la semana del año. Creo que es hora de cambiar eso, por lo que su trabajo es escribir un programa o función que, cuando se le da una fecha, genera un número entero entre 1 y 53 correspondiente a la semana actual del año.

Para los propósitos de este desafío, diremos que el primer domingo del año marca el comienzo del año, por lo que el único caso cuando el 1 de enero se considera la semana 1 es cuando cae en domingo.

  • La entrada puede ser cualquier formato de fecha que no incluya explícitamente el número de semana (solo especifique el formato en su respuesta) para las fechas entre 1JAN1900y 31DEC2100.
  • La salida es un número entero entre 1 y 53
  • Puede usar cualquier método estándar para proporcionar entrada / salida.

Casos de prueba

17MAY2017 -> 20

3JAN2013 -> 53

1JAN2017 -> 1

17MAY1901 -> 19

31DEC2100 -> 52

7JUL2015 -> 27
  • Este es el por lo que se aplican todas las reglas estándar de golf, y gana el código más corto (en bytes).
J_Lard
fuente
55
Las semanas ISO serían más estándar; IIRC se basan en el primer jueves de un año.
Neil
¿Podemos usar otros formatos de entrada de fecha (es decir, 07/07/2015)? Puede 7JUL2015ser 07JUL2015?
Stephen
@StephenS Sí, está bien. 7/7/2015, 2015-07-07también son válidos.
J_Lard
2
@Neil: No es exactamente una buena coincidencia con la definición estándar aquí, lo que hace que sea menos probable que el problema se pueda resolver a través de una solución integrada, mientras que no es más difícil de resolver sin él.
44
Nota para las personas que usan %U: Como señala @J_Lard, debe tener cuidado de si la semana 0 es la semana 52 o 53 del año anterior. Es la semana 53 en 2001, 2007, 2013, 2018, 2024, 2029 y se repite en un ciclo de 28 años. Otros años es la semana 52.
Neil

Respuestas:

2

Ohm , 12 33 bytes

EDITAR : se corrigieron los casos límite para "% U".

IΩDÖ?┼╓y≤s"-12-31"C"%F"╓₧Ω
"%U"╓&

Asume que la entrada puede ser una marca de tiempo. Explicación por venir.

Pruébalo en línea!

Nick Clifford
fuente
1
La semana 0 es diferente en años como 1995 y 2023.
Neil
@Neil Eso es cierto, pero el desafío dice que la respuesta debe estar entre 1 y 53, y básicamente estoy haciendo lo mismo que todas las otras respuestas.
Nick Clifford
Lo siento, tengo mis años confundidos. De todos modos, es 52 en algunos años y 53 en otros.
Neil
@Neil Ahí vamos.
Nick Clifford
1
De hecho, esto da respuestas correctas para, por ejemplo, el 1 de enero de 2018 y 2019.
Neil
6

MATL , 50 bytes

Gracias a @Neil y @NickClifford por señalar un error, ahora corregido

ZO1)TThXJYOXIGYO&:8XO!s310=sJ4B-YOIq&:8XO!s310=sX\

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

Utiliza las tres funciones de conversión de fecha / hora que hay en MATL:

  • XO: convierte la fecha y la hora al formato de cadena;
  • YO: convierte la fecha y hora en número de serie;
  • ZO: convierte fecha y hora a vector de componentes.

Determinar si la semana "0" debería convertirse en 52 o 53 fue costoso, porque MATL no puede definir funciones invocables para reutilizar la 8XO!s310=sparte. La reutilización por medio de un bucle con una rama solo guarda un byte y complica la explicación, por lo que probablemente no valga la pena.

Además, se podría obtener algo ingresando la fecha como una matriz [año, mes, día]; pero no usaría las tres funciones de fecha :-)

Considere la entrada '17MAY2017'como un ejemplo.

       % Implicit input
       % STACK: '17MAY2017'
ZO     % Convert to date vector
       % STACK: [2017 5 17]
1)     % Get first entry: year
       % STACK: 2017
TTh    % Append [1 1]
       % STACK: [2017 1 1]
XJ     % Copy to clipboard J
YO     % Convert to date number
       % STACK: 736696
XI     % Copy to clipboard I
GYO    % Push input again. Convert to date number
       % STACK: [736696 736832]
&:     % Binary range
       % STACK: [736696 736697 736698 ... 736832]
8XO    % Convert to date string with format 'ddd': day of week
       % STACK: ['Sun'; 'Mon'; 'Tue'; ... ; 'Wed']
!s     % Sum of each row (chars are interpreted as code points)
       % STACK: [310 298 302 ...  288]
310=   % Compare with 310 (sum of 'Sun')
       % STACK: [1 0 0 ... 0]
s      % Sum of array. If is 0, it needs to be transformed into 52 or 53,
       % depending on the number of Sundays the previous year contains.
       % STACK: 20
J      % Paste from clipboard J
       % STACK: 20, [2017 1 1]
4B-    % Push [1 0 0] and subtract element-wise
       % STACK: 20, [2016 1 1]
YO     % COnvert to date number
       % STACK: 20, 736330
I      % Paste from clipboard I
       % STACK: 20, 736330, 736696
q      % Subtract 1
       % STACK: 20, 736330, 736695
&:     % Binary range
       % STACK: 20, [736330 736331 736332 ... 736695]
8XO    % Convert to date string with format 'ddd': day of week
       % STACK: 20, ['Fri'; 'Sat'; 'Sun'; ... ; 'Sat']
!s     % Sum of each row (chars are interpreted as code points)
       % STACK: 20, [289 296 310 ... 296]
310=   % Compare with 310 (sum of 'Sun')
       % STACK: 20, [0 0 1 ... 0]
s      % Sum of array
       % STACK: 20, 52
X\     % 1-based modulo
       % STACK: 20
       % Implicit display
Luis Mendo
fuente
2
¡Felicidades por 50k! Estoy justo detrás de ti :)
Digital Trauma
1
Quedan 2 puntos ... y ¡boom! Felicidades!
Jonathan Allan
¿Funciona esto con los casos extremos señalados por Neil? Sé que no sirve %U, pero solo quiero asegurarme.
Nick Clifford
Esto parece pensar que el 1 de enero de 2019 está en la semana 53, pero solo en la semana 52.
Neil
@Neil Sí, tienes razón. Curiosamente, los otros casos de prueba son correctos.
J_Lard
4

JavaScript (ES6), 82 80 bytes

Toma entrada como (year,month,day).

let f =

(y,m,d)=>-~((((x=new Date(y,m-1,d))-new Date(y,0,1))/864e5+372-x.getDay())/7%53)

console.log(f(2017, 5,17)) // 20
console.log(f(2013, 1, 3)) // 53
console.log(f(2017, 1, 1)) // 1
console.log(f(1901, 5,17)) // 19
console.log(f(2100,12,31)) // 52
console.log(f(2015, 7, 7)) // 27

Arnauld
fuente
4

JavaScript (Firefox 34+), 70 bytes

with(new Date())y.value=getFullYear(),m.value=getMonth()+1,d.value=getDate()+1
f=
(y,m,d)=>new Date(y,--m,d-new Date(y,m,d).getDay()).toLocaleFormat`%U`
<div oninput=w.value=f(y.value,m.value,d.value)><input id=y type=number><input id=m type=number min=1 max=12><input id=d type=number min=1 max=31><input id=w readonly placeholder=Output>

Funciona encontrando el primer día de la semana que contiene la fecha dada, luego buscando el número de la semana de ese día (que nunca es cero).

Neil
fuente
+1 para with. Siempre +1 para with!
Shaggy
2

Python 2, 70 64 bytes

Entrada => (year,month,day)

from datetime import*;lambda*v:int(date(*v).strftime('%U'))or 53

print(f(2017, 5,17)) #20
print(f(2013, 1, 3)) #53
print(f(2017, 1, 1)) #1
print(f(1901, 5,17)) #19
print(f(2100,12,31)) #52
print(f(2015, 7, 7)) #27

-6 bytes, gracias a @ovs

Wondercricket
fuente
2

JavaScript (solo Firefox), 77 bytes

Toma la fecha como cadena: es decir Jan 1, 2017

s=>+new Date(s)[k='toLocaleFormat']`%U`||new Date(s.slice(-4)-1,11,31)[k]`%U`
Powelles
fuente
Buen intento, pero la "semana 0" no siempre es la misma semana (1995 y 2023 son diferentes).
Neil
Lo siento, casos de prueba incorrectos. Debería publicar un comentario apropiado sobre la pregunta.
Neil
@Neil Debe corregirse.
Powelles
2

PHP, 125 bytes

for($w=53,$a=0;($c=date_create)($argn)>=$n=date_modify($c("07JAN1900"),"+$a week");$a++)$w=date_format($n,z)<7?1:$w+1;echo$w;

Pruébalo en línea!

PHP, 28 bytes

Versión para lunes en lugar de domingo

<?=date(W,strtotime($argn));

Pruébalo en línea!

Jörg Hülsermann
fuente
2

C #, 138 123 121 bytes

namespace System.Globalization{d=>CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(d,(CalendarWeekRule)1,(DayOfWeek)0);}

Resulta que hay un incorporado para eso, aunque es bastante grande ...

namespace System.Globalization
{
    Func<DateTime, int> f = d =>
        CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(d, (CalendarWeekRule)1, (DayOfWeek)0);
 }
TheLethalCoder
fuente
1

Powershell, 260 + 8 = 268 bytes

+8 bytes debido a la -DateTimebandera


Acepta argumentos como "day month year"formato.

function W([datetime]$DateTime = (Get-Date)) {
$cultureInfo = [System.Globalization.CultureInfo]::CurrentCulture
$cultureInfo.Calendar.GetWeekOfYear($DateTime,$cultureInfo.DateTimeFormat.CalendarWeekRule,$cultureInfo.DateTimeFormat.FirstDayOfWeek)
}

No es experto en Powershell, no puede jugar golf


Caso de prueba

>W -DateTime "11 March 2015"
11
stevefestl
fuente