Blog de programación en C++ Builder.pdf

7
 Dato s y So ftware - So luc io nes Da t o s y So ft wa r e - So luc i o ne s Inicio Contáctenos Qué es DatoSoft Descargas Formas con métodos similares Como aprovechar un metodo de una forma en otra que tambien tiene un metodo similar solo con algunas diferencias sin heredar? Si se maneja friend se puede acceder al metodo de la amiga pero en el metodo la forma se refiere a sus propios edits y demas y no a la que lo llama. / Ir a otros temas... Pr o g r a m a ci ó n co n C++ B uilde r  Esta herramienta de programación es la elegida por muchos desarrolladores en lenguaje C++ por su facilidad para crear aplicaciones Windows, casi de una manera tan fácil como en Visual Basic. Algunos apuntes del día a día... CONTENIDO formas que automaticamente se crean objetos dinamicos incremental linker se queda pegado Placing datasets (and data sources) directly on forms Cadenas en C++ Builder: filtros Recorrer los controles de una forma DBGrids Variants Busquedas Sobre los colores Para asignarle eventos a TApplication Paso de parámetros puntero como de salida Formas con métodos similares Texto de una listBox Para que en una combo box no se pueda escribir: Operador incremento en campos de tablas Linker failed to create map file error code 0 Para detectar teclas en Windows Para enviar una tecla a un edit, de modo que el curso se mueva al final. Para definir eventos dinamicos detectar que esta corriendo otra instancia Para crear accesos directos en el menú del botón inicio Para busquedas: Para detener una instruccion for, while etc. Retornar un TDateTime en una función Posicionando el cursor en TMemo Fechas y horas Uso de los manipulators si no se usa "using namespace std" El método length de las std:string cuenta inclusive el null Para extraer los parametros de la línea de comandos Detectar dos instancias ejecutandose de una mismavaplicación Constructor hides a otro Para que los hints duren mas Como colocar una fecha con el formato correcto del sistema ormas que automáticamente se crean (en las opciones del proyecto)  jo con las formas que automáticamente se crean, porque estando así efinidas en las propiedades del proyecto, pues sin querer pueden abrir ablas etc. n proyecto en zeos no se debe conectar en tiempo de diseño, porque si uego no esta disponible el servidor, bloquea al C Builder. Blog de programación en C++ Builder http://datosoft.com/BlogCBuilder.htm#recorrerControlesForma 1 de 7 09/01/2015 12:53 a. m.

Transcript of Blog de programación en C++ Builder.pdf

  • Datos y Software - Soluciones Datos y Software - Soluciones

    Inicio Contctenos Qu es DatoSoft Descargas

    Formas con mtodos similaresComo aprovechar un metodo de una forma en otra que tambientiene un metodo similar solo con algunas diferencias sin heredar?Si se maneja friend se puede acceder al metodo de la amiga pero enel metodo la forma se refiere a sus propios edits y demas y no a laque lo llama./

    Ir a otros temas...

    Programacin con C++ BuilderEsta herramienta de programacin es la elegida por muchos desarrolladores en lenguaje C++ por su facilidad para crear aplicaciones Windows, caside una manera tan fcil como en Visual Basic.Algunos apuntes del da a da...

    CONTENIDO

    formas que automaticamente se creanobjetos dinamicosincremental linker se queda pegadoPlacing datasets (and data sources) directly on formsCadenas en C++ Builder:filtrosRecorrer los controles de una formaDBGridsVariantsBusquedasSobre los coloresPara asignarle eventos a TApplicationPaso de parmetros puntero como de salidaFormas con mtodos similaresTexto de una listBoxPara que en una combo box no se pueda escribir:Operador incremento en campos de tablasLinker failed to create map file error code 0Para detectar teclas en WindowsPara enviar una tecla a un edit, de modo que el curso se mueva al final.Para definir eventos dinamicosdetectar que esta corriendo otra instanciaPara crear accesos directos en el men del botn inicioPara busquedas:Para detener una instruccion for, while etc.Retornar un TDateTime en una funcinPosicionando el cursor en TMemoFechas y horas Uso de los manipulators si no se usa "using namespace std"El mtodo length de las std:string cuenta inclusive el nullPara extraer los parametros de la lnea de comandosDetectar dos instancias ejecutandose de una mismavaplicacinConstructor hides a otroPara que los hints duren masComo colocar una fecha con el formato correcto del sistema

    Formas que automticamente se crean (en las opciones del proyecto)Ojo con las formas que automticamente se crean, porque estando asdefinidas en las propiedades del proyecto, pues sin querer pueden abrirtablas etc.Un proyecto en zeos no se debe conectar en tiempo de diseo, porque siluego no esta disponible el servidor, bloquea al C Builder.

    Blog de programacin en C++ Builder http://datosoft.com/BlogCBuilder.htm#recorrerControlesForma

    1 de 7 09/01/2015 12:53 a. m.

  • Texto de una listBoxPara sacar el texto de una ListBox (es un AnsiString):ListBox1->Items->Strings[ListBox1->ItemIndex];

    Para que en una combo box no se pueda escribir:usar estilo csDropDownList

    Operador incremento con campos de tablasNo se pueden hacer operaciones como esta:table1->FieldValues["campo1"]+=8;Toca sacar primero el valor del campo a una variable y luegotable1->FieldValues["campo1"]=variable+8;

    Linker failed to create map file error code 0

    FAQ913C.txt Linker failed to create map file error code 0Category :LinkerPlatform :AllProduct :C++Builder 1.x

    Question:I am getting a "fatal linker error: linker failed to create map file :error code 0." when running an example project.

    What do I do to make this error go away?

    Answer:

    (1) Delete the *.il? in the project(2) Delete the *.csm files in the lib directory(3) Delete the deflink.il? files in the bin directory

    Para volver a crearlos: bcb -deflink

    Para detectar teclas en Windows con C++ Buildervoid __fastcall TFrmMain::FormKeyDown(TObject *Sender,WORD &Key,TShiftState Shift){// Las teclas estan definidas en: Virtual-Key Codes// Aqui se cheque que pulsen F5 y Ctrl y Shift al mismo tiempo:if (Key==VK_F5 && Shift.Contains(ssCtrl) &&Shift.Contains(ssShift))sndPlaySound("copyright.wav", SND_SYNC);

    Para enviar una tecla a un edit, de modo que el curso se muevaal final.PostMessage(EdICuenta->Handle, WM_KEYDOWN,VK_END,0);

    Para definir eventos dinamicamente, solo para una forma:

    // Definir eventos dinamicamente que nazcan y mueran en estaforma:DataModule1->DSFacturas->OnDataChange=TFrmConsFacturacion::FacturasDataChange;DataModule1->TblFacturas->AfterPost=TFrmConsFacturacion::FacturasAfterPost;DataModule1->TblFacturas->BeforePost=TFrmConsFacturacion::FacturasBeforePost;

    Luego en el destructor:// Quitar los eventos definidos al empezarDataModule1->DSFacturas->OnDataChange=NULL;DataModule1->TblFacturas->AfterPost=NULL;DataModule1->TblFacturas->BeforePost=NULL;

    Ver Agua ConsFacturacion

    Trabajar con objetos dinmicos tiene una ventaja cuando no se desea queel constructor sea invocado en el punto h al declarar la variable, ejemplo:TPermisos Permisos vs TPermisos *Permisos

    Si el incremental linker se queda pegado, revisar en opciones delproyecto, las rutas de los directorios de las lib y los nclude. Quitar la de c:\si aparece

    Note: Placing datasets (and data sources) directly on forms isrecommended only for very simple database applications. Even formoderately simple database applications that only work with a few tablesor queries on a few forms, using a DATA MODULE eases developmentand maintenance.

    Cadenas en C++ Builder:1. Estn las tradicionales del c: char Cadena[20];2. La clase standar del C++: string;3. Las nuevas cadenas largas del Pascal: AnsiString que se redefine comotypedef AnsiString String en sysdefs.h. Son las que se utilizan en todos loscomponentes visuales de la vcl. AnsiString es una clase que soporta eloperador + para concatenar.4. Para arreglos, TStringList, en vcl\classes.hpp5. Las wchar para manejar UNICODEPara colocar una cadena que en medio tenga un carcter como \x14 (20decimal):Lista->Add("5011 187018E41401003\x14""5012 187203");Ocurri en depurar.cpp de signal.

    FiltrosPara colocar filtros que dependan de edits, combobox etc.:

    String Filtro; // AnsiString (Clase emuladora string tipo pascal) Filtro="IGondola="+CBGondolas->Text; // Construimos la expresin TblKarMaest->Filtered= true; TblKarMaest->Filter=Filtro; TblKarMaest->RecordCount!=0 // Solo cuenta los del filtro!!

    Para colocar filtros a campos fecha:[FFactura]>'01/01/2001'Otro ejemplo:Filtro="IFactAguaNULL and[FFactura]>'"+FechaDesde->DateString()+"'";Con FechaDesde del tipo TDateTime

    Para colocar expresiones caracter entre comillas:Filter=String("IGrado=")+IGrado+" and "+IGrupo='"+IGrupo+"'";

    Para distinguir de campos vaciosIFactAguaNULL

    Para recorrer los controles de una forma:

    void TfrmNuevoArt::InitDatos() {int i;

    TControl *Control= dynamic_cast (this); // Recorrer los controles de la forma for(i=0; i < Control->ComponentCount; i++) { //ShowMessage(Control->Components[i]->Name); if (Control->Components[i]->Name.SubString(1,2)=="ed%quot;) dynamic_cast (Control->Components[i])->Text="";

    }}

    DBGridsUn DBGrid es una simple ventana cuyas celdas se dibujan, la celda no esun TControl ni nada por el estilo, ver los ejemplos pruebas\dbgrid) y se vque para dibujar simplemente se usa el canvas del grid.Seguramente que al momento de escribir se crea un edit para capturarlounicamente.

    Para colocarle la flechita abajo o el boton con ... en una columna toca conel editor de columnas aadir la del caso y ya sea colocarleen la propiedad picklist las que deseamos que aparezcan o en el butonstylecolocar ellipse y definir un evento tal (estando ahipulsar la ayuda).

    Blog de programacin en C++ Builder http://datosoft.com/BlogCBuilder.htm#recorrerControlesForma

    2 de 7 09/01/2015 12:53 a. m.

  • Ejemplo para detectar que esta corriendo otra instancia de unprograma en WIN32:try{CreateMutex(NULL, false, Application->ExeName.c_str());if (ERROR_ALREADY_EXISTS==GetLastError()) {ShowMessage("Ya se est ejecutando el programa. Observe en labarrade tareas.");PostQuitMessage(0);}else {Application->Initialize();Application->CreateForm(__classid(TDataModule1),&DataModule1);Application->CreateForm(__classid(TFrmMain), &FrmMain);Application->Run();}}*/

    /*Para crear accesos directos en el men del botn inicio,An se sigue utilizando DDE para conversar con el ProgramManager.La VCL tiene un componente que encapsula el inicio y final de laconversacin: TDdeClientConvBasta colocarle en las propiedades, DdeService y DdeTopic,"program" en cada uno, y luego DdeClientConv1->ExecuteMacro("[CreateGroup(tigre2)][AddItem(e:\\ut\\fconvert.exe,ivan)]",false))Ve en Pruebas, PrDde*/

    /*Para detener una instruccion for, while etc.Para permitir que un botn Cancelar acte y detenga un ciclo, debecolocarse dentro del ciclo: Application->ProcessMessages();Y El cdigo asociado al botn debe ser colocar una variable a false,variable que debe ser una de las condiciones del ciclo, por supuesto.No funciona colocar PostQuitMessage() o Close() en el cdigoasociado al click del boton, porque regresa al ciclo y contina dandovueltas.

    Retornar un TDateTime en una funcinSi una funcion necesita retornar un TDateTime debe ser as, puesusando FieldByName sale Error de generacion de codigo enCBuilder 1.0:TDateTime TUsuario::GetFechaPago() {return DataModule1->TblUsuarios->FieldValues["FPagoAnt"];}

    Posicionando el cursor en TMemoPara posicionarse al inicio de un TMemoMemo1->SelStart=0;Memo1->SelLength = 0;Memo1->Perform(EM_SCROLLCARET, 0, 0);Memo1->SetFocus();

    Para ubicarse en cierto punto y seleccionando texto: (didactica.exe)Memo1->SetFocus();Memo1->SelStart=1416;Memo1->SelLength = 10;

    Fechas y horasEjemplo de resta dados dos fechas y dos horas, mostrando la

    El evento que responde a cambio de fila o de record es el ondatachange deun datasource, con Field igual a NULL.Ver Contador para un ejemplo de como actualizaLabels a medida que semueven por el grid.

    Ejemplo para que la tecla Ctrl-suprimir no funcione en un Grid

    void __fastcall TFrmConsFacturacion::DBGrid1KeyDown(TObject *Sender,WORD&Key, TShiftState Shift){

    if (Key==VK_DELETE && Shift.Contains(ssCtrl)) Key=NULL; // Como es por referencia, se cambia y el evento // default la recibe como null }

    Para no permitir que la flecha hacia abajo aada registros:

    void __fastcall TFrmMateriasPeriodo::DBGrid1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { (Key==VK_DOWN && DBGrid1->DataSource->DataSet->RecNo== DBGrid1->DataSource->DataSet->RecordCount) Key= NULL;}

    Otra manera para cuando el Recno no coincida con las lineas del grid,tomando previamente el RecNo del ultimo registro del grid:

    void __fastcall TFrmGrabarNotas::DBGrid1KeyDown(TObject *Sender, WORD&Key, TShiftState Shift) { // Para desactivar Ctrl-Suprimir en el grid. if (Key==VK_DELETE && Shift.Contains(ssCtrl)) Key=NULL; else if (Key==VK_DOWN && Query1->RecNo==LastRecord) Key= NULL;}

    Para poder tener campos de diferentes tablas en un mismo dbgrid, debecolocarse asociado al grid una TTable con caractersticas muy especiales:Primero debe ser un campo aadido con fields editor (boton derecho enttable) usando new field y no add fields

    keyFields= IUsuario (Contenido en table1 a buscar en la otra)LookUpDataSet=Table2 (Tiene a IUsuario y a NUsuario, con llaveIUsuario)LookKeyFields=IUsuario (Campo a buscar en la tabla 2 que case conkeyfield)LookUpResultField=NUsuario (Campo a devolver de la tabla 2)LookUp=True

    No se requiere colocar propiedades de lookup en la tabla, ni se requiereindexado, pero con ste funciona mas rpido

    Estos campos solo son de lectura y deben definirse en el eventoOnCalcFields.Si se quiere que aparezca el valor tomado de otra tabla debe ser un lookup,que tambien queda de solo lectura.Si se quiere mostrar un valor en el campo, pero que no sea calculado nilookup,de modo que se pueda cambiar, debe colocarse un evento en elDBGrid en OnColEnter, que asigne al campo el valor de la otra tabla, (nose puede en el OnCalcFields porque se produce StackOverFlow), tal comoocurre en kardex,ej:

    if (DbGridFact->SelectedField->FieldName=="ENTRADAS") { if (DataModule1->Art->Locate("CodiArti",

    DataModule1->MovTemp->FieldByName("CodiArti")->AsString, TLocateOptions())) { DataModule1->MovTemp->Edit(); DataModule1->MovTemp->FieldValues["Valor"]

    =DataModule1->Art->FieldValues["ValoComp"]; }}

    Para chequear la columna actual:ColumnaActual=DBGrid1->SelectedIndex;

    Para darle el foco a una columna dada:DBGrid1->SelectedIndex=3;DBGrid1->SetFocus();

    Blog de programacin en C++ Builder http://datosoft.com/BlogCBuilder.htm#recorrerControlesForma

    3 de 7 09/01/2015 12:53 a. m.

  • diferencia en horas (tanto la resta de fecha como de horas debemultiplicarse por 24)

    TDateTime FechaAct, HoraAct,FechaReg, HoraReg;int DifHoras;

    FechaAct=TDateTime().CurrentDate();HoraAct=TDateTime().CurrentTime();FechaReg=TDateTime().CurrentDate()-2;HoraReg=TDateTime().CurrentTime()+6./24;DifHoras=(int)(FechaAct-FechaReg)*24+(double)(HoraAct-HoraReg)*24;ShowMessage(DifHoras);*/

    Mas sencillo as:TDateTime().CurrentTime().DecodeTime(&ha, &ma, &sa, &msa);Config.GetHoraTest().DecodeTime(&ht, &mt, &st, &mst);if (ha==ht && ma==mt && abs(sa-st)Caption=String("Fecha de inventarios iniciales:(")+BufDate+")";imprime ("mm/dd/yyyy")

    Si se quiere trabajar con campos time como llave, debe grabarse concero milisegundos para que cuando se vaya a buscar hayacoincidencia.Recordar que es un doble y de lo contrario no coinciden lo que segrabo con lo que se escribe en el sql. Ejemplo de signal, primerodecodificamos la hora:HoraSignal.DecodeTime(&Hora, &Min, &Sec, &MilSec);Y al grabarla la ponemos con cero milisegundosFrmDMSignal->TblHistoria->FieldValues["THora"]=TDateTime(Hora,Min,Sec,0);

    Luego en la manipulacion de la tabla:THora=FrmDMMonitor->TblCola->FieldByName("THora")->AsDateTime;osItems[0]->ReadOnly= true;

    Para validar a la salida de una celda:En el OnColExit Colocar el codigo validador, y si es falso,en el colenter colocar el SelectedIndex en donde estaba. Ver el cdigofuente del programa de contabilidad, al capturar el asiento.En un DBGrid para que el texto que escriban este en mayusculas tocadefinirlo en el On DrawColumnCell asi:

    String Texto= DataModule1->MovTemp->FieldByName("CodiArti")->AsString;if (DataCol==1) { // la columna de interes DbFact->Canvas->TextOut(Rect.Left+2,Rect.Top+2,Texto.UpperCase());}else DbFact->DefaultDrawColumnCell(Rect, DataCol, Column, State);

    Pero para que esto realmente se tome el dato entrado en la tabla toca en elevento OnColEnter del grid, colocar:CodiArti=DataModule1->MovTemp->FieldByName("CodiArti")->AsString;DataModule1->MovTemp->FieldValues["CodiArti"]=CodiArti.UpperCase();

    La clave para que no se mueva el grid en las validaciones y en los forrecorriendo la tabla, es desconectar el grid del datasource en los procesos yjusto antes de que se vuelva a visualizar volverlo a conectar.Una manera de hacerlo es con DataSet->DisableControls, por ejemplo si eldataset es un Query1: (Ver agua Reporte para lecturas)Query1->DisableControls();FrmRptLeerLectura->QuickReport1->Preview();Query1->EnableControls();

    Tcnica para hacer que la fila del DBGrid se ilumine en la medida que nosmovemos, pero con edicion y todo: (Grabarnotasgrupo en colegios)

    En el datasource, evento datachange:void __fastcall TFrmGrabarNotasGrupo::Datasource1DataChange(TObject*Sender,TField *Field){RecNum=DSNotasTemp->DataSet->RecNo;}

    En el ondrawColumnCell del dbgrid:

    void __fastcall TFrmGrabarNotasGrupo::DBGNotasDrawColumnCell( TObject *Sender, const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State){ //La propiedad DefaultDrawing del grid=false en tiempo de diseo. //Nosotros le dibujamos el texto try { if (DM->TblNotasTemp->RecNo==RecNum) DBGNotas->Canvas->Brush->Color=clInfoBk; DBGNotas->DefaultDrawColumnCell(Rect, DataCol, Column, State); } catch (MyException &e) { ShowMessage(e.Mensaje()); }}

    Ejemplo de cdigo para validar una columna en un dbgrid. Se hace en elevento updateData del datasource, y si no cumple con la especificacin setira una exception. (tomado de main.cpp en colegios)

    void __fastcall TFrmMain::DSEstudiantesUpdateData(TObject *Sender) { try { String situacion;

    situacion=DM->TblEstudiantes->FieldByName("Situacion")->AsString; if (situacion.IsEmpty()) return; if (islower(situacion[1])) { DM->TblEstudiantes->Edit(); DM->TblEstudiantes->FieldValues["Situacion"]=situacion.UpperCase(); situacion=situacion.UpperCase(); } if (situacion!="" && situacion!="C" && situacion!="D" && situacion!="M") {

    DM->TblEstudiantes->Edit(); DM->TblEstudiantes->FieldValues["Situacion"]="";

    Blog de programacin en C++ Builder http://datosoft.com/BlogCBuilder.htm#recorrerControlesForma

    4 de 7 09/01/2015 12:53 a. m.

  • AsString = "INF95"; DataModule1->TblCargaAcad->IndexName="Materia"; if (DataModule1->TblCargaAcad->GotoKey()) IDocente= DataModule1->TblCargaAcad->FieldByName("IDocente")->Value; else ShowMessage("NO Encontrado");

    Con locate: bool LocateSuccess; TLocateOptions SearchOptions;SearchOptions Locate("Company", "Professional Divers, Ltd.", SearchOptions); // campo contenido }

    Sobre los coloresCaso:Se tiene una forma con color clSilver (TColor)(12632256)o C0C0C0 quees el mismo de BtnFace y se tiene un bitmap que se le oloca ese fondo conlos graficadores. Pero al unirlos no resultan igual y se nota la sombra.Solucin cambiar de color de alta intensidad (16 bits) en el modo de vidoal modo verdadero (24 bits). Ahi si coinciden. Expliquelo Vargas.*/

    /*Para asignarle eventos a TApplicationver en src\cbuilder\pruebas o ConsFacturacion en agua

    En el constructor;DataModule1->TblAbaBancos->BeforeDelete=TFrmBancos::NoDelete;

    En el desctructorDataModule1->TblAbaBancos->BeforeDelete=NULL;

    En la implementacin del metodo a llamar, en este caso para que no borre.void __fastcall TFrmBancos::NoDelete(TDataSet *) {Abort();}

    */

    /*Paso de parmetros puntero como de salida: (Se cambia la direccin delpuntero en la funcin y sale cambiada.)Ver ejemplo punt_in_out.cpp en carpeta universidad nacional Ilustra comoa semejanza de los enteros etc. que si se desean pasarcomo parmetro de salida, se debe pasar su direccin, a los punteros les

    Blog de programacin en C++ Builder http://datosoft.com/BlogCBuilder.htm#recorrerControlesForma

    5 de 7 09/01/2015 12:53 a. m.

  • Detectar dos instancias ejecutandose de una misma aplicacinPara evitar que haya dos instancias de una misma aplicacincorriendo:CreateMutex(NULL, false, GetExeName.c_str()); //GetExeNameest en clUtil// solo es correcto el nombre sin la extensin y sin pathif (ERROR_ALREADY_EXISTS==GetLastError()) {ShowMessage("Ya se est ejecutando el programa. Observe en labarra de tareas.");PostQuitMessage(0);}// Una forma general de manejar exceptions de todo tipo:try{Application->Initialize();Application->CreateForm(__classid(TDM), &DM);Application->CreateForm(__classid(TFrmMain), &FrmMain);Application->Run();}catch (Exception &exception){Application->ShowException(&exception);}catch (MyException &e) {Application->MessageBox(e.Mensaje(),"Error",MB_OK|MB_ICONHAND);}catch (...){// Por aca entran las C++ Exception.//WriteToFile("falla.txt", (String( itoa(i,Temp,10))+"\n").c_str());ShowMessage( String("An exception of type ") +__ThrowExceptionName()+ "\nwas thrown by line " + AnsiString(__ThrowLineNumber())+ "\nof file " + __ThrowFileName() );

    }

    return 0;}

    Como colocar una fecha en un control, con el formato del fechadel sistema:char BufDate[20];// Funcion del API para mostrar el formato de fecha del sistema, ej:mm/dd/yyyy::GetLocaleInfo(LOCALE_SYSTEM_DEFAULT,LOCALE_SSHORTDATE,BufDate,);TDateTime fTemp(GetAnioActual(), 12,31);edFechaVenc->Text=fTemp.FormatString(BufDate);

    ocurre lo mismo.

    bool buscar(int cod, struct biblioteca **anodo /*direccion de lavariable puntero*/) {bool Resultado= false;

    temp=lst;while(temp->sgte!=NULL) {if (temp->codigo==cod) {Resultado=true;*anodo= temp; // El contenido de Anodo es cambiadobreak;}temp=temp->sgte;}// Estamos en el ultimo nodoif(temp->codigo==cod) {Resultado= true;*anodo=temp;}return Resultado;}*/

    Blog de programacin en C++ Builder http://datosoft.com/BlogCBuilder.htm#recorrerControlesForma

    6 de 7 09/01/2015 12:53 a. m.

  • Blog de programacin en C++ Builder http://datosoft.com/BlogCBuilder.htm#recorrerControlesForma

    7 de 7 09/01/2015 12:53 a. m.