Parsowanie czasu

Parsowanie czasu
BO
  • Rejestracja:ponad 14 lat
  • Ostatnio:około rok
0

Chcę np. taki format czasu:
00:06:2
przeparsować na właściwy czyli:
00:06:02

lub z takiego:
00:06:71
na taki
00:07:11

Macie jakiś dobry pomysł na to?

DR
  • Rejestracja:prawie 12 lat
  • Ostatnio:około 4 godziny
  • Postów:1131
somedev
  • Rejestracja:prawie 7 lat
  • Ostatnio:prawie 5 lat
  • Postów:666
0

Ja bym dzielił na h m s, po czym napisał, funkcje na parsowanie każdej składowej. Funkcja wypluwała by ilość pełnych jednostek nadrzędnych (w przypadku m, nadrzędne to h), oraz resztę w jednostkach parsowanych. Po przeprasowaniu 3 składowych masz 6 składowe wynikowe - 1 składowa doby, 2-3 składowa godziny x2 , 4-5 składowa minuty x2. 6 składowa sekundy. Teraz musisz to posumować z pamięcią o przeniesieniach lub użyć czegoś w rodzaju klasy DateTime lub TimeSpan - ustawić na 00:00:00 i dodawać sekundy, potem minuty etc. W zasadzie to można zupełnie tą magię wyżej odpuścić i posplitować po dwukropku i dodawać do TimeSpana 00:00:00 sec, min, h bez parsowania tego i będzie. Pytanie czy masz to zrobić szybko, czy ma szybko działać, czy ma być elegancko zrobione. W zależności od potrzeby masz tutaj 2 rozwiązania, a trzeci było by wykluczeniem TimeSPana i ręczne napisanie funkcji do dodawania czasu, który będzie wypluwał coś ala TimeSpan, lub znów składowe z przeniesieniem (coś jak adder w logice cyfrowej).

edyta.

Podana funkcja wyżej jeśli jest gotowa i rozwiązuje problem, to o ile nie jest to problem akademicki jest lepszym rozwiązaniem.

edytowany 1x, ostatnio: somedev
BO
  • Rejestracja:ponad 14 lat
  • Ostatnio:około rok
0
Dregorio napisał(a):

Użyj https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
Mam coś takiego:

Kopiuj
DateTimeFormatter readFormatter = DateTimeFormatter.ofPattern("hh:mm:ss.SSS");
LocalTime parsedDate = LocalTime.parse("00:02:3", readFormatter);

i rzuca wyjątek w stylu: Text '00:02:3' could not be parsed at index 6

vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
1

Poprawiona wersja:

Kopiuj
import java.util.*;
import java.lang.*;
import java.io.*;
import java.time.LocalTime;
import java.time.format.*;

class Ideone
{
	public static void main (String[] args) throws java.lang.Exception
	{
		DateTimeFormatter readFormatter = DateTimeFormatter.ofPattern("H:m:s");
		LocalTime parsedDate = null;
		try {
		   parsedDate = LocalTime.parse("00:12:3", readFormatter);
		} catch(DateTimeParseException e) {
			System.out.println(e);
		}   
		System.out.print(parsedDate);
	}
}


Wynik: 00:12:03

https://ideone.com/tWznbc

edytowany 1x, ostatnio: vpiotr
YA
Kolega,oprócz parsowania, chciał mieć też jakąś logikę przetwarzającą, która poprawnie tłumaczyłaby np. "00:06:71", czyli pewnie jakiegoś splita trzeba zrobić i ręcznie powyliczać poprawne wartości. Pewnie wyjdą jakieś dodatkowe wymagania, np. co jak przekroczymy 24h, co jak przekroczymy 365/366 dni w roku itd. i pewnie zabije się o jakiś przypadek brzegowy. Przychylam się do wersji, która się wywali na niepoprawnym czasie :)
V-2
  • Rejestracja:około 8 lat
  • Ostatnio:10 miesięcy
  • Postów:671
3
boleq napisał(a):

lub z takiego:
00:06:71
na taki
00:07:11

Macie jakiś dobry pomysł na to?

Mój dobry pomysł byłby taki, żeby tego nie robić ;) Chyba, że nie masz na decyzję wpływu, bo jest to jakieś zadanie, albo tak się szef uparł, itp., ewentualnie forma ćwiczenia.

Praktycznego sensu w tym nie widzę. Jeśli człowiek wprowadził "06:71" błędnie, to jest mało prawdopodobne, że zrobił to, bo miał na myśli "07:11".

Jeśli coś jest trudne do zaimplementowania (w oparciu o biblioteki standardowe i ogólnodostępne, nawet w bogatym tzw. ekosystemie), to może istnieć ku temu całkiem niezły powód. Moim zdaniem tak jest w tym przypadku.


Nie ma najmniejszego powodu, aby w CV pisać "email" przed swoim adresem mailowym, "imię i nazwisko" przed imieniem i nazwiskiem, ani "zdjęcie mojej głowy od przedniej strony" obok ewentualnego zdjęcia. W drugiej firmie której już pracuję mam palących marihuanę programistów [...] piszą kod "leniwie", często nie wysilając się, rozwlekając ten kod, unikając np. programowania funkcyjnego (mówię tutaj o lambdach w javie).
edytowany 1x, ostatnio: V-2
BO
  • Rejestracja:ponad 14 lat
  • Ostatnio:około rok
0

ok próbowałem tak ale wtedy są problemy z;
Text '00:00:00.555' could not be parsed, unparsed text found at index 8

hcubyc
  • Rejestracja:ponad 12 lat
  • Ostatnio:prawie 3 lata
0
boleq napisał(a):

ok próbowałem tak ale wtedy są problemy z;
Text '00:00:00.555' could not be parsed, unparsed text found at index 8

bo formater miał przyjmowac godziny, minuty, sekundy, a ty mu dorzuciłeś do tego milisekundy. Generalnie jest wiele sposobów jak można ograć wiele różnych formatów zapisu czasu, ale najprostszy to walidacja tego co podaje użytkownik i jeżeli masz taką możliwość to tak rób i zaoszczędzisz sobie kodzenia. Zresztą wszystko nie tylko 'czas' warto walidować, bo im więcej użytkowników tym więcej głupich pomysłów i czasem prób 'hackowania' systemu


Limitations are limitless > ##### Ola Nordmann napisał(a)
> Moim językiem ojczystym jest C++ i proszę uszanować to, że piszę po polsku.
edytowany 2x, ostatnio: hcubyc
XY
  • Rejestracja:ponad 6 lat
  • Ostatnio:11 dni
  • Postów:259
0
V-2 napisał(a):

Jeśli coś jest trudne do zaimplementowania (w oparciu o biblioteki standardowe...

Co tu jest takie trudne? Wyrażenie regularne z grupami i jazda. Tak, wiem, wtedy będziesz miał 2 problemy, ale dla autora tego powiedzonka już i tak jesteś stracony, bo używasz Javy. ;)

edytowany 1x, ostatnio: xy
catom
  • Rejestracja:około 6 lat
  • Ostatnio:ponad 2 lata
  • Postów:58
1
xy napisał(a):

Co tu jest takie trudne? Wyrażenie regularne z grupami i jazda. Tak, wiem, wtedy będziesz miał 2 problemy, ale dla autora tego powiedzonka już i tak jesteś stracony, bo używasz Javy. ;)

Samo używanie regexów, do wydawałoby się, trywialnej operacji można już uznać za trudne.
@V-2 raczej chodziło o sam problem. Otrzymujemy dane w wielu różnych formatach, nie mówiąc o godzinach typu 6:71. Jeśli takie dane otrzymaliśmy i próbujemy je obsłużyć, to coś dziwnego dzieje się na wejściu i raczej wydawałoby się, że to tam należy sprawdzić, dlaczego tak się dzieje i uniemożliwić wprowadzanie nieprawidłowych dat.

No, chyba, że te daty, z jakiegoś powodu są w danej aplikacji prawidłowe, ale na to musi istnieć naprawdę dobre uzasadnienie.

I na tym skupia się @V-2 - dlaczego w ogóle uznajemy, że godzina 6:71 jest uznawana za prawidłową? Dlaczego wejście nie może nam zapewnić jakiegoś standardowego, znormalizowanego formatu daty? Może nie ma sensu wymyślać mechanizmu do obsługi czegoś, co jest błędne, tylko po prostu poprawić tamten błąd u źródła?
Już nawet nie skupiając się na tym konkretnym przypadku, zbyt często widziałem, jak developerzy wymyślali rozwiązania na jakiś swój konkretny problem, powstawały jakieś potworki, nikt nie chciał z danym systemem pracować, bo ma niewygodne API. Ale nikt nie pomyślał o tym, że to API można poprawić, uporządkować i sprawić, by praca z nim była przyjemna, dopóki jest jeszcze na to czas (np. nie utworzono jeszcze zbyt wielu zależności i można sobie pozwolić na drobny refaktor już istniejących).
Niestety, przez takie podejście task oriented, zbyt często rozwiązując swój problem, obchodzimy tylko realny, globalny problem, a potem napotykamy ten słynny technical debt.

Wracając do tematu OPa - oczywiście, pewnie najprościej obsłużyć to regexami z grupami (choć, czy najefektywniej? jakie rzeczywiście będą formaty danych? czy ktoś nie może sobie wprowadzić danych, które doprowadzą do zwiększenia obciążenia na potrzeby weryfikacji regexa i nie spowodują jakiegoś DoSa?),

Problem z regexami jest taki, że zaczynamy od jakiegoś prostego i naiwnego ^(?:(?:\d{1,2}-){2}(?:\d{2}|\d{4}))(?:[tT ](\d{1,2}:){2}(?:\d{1,2}))?$ potem robimy kilka "prostych" modyfikacji i powstają takie regexy jak ten:

Kopiuj
^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:Z|[+-][01]\d:[0-5]\d)$
edytowany 1x, ostatnio: catom
V-2
  • Rejestracja:około 8 lat
  • Ostatnio:10 miesięcy
  • Postów:671
3
xy napisał(a):
V-2 napisał(a):

Jeśli coś jest trudne do zaimplementowania (w oparciu o biblioteki standardowe...

Co tu jest takie trudne? Wyrażenie regularne z grupami i jazda.

Trudne do zaimplementowania w oparciu o biblioteki standardowe - napisałem przecież. Czyli "trudne" w tym sensie, że trudno jest wymusić na nich oczekiwane zachowanie, i praktycznie rzecz biorąc musimy je obchodzić, własną ścieżką. Np. w taki sposób jak podałeś. Już to powinno skłonić inżyniera do refleksji.

catom napisał(a):

@V-2 raczej chodziło o sam problem. Otrzymujemy dane w wielu różnych formatach, nie mówiąc o godzinach typu 6:71. Jeśli takie dane otrzymaliśmy i próbujemy je obsłużyć, to coś dziwnego dzieje się na wejściu i raczej wydawałoby się, że to tam należy sprawdzić, dlaczego tak się dzieje i uniemożliwić wprowadzanie nieprawidłowych dat.

Tak, między innymi o to mi chodzi. "Domyślny" system, który po cichu poprawia nieprawidłowe dane, jest moim zdaniem gorszy, niż system prosty. Jeśli użytkownik wpisał (dajmy na to) czas okrążenia 1:77, to czy na pewno chodziło mu o 2:17? A może chciał raczej wpisać 1:7 (czyli 1:07), tylko mu rączka zadygotała?

- Mamo, wychodzę!
- Dobrze, o której wracasz? Obiad jest na drugą.
- Będę najpóźniej na dwunastą dziewięćdziesiąt!
- Trzynastą trzydzieści, tak?
- O w mordę, no tak, znowu się przejęzyczyłem - zafrasował się autor tego pomysłu (w epoce dziecięcej beztroski jeszcze).
- Co ja ci mówiłam o wyrażeniach regularnych - oburzyła się matka. I słusznie się oburzyła


Nie ma najmniejszego powodu, aby w CV pisać "email" przed swoim adresem mailowym, "imię i nazwisko" przed imieniem i nazwiskiem, ani "zdjęcie mojej głowy od przedniej strony" obok ewentualnego zdjęcia. W drugiej firmie której już pracuję mam palących marihuanę programistów [...] piszą kod "leniwie", często nie wysilając się, rozwlekając ten kod, unikając np. programowania funkcyjnego (mówię tutaj o lambdach w javie).
edytowany 3x, ostatnio: V-2

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.