---
title: 'Número de semana en MySQL y PHP'
url: 'https://desk.co.cr/blog/week-in-mysql-and-php'
markdown: 'https://desk.co.cr/blog/week-in-mysql-and-php.md'
lang: es
date: '2019-01-28'
description: 'Para los que tenemos que coordinar números de semana que provienen de fechas manejadas entre MySQL y PHP, a veces es un reto, especialmente cuando se trata de la última o primera semana de un año. Cuál e'
taxonomy:
  category:
    - blog
  tag:
    - ti
    - programacion
  archives_month:
    - jan_2019
  archives_year:
    - '2019'
---

# Número de semana en MySQL y PHP

Para los que tenemos que coordinar números de semana que provienen de fechas manejadas entre MySQL y PHP, a veces es un reto, especialmente cuando se trata de la última o primera semana de un año.

Cuál es el asunto? Dependiendo de cómo uno cuenta las semanas del año (por ejemplo iniciando en 0 o iniciando en 1) la semana del 31 de diciembre 2018 podría ser considerada como la última del año 2018 o la primera del 2019. Y por ende, podría ser la Semana 53 del 2018, la Semana 0 del 2019 o la Semana 1 del 2019. Adicionalmente, si uno requiere combinar el número de la semana con el año, podrían darse constelaciones extrañas:

- Ejemplo A: **31/12/2018**
    - Año de la fecha: 2018
    - Número de la semana: primera semana del 2019 (Semana 0 o 1, dependiendo de la configuración del sistema)
    - Año de la semana: 2019
- Ejemplo B: **02/01/2016**
    - Año de la fecha: 2016
    - Número de la semana: última semana del 2015 (Semana 52 o 53, dependiendo de la configuración del sistema)
    - Año de la semana: 2015

Yo me topé con este fenómeno durante el desarrollo de una interfaz para una base de datos y encontré la pista para mi solucioń en [stackoverflow \[1\]](#fuentes).

La interpretación depende de la configuración tanto de MySQL como de PHP en el servidor donde están instalados. Para MySQL, el valor predeterminado es definido por el valor de la propiedad `default_week_format` en las variables del sistema [\[2\]](#fuentes).

En PHP, el número de la semana es definido e interpretado según ISO-8601 siempre, pero en MySQL la definición puede ser diferente y por ende, cuando haya que homologar información entre MySQL y PHP, pueden ocurrir conflictos. La ISO-8601 define el número de semana de la siguiente manera [\[3\]](#fuentes):

- Las semanas del calendario tienen 7 días e inician los lunes.
- El número de semana 1 es aquella semana, que contiene el primer jueves del año.

En otras palabras: si el 01 de enero cae lunes, martes, miércoles o jueves, está en la semana 1. Si el 01 de enero cae viernes, sábado o domingo, pertenece a la semana 52 o 53 del año anterior.

Para lograr una consistencia entre MySQL, PHP y una fecha determinada, lo recomendable es utilizar la función YEARWEEK en MySQL [\[4\]](#fuentes) y date() en PHP [\[5\]](#fuentes) de la siguiente manera:

## Ejemplos

### Ejemplo A

En MySQL:

```
> SELECT YEARWEEK('2019-01-01', 3);
+---------------------------+
| YEARWEEK('2019-01-01', 3) |
+---------------------------+
|                    201901 |
+---------------------------+
1 row in set (0.00 sec)
```

- Interpretación: 
    - Resultado: 201901 (Año 2019, Semana 01)
    - El argumento 3 define el modo, donde se define el día lunes como primer día de la semana, que la primera semana del año inicia en 1 y la semana 1 es aquella semana que contiene 4 o más días en el año que corresponde [\[6\]](#fuentes).

Ingresando la misma fecha en PHP:

```
<?php
echo date('oW', '2019-01-01');
// muestra en pantalla: 201852
?>
```

- Interpretación: 
    - El argumento W indica el número de semana según ISO-6801 y el argumento o el año de la fecha señalada, tomando en consideración (y ajustando cuando sea necesario) el año de la semana calendario (en lugar del año de la fecha).

### Ejemplo B

En MySQL:

```
> SELECT YEARWEEK('2016-01-02', 3);
+---------------------------+
| YEARWEEK('2016-01-02', 3) |
+---------------------------+
|                    201553 |
+---------------------------+
1 row in set (0.00 sec)
```

En PHP:

```
<?php
echo date('oW', '2016-01-02');
// muestra en pantalla: 201553
?>
```

### Ejemplo C

En MySQL:

```
> SELECT YEARWEEK('2018-12-31', 3);
+---------------------------+
| YEARWEEK('2018-12-31', 3) |
+---------------------------+
|                    201901 |
+---------------------------+
1 row in set (0.00 sec)
```

En PHP:

```
<?php
echo date('oW', '2018-12-31);
// muestra en pantalla: 201901
?>
```

## Fuentes

- \[1\] Reed, M. (2015). PHP date ('W') vs MySQL YEARWEEK(now()). Stack Overflow. <https://stackoverflow.com/questions/15562270/php-datew-vs-mysql-yearweeknow>
- \[2\] Oracle. (2019). MySQL Reference Manual: Server System Variables. [https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar\_default\_week\_format](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_default_week_format)
- \[3\] Wikipedia. (2019). ISO week date. [https://en.wikipedia.org/wiki/ISO\_week\_date](https://en.wikipedia.org/wiki/ISO_week_date)
- \[4\] Oracle. (2019). MySQL Reference Manual: Date and Time Functions. [https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function\_yearweek](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_yearweek)
- \[5\] The PHP Group. PHP: date - Manual. <https://secure.php.net/manual/de/function.date.php>
- \[6\] Oracle. (2019). MySQL Reference Manual: Date and Time Funcionts, WEEK. [https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function\_week](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_week)

## Créditos

- Zeller, S. (2018). [A number one painted on a red garage door](https://unsplash.com/photos/387LUjMAiHI). \[Imagen en línea\]. Unsplash. <https://unsplash.com/>

---

## Navigation

- Parent: [Apuntes](https://desk.co.cr/index.md)
- Previous: [Ignorar archivos específicos en SVN](https://desk.co.cr/blog/svn-ignore.md)
- Next: [Configuración de Grav CMS](https://desk.co.cr/blog/configuracion-grav.md)
