<?php
Class Fecha {	
	/*
		Ingresa un formato machine y debe devolver un formato humano.
		Ingresa un formato humano y debe devolver un formato machine.
		##Formato de fecha: 
			https://www.php.net/manual/en/datetime.format.php
	*/	
	static public function formato($formato_output_DESEADO, $datetime) {
		/*
			Reemplazos inteligentes, se espera algo como esto:
			$formato_input_IDENTIFICADO: se espera algo libre, como "d de mmmm DE Y"
			$formato_output_DESEADO
		*/		
		
		/*		
					$formatos_posibles = array(
			//			"d de mmm"=>"$d de $mmm",
			//			"d de mmmm"=>"$d de $mmmm",			
						"yyyy"    =>"$yyyy",
					);		
		
		if(!in_array($formato_output_DESEADO, array_keys($formatos_posibles))) {
			error_y_salir("##Error20260325185148-40252dav: No existe el formato '$formato_output_DESEADO'.");
		}			
		return $formatos_posibles[$formato_output_DESEADO];
		*/

		
		$fecha_obj = self::auxiliar1_identificar_formato_y_generar_fecha_obj($datetime);
		if($fecha_obj==FALSE) {			
			error_y_salir("##Error20260504185736-3025dav: no debería haber llegado a este punto.");		
		}
		//vamos aquí  traer aquí  la normalización  ##vamosaqui202604051744
		$fecha_string = self::normalizar_formato($formato_output_DESEADO, $fecha_obj);
		return $fecha_string; //En el formato deseado		
	} //Fin de formato

	private static function auxiliar1_identificar_formato_y_generar_fecha_obj($datetime) {
		require(__DIR__ . "/Fecha_Aux1_fecha_identificar_formato_y_generar_fecha_obj.php");
		$fecha_obj = call_user_func("Fecha_Aux1::auxiliar1_identificar_formato_y_generar_fecha_obj", $datetime);
		return $fecha_obj;
	} //Fin de auxiliar1_identificar_formato_y_generar_fecha_obj


	private static function auxiliar2() {
		require(__DIR__ . "/Fecha_Aux2_fecha_formatos_aceptados_de_funcion_date_php.php");		
		$formatos_aceptados_de_funcion_date_php = Fecha_Aux2::formatos_aceptados_de_funcion_date_php();
		return $formatos_aceptados_de_funcion_date_php;
	} //Fin de auxiliar2
	
	private static function auxiliar3() {
		require(__DIR__ . "/Fecha_Aux3_periodos_sinonimos_y_traducciones_para_formatos_DATE.php");
		$periodos_sinonimos_y_traducciones_para_formatos_DATE = Fecha_Aux3::periodos_en_formato_date();
		return $periodos_sinonimos_y_traducciones_para_formatos_DATE;
	} //Fin de auxiliar3

	static public function auxiliar4() {
		require_once(__DIR__ . "/Fecha_Aux4_fecha_auxiliar_stop_words.php");
		$lista_de_stop_words_tipicas_en_fechas = Fecha_Aux4::lista_de_stop_words_tipicas_en_fechas();
		return $lista_de_stop_words_tipicas_en_fechas;
	} //Fin de auxiliar4
	
	static public function normalizar_formato($formato_output_DESEADO, $fecha_obj) {		
		/* Los siguientes términos son equivalentes, hablan de lo mismo:
				-$fecha_obj
		        -la fecha real
				-la fecha de input
				-la fecha de input $fecha_obj				
			Todos esos términos son los mismos.
		*/
		$formatos_aceptados_de_funcion_date_php               = self::auxiliar2();
		$periodos_sinonimos_y_traducciones_para_formatos_DATE = self::auxiliar3();		
		$lista_de_stop_words_tipicas_en_fechas                = self::auxiliar4();
		//##partes_de_fecha_____lugar1de2: partición
		$partes_de_fecha = preg_split("~[\s,\-\/]~", $formato_output_DESEADO );
		$strict_TRUE = TRUE;
		$const_TRUE  = TRUE;
		//El siguiente bucle es un motor del carajo: toma cada una de las partes del 
		//formato DESEADO, y las transforma en la fecha de input $fecha_obj
		
		//También puede entenderse como que toma cada parte del formato deseado y busca esa parte 
		//en la fecha input, que ya previamente está discriminada como objeto.
		//Teniendo en cuenta que el output de la presente función es una string, y a que la fecha 
		//es la misma de $fecha_obj, no necesita crear un objeto para el "formato DESEADO", sino que basta 
		//con el objeto de la fecha input $fecha_obj, 
		foreach($partes_de_fecha as $key=>$parte) {
			$pn = trim(strtolower($parte)); //$pn = parte normalizada, para buscarla. 
			switch( $const_TRUE ) {
				//##ABAJO: partes como mmm, m, d, que son típicamente entendidos por la función date de php
				case ( in_array($pn, $formatos_aceptados_de_funcion_date_php, $strict_TRUE) ):
				  $partes_de_fecha[$key] = $fecha_obj->format($parte);
				  /* Ejemplo:
									$d    = $fecha_obj->format("d");
									$yyyy = $fecha_obj->format("Y");
				  */
				  break;
				//##ABAJO: partes como nombres de días de la semana, meses, en un idioma, que deben 
				//         traducirse y no se pueden tomar directamente de lo que arroja la función date;
				//         o sinónimos para los formatos usuales de Date
				case ( in_array($pn, array_keys($periodos_sinonimos_y_traducciones_para_formatos_DATE), $strict_TRUE) ):	
				  $callback = $periodos_sinonimos_y_traducciones_para_formatos_DATE[$parte];				  
				  $partes_de_fecha[$key] = call_user_func($callback, $fecha_obj );
				  break;	
			    //##ABAJO: palabras triviales que cambian con los idiomas y existen en las fechas, como 
				//         la preposición "de"
				case ( in_array($pn, $lista_de_stop_words_tipicas_en_fechas, $strict_TRUE) ):
				  $partes_de_fecha[$key] = Fecha_Aux4::normalizar_stop_word($parte);
				  break;
			    //Otros casos podrían ser: sufijos como st, nd, rd, th
				//                         
			}
		}
		//var_dump($formato_output_DESEADO);
		//var_dump($fecha_obj);
		//var_dump($partes_de_fecha);
		//Es de notar que $partes_de_fecha está ya en el orden deseado, así que lo volvemos a unir en string:
		//##partes_de_fecha_____lugar2de2: unión
		$fecha_str = implode(" ", $partes_de_fecha);
		return $fecha_str;
		/* ##Futuro: debería volverse algo tan simple como:
		$fecha_string = $fecha_obj->format($formato_output_DESEADO);
		return $fecha_string;
		*/		
	} //Fin de formato
} //Fin de Fecha

/*
##rationale:
	Originalmente se quería pasar de 
		date("d de Y") 
		a
		date("d \d\e Y");
	Y ello se podía lograr "escapando" las stop-words. Pero no resolvía el problema de la traducción, 
	como pasar de "Saturday" a "Samstag" o "Sábado"
	Tampoco resolvía la ambigüedad de que al usuario programador le toca aprenderse que para meses 
	en 3 letras es una sigla de formato muy diferente de para año en 2 dígitos o años en 4 dígitos.

Este módulo busca resolver por fin el problema de conversión entre fechas. Sin necesidad de múltiples 
funciones, sino una sola y un formato, similar a como actúa la función DATE, pero mucho más simple 
que como se hace en php, mysql, etc. Sino algo más simple apuntando a como lo hacía Edwin en FoxPro (##20260415).

El método consiste en que para pasar de 
	string1 --> string2 
	se toma: 
	string1 --> formato_input_IDENTIFICADO --> $fecha_obj ---> partes de formato_output_DESEADO 
														  ---> $fecha_obj a partes de formato_output_DESEADO
														  ---> se unen esas partes en una string y se retorna:
														  ---> $string2

*/
/*
//##Modo de uso:
$formato_estandar = "Y-m-d H:i";
//$f = new Fecha($formato_estandar, "2026-04-02 17:35:48");
$formato_estandar = "d de mmmm DE Y";
echo Fecha::formato($formato_estandar, "2026-09-07 17:35:48");


*/