style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

Operaciones con tiempo (ejercicio)

TL;DR

Escribir un programa en la línea de comandos que reciba: ultima hora de entrada en formato hh:mm AM/PM (o 24hrs) y un total de horas trabajadas en la semana como número de punto flotante (1 hr y media se escribiría 1.50 ).

La salida debe de ser:

1) Cuántas horas se llevan trabajadas hasta el momento de la ejecución del programa sin importar el formato (eg. has trabajado 23.5 hrs o has trabajado 23h30m )
2) A que hora se habrá llegado al siguiente multiplicador de 8. ( eg puedes salir a las 5:58 pm )

Ejemplo de ejecución:

~ $ date
Thu Apr 16 17:50:26 CDT 2015
~ $ t 01:33pm 25.58
Tiempo transcurrido: 29h51m47.999725341s
Salida a las: 19:58

Version larga.

Una forma útil de aprender nuevas cosas es hacer aplicaciones pequeñas de utilería. En mi trabajo tengo reloj checador que me dice cuánto he trabajado pero no dice cuándo habré trabajado N hrs.

Ejemplo, si entro a las 9 am salgo de comer de 12 a 1 y ya son las 4 de la tarde el reloj de ve así:

regular 09:00am
regular 12:00pm     3hrs

comida 12:00pm
comida 01:00pm 

regular 01:00pm
regular 

Dice que he trabajado 3 hrs e intuitivamente yo sé que he trabajado 3 hrs más ( 1 pm a 4 pm son 3 ) y que me faltan 2 para cumplir las 8 al día ( 3 + 3 = 6 + 2 = 8 )

Hasta ahí todo bien, pero resulta que no siempre llego a la hora en punto ni me tardo una hora cerrada para comer, a veces se ve así:

regular 09:49am
regular 12:15pm     2.43hrs

comida 12:15pm
comida 01:24pm 

regular 01:24pm
regular 

Pero raramente hago check en la hora exacta, a veces son 1:24, a veces llevo 6.65 horas trabajadas y sumar fracciones es muy problemático

Mi reloj esta semana se ve así:

Así que hice un programa que si le paso la última marca (01:33pm como en la foto) y el total trabajado (25.58 hrs - alrededor 25hrs32min) me dice cuantas horas llevo trabajadas y cuando cumpliré el siguiente múltiplo de 8 (7:58 pm en este caso).

Les dejo este programa como ejercicio.

En Java 8 se agregó el paquete java.time que incorpora la biblioteca joda time a la biblioteca estándar de Java ( con algunas modificaciones ) se hizo para este tipo de cosas.

https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html

https://docs.oracle.com/javase/tutorial/datetime/overview/index.html

Saludos.

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Cid

???

Si es el cuarto día tendrías que tener 32 horas y si tu programa dice que a las 5:20 llevas un total de 29h51m para 32h te faltarían solo 2h9m si se lo sumas a 5:20 tu hora de salida daría algo así como 7h29m o no entendí

Otra cuestión ese programa solo se ejcutaría despues de que salgas a comer o de lo contrario tendriamos que colocar otros parametros para indicar la salida a comer no ?

Imagen de ezamudio

25.58

El 25.58 lo interpretas como 25 horas y 58% de una hora, o 25:58? O sea conviertes de base 10 a base 60 o tomas los decimales como minutos?

± 1 min. :-P

He aquí un código. No es tan «preciso» como el tuyo: ± 1 min. :-P

@SrCid, si asi es, si te

@SrCid, si asi es, te dice: Puedes salir a las 7:29 pm y estás a mano con las horas.

Y si, es correcto, solo tiene sentido ejecutarlo después de regresar de comer, pero también lo puedo ejecutar antes y pensar mentalmente que debo agregar una hora de comida a eso.

@ezamudio: Si, el punto si es como fracción "normal" ( en base 10 ), así que 25.50 es igual a 25:30 hrs (25h30m) en la salida no importa.

@jpaul Se ve mucho más

@jpaul Se ve mucho más sencillo de lo que me habría imaginado, te agregue comentarios en tu post.

Re: comentarios

Si pudiera conseguir algo de tiempo, quizás pueda integrar tus comentarios. Mientras tanto, dejaré esa pequeña satisfacción a alguien más si es que está interesado.

Imagen de Cid

Una implementación más

Esta muy sencilla y todavía proclive a errores, además de que solo acepta el formato de am y pm, no conozco nada de la API de TIme (Joda) pero bueno de algo sirvio hacer este ejercicio, tambien me falta ver lo del formato en que imprimo, no hice mucho caso de ello pero fue lo que pude hacer:

import java.time.Duration;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

public class TimeCalc {

        public static void main(String[] args) {

                if (args.length < 2){
                        System.out.println("Mode de uso: java TimeCalc hh:mmam/pm horastrabajadas");
                        System.out.println("Ejemplo: java TimeCalc 07:43pm 25.32");
                                        return;
                }

                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mma");
                LocalTime entrada = LocalTime.parse(args[0], formatter);
                // Horas trabajadas desde la ultima entrada
                LocalTime ahora = LocalTime.now();
                LocalTime horasEntrada = ahora.minusHours(entrada.getHour()).minusMinutes(entrada.getMinute());

                String[] horasTrabajadas = args[1].split("\\.");

                // Duración de la semana
                Duration transcurrido = Duration.ofHours(Long.valueOf(horasTrabajadas[0]));
                long minutes = (Long.valueOf(horasTrabajadas[1]) * 60) / 100;
                transcurrido = transcurrido.plusMinutes(minutes);

                // Sumatoria de la semana con las horas laboradas desde la ultima entrada
                Duration total;
                total = transcurrido.plusHours(horasEntrada.getHour());
                total = total.plusMinutes(horasEntrada.getMinute());
                total = total.plusSeconds(horasEntrada.getSecond());

                System.out.println("Tiempo transcurrido: " + total);

                Duration horasFaltantes = Duration.ofHours(0);
                for (int i = 8; i <= 40; i += 8){
                        horasFaltantes = calcularSalida(i, total);
                        if (horasFaltantes != null){
                                break;
                        }
                }

                LocalTime salida = ahora.plusHours(horasFaltantes.toHours());
                System.out.println("Salida a las " + salida);

        }

        public static Duration calcularSalida(int limite, Duration horasEfectivas) {
                long hora = horasEfectivas.toHours();
                Duration salida = (hora < limite) ? Duration.ofHours(limite).minus(horasEfectivas) : null;
                return salida;
        }

}

Espero sus comentarios, se que los habrá.

Gracias, saludos.

Re: comentarios

Oye, Oscar. Tuve unos minutos libres e integré tus comentarios. Puedes pasarle nuevamente tus herramient-it-as de análisis de código estático, pa' saber si hay algo más que «arreglar». :-)

import java.time.*;import

Este código resultó más breve que el que hice inicialmente ( en Go ) gracias al bien diseño del API de java.time.

.

.

.

import java.time.*;
import java.time.temporal.*;
import static java.time.temporal.ChronoUnit.*;
import java.text.*;

class T {
    private static final int HOURS_DAY = 8;
    private static final int MINS_HOUR = 60;
    public static void main( String ... args ) {

        LocalTime lastStamp = LocalTime.parse(args[0]);
        Double total = Double.parseDouble(args[1]);

        LocalTime now = LocalTime.now();
        double hoursElapsed = (total * MINS_HOUR + MINUTES.between(lastStamp,now)) / MINS_HOUR;
        double nextTarget = hoursElapsed - ( hoursElapsed % HOURS_DAY ) + HOURS_DAY;
        LocalTime endTime = now.plus((int)(( nextTarget - hoursElapsed ) * MINS_HOUR), MINUTES);
        System.out.printf("Total: %s%nSalida a las: %s", hoursElapsed, endTime);
    }
}

$ java T "13:31" 0.72
Total: 1.8199999999999998
Salida a las: 20:37:48.400

¿Total negativo?

 

Obtengo lo siguiente:

Total: -9.946666666666665
Salida a las: 19:50:27.157

Con que entrada? Al parecer

Con que entrada? Al parecer el default de LocalTime.parse() recibe formato 24 hrs. ,

Misma entrada.

① Misma entrada. Quizás diferente zona horaria. ② En efecto.

Imagen de Cid

duda

Ejecute el programa de tu solución y aunque fue a distinta hora solo cambiaría el total pero debería de decir misma hora de salida pero no la dio:

Total: 4.536666666666666
Salida a las: 20:20:52.481

esto a que se debe ?

Pruebas...

 

Aquí hay un perrito que ejecuta algunas pruebas para saber si es una puerta de cristal:

Glass door?

Clásico, quise quitar lineas

Clásico, quise quitar lineas a lo wey y reducir variables, cuando vi que no me salió lo regresé como estaba y olvidé unos paréntesis.

Esto:

now.plus((int)( nextTarget - hoursElapsed ) * MINS_HOUR, MINUTES);

debe de ser

now.plus((int)(( nextTarget - hoursElapsed ) * MINS_HOUR), MINUTES);

De otra forma trunca nextTarget - hoursElapse ( que son double ) antes de multiplicarlos por 60, entonces, digamos 16.0 - 12.5 me daba 3 en vez de 3.5

Pero ya está :P

Imagen de Cid

jajaja

Ya me dijo perro terco, jajaja.

Otra duda...

¡Todavía no está! :-P

Total: -11.28
Salida a las: 20:46:07.380
Total: -11.28
Salida a las: 20:46:34.935

Sólo por curiosidad, ¿debo salir en el segundo 07 o en el segundo 34?

En cualquier segundo de ese

En cualquier segundo de ese minuto.

Para mejores (y no tan ambiguos resultados)

 
System.out.printf("Total: %s%nSalida a las: %d:%d", elapsed, endTime.getHour(), endTime.getMinute());

Lo que no entiendo es por qué te salen totales negativos...

En cualquier segundo de ese

En cualquier segundo de ese minuto.

Para mejores (y no tan ambiguos resultados)

 
System.out.printf("Total: %s%nSalida a las: %d:%d",
    elapsed,
    endTime.getHour(),
    endTime.getMinute());

Lo que no entiendo es por qué te salen totales negativos...

Re: jajaja

 

Nope. No quise decir eso, sino que el canino se asegura de que no exista una puerta de cristal al frente. No es capaz de verla, pero sí es capaz de recordarla.

Perrito

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">