Introducere
Java 8 a introdus un nou API pentru date și timp în pachetul java.time. Acest API rezolvă multe probleme ale vechilor clase Date și Calendar, oferind o abordare mai intuitivă și thread-safe.
De ce să folosim noul API?
- Immutabilitate - obiectele sunt thread-safe
- API clar și intuitiv
- Suport pentru zone orare
- Calcule simple cu date
LocalDate - Lucrul cu Date
LocalDate reprezintă o dată fără timp și fără fus orar (ex: 2024-03-15).
Crearea unei Date
import java.time.LocalDate;
import java.time.Month;
// Data curentă
LocalDate astazi = LocalDate.now();
System.out.println("Astăzi: " + astazi);
// Dată specifică
LocalDate dataNasterii = LocalDate.of(1990, 5, 15);
System.out.println("Data nașterii: " + dataNasterii);
// Folosind enum Month
LocalDate craciun = LocalDate.of(2024, Month.DECEMBER, 25);
System.out.println("Crăciun: " + craciun);
// Parse din String
LocalDate dataText = LocalDate.parse("2024-03-15");
System.out.println("Din text: " + dataText);
Astăzi: 2024-03-15
Data nașterii: 1990-05-15
Crăciun: 2024-12-25
Din text: 2024-03-15
Extragerea Componentelor
LocalDate data = LocalDate.of(2024, 3, 15);
// Componente individuale
int an = data.getYear();
int luna = data.getMonthValue();
Month lunaEnum = data.getMonth();
int zi = data.getDayOfMonth();
int ziDinAn = data.getDayOfYear();
DayOfWeek ziDinSaptamana = data.getDayOfWeek();
System.out.println("An: " + an);
System.out.println("Luna: " + luna + " (" + lunaEnum + ")");
System.out.println("Zi: " + zi);
System.out.println("Ziua " + ziDinAn + " din an");
System.out.println("Zi din săptămână: " + ziDinSaptamana);
An: 2024
Luna: 3 (MARCH)
Zi: 15
Ziua 75 din an
Zi din săptămână: FRIDAY
Modificarea Datelor
LocalDate data = LocalDate.of(2024, 3, 15);
// Adăugare
LocalDate pesteSaptamana = data.plusWeeks(1);
LocalDate pesteOLuna = data.plusMonths(1);
LocalDate pesteUnAn = data.plusYears(1);
LocalDate peste45Zile = data.plusDays(45);
// Scădere
LocalDate acumOSaptamana = data.minusWeeks(1);
LocalDate acum3Luni = data.minusMonths(3);
// Modificare specifică
LocalDate primaDinLuna = data.withDayOfMonth(1);
LocalDate ultimaDinLuna = data.withDayOfMonth(data.lengthOfMonth());
System.out.println("Original: " + data);
System.out.println("Peste o săptămână: " + pesteSaptamana);
System.out.println("Prima zi din lună: " + primaDinLuna);
System.out.println("Ultima zi din lună: " + ultimaDinLuna);
LocalDateTime - Lucrul cu Date și Timp
LocalDateTime combină data și timpul fără fus orar.
Crearea LocalDateTime
import java.time.LocalDateTime;
import java.time.LocalTime;
// Data și ora curentă
LocalDateTime acum = LocalDateTime.now();
System.out.println("Acum: " + acum);
// Dată și oră specifică
LocalDateTime intalnire = LocalDateTime.of(2024, 3, 15, 14, 30, 0);
System.out.println("Întâlnire: " + intalnire);
// Combinare LocalDate cu LocalTime
LocalDate data = LocalDate.of(2024, 3, 15);
LocalTime ora = LocalTime.of(14, 30);
LocalDateTime combinat = LocalDateTime.of(data, ora);
System.out.println("Combinat: " + combinat);
// Parse din String
LocalDateTime parsed = LocalDateTime.parse("2024-03-15T14:30:00");
System.out.println("Parsed: " + parsed);
Operații cu LocalDateTime
LocalDateTime start = LocalDateTime.of(2024, 3, 15, 10, 0);
// Adăugare timp
LocalDateTime dupa2Ore = start.plusHours(2);
LocalDateTime dupa30Minute = start.plusMinutes(30);
LocalDateTime dupa3ZileSi4Ore = start.plusDays(3).plusHours(4);
// Truncare
LocalDateTime laOra = start.truncatedTo(ChronoUnit.HOURS);
LocalDateTime laMinut = start.truncatedTo(ChronoUnit.MINUTES);
System.out.println("Start: " + start);
System.out.println("După 2 ore: " + dupa2Ore);
System.out.println("După 3 zile și 4 ore: " + dupa3ZileSi4Ore);
System.out.println("Trunchiat la oră: " + laOra);
Formatare Date și Timp
DateTimeFormatter permite formatarea și parsarea flexibilă a datelor.
Formatare Standard
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
LocalDateTime dataOra = LocalDateTime.of(2024, 3, 15, 14, 30, 45);
// Formate predefinite
String iso = dataOra.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
String basic = dataOra.format(DateTimeFormatter.BASIC_ISO_DATE);
// Formate localizate
String scurt = dataOra.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT));
String mediu = dataOra.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM));
String lung = dataOra.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG));
System.out.println("ISO: " + iso);
System.out.println("Basic: " + basic);
System.out.println("Scurt: " + scurt);
System.out.println("Mediu: " + mediu);
Formatare Personalizată
LocalDateTime dataOra = LocalDateTime.now();
// Pattern-uri personalizate
DateTimeFormatter format1 = DateTimeFormatter.ofPattern("dd/MM/yyyy");
DateTimeFormatter format2 = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
DateTimeFormatter format3 = DateTimeFormatter.ofPattern("EEEE, d MMMM yyyy");
DateTimeFormatter format4 = DateTimeFormatter.ofPattern("HH:mm:ss dd.MM.yyyy");
DateTimeFormatter format5 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
System.out.println("Format 1: " + dataOra.format(format1));
System.out.println("Format 2: " + dataOra.format(format2));
System.out.println("Format 3: " + dataOra.format(format3));
System.out.println("Format 4: " + dataOra.format(format4));
System.out.println("Format 5: " + dataOra.format(format5));
Tabel Pattern-uri Comune
| Pattern | Descriere | Exemplu |
|---|---|---|
| y | An | 2024 |
| M | Luna în an | 3 sau 03 |
| MMM | Luna abreviată | Mar |
| MMMM | Luna completă | Martie |
| d | Zi în lună | 15 |
| E | Zi în săptămână | Vin |
| EEEE | Zi completă | Vineri |
| H | Ora (0-23) | 14 |
| h | Ora (1-12) | 2 |
| m | Minut | 30 |
| s | Secundă | 45 |
| a | AM/PM | PM |
Parsare cu Format
// Parsare cu format specific
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
String dataText = "15/03/2024 14:30";
LocalDateTime parsed = LocalDateTime.parse(dataText, formatter);
System.out.println("Parsed: " + parsed);
// Parsare flexibilă
DateTimeFormatter flexibil = DateTimeFormatter.ofPattern("[dd/MM/yyyy][dd-MM-yyyy]");
LocalDate data1 = LocalDate.parse("15/03/2024", flexibil);
LocalDate data2 = LocalDate.parse("15-03-2024", flexibil);
// Parsare cu locale specific
DateTimeFormatter romanesc = DateTimeFormatter.ofPattern("d MMMM yyyy", new Locale("ro", "RO"));
LocalDate dataRo = LocalDate.parse("15 martie 2024", romanesc);
System.out.println("Data RO: " + dataRo);
Operații Avansate
Calcularea Perioadelor
import java.time.Period;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
// Period - pentru date
LocalDate nastere = LocalDate.of(1990, 5, 15);
LocalDate astazi = LocalDate.now();
Period varsta = Period.between(nastere, astazi);
System.out.println("Vârstă: " + varsta.getYears() + " ani, " +
varsta.getMonths() + " luni, " +
varsta.getDays() + " zile");
// Duration - pentru timp
LocalDateTime start = LocalDateTime.of(2024, 3, 15, 10, 0);
LocalDateTime end = LocalDateTime.of(2024, 3, 15, 14, 30);
Duration durata = Duration.between(start, end);
System.out.println("Durată: " + durata.toHours() + " ore și " +
durata.toMinutesPart() + " minute");
// ChronoUnit pentru calcule specifice
long zile = ChronoUnit.DAYS.between(nastere, astazi);
long ore = ChronoUnit.HOURS.between(start, end);
System.out.println("Total zile de la naștere: " + zile);
System.out.println("Total ore: " + ore);
Ajustări Temporale
import java.time.temporal.TemporalAdjusters;
import java.time.DayOfWeek;
LocalDate data = LocalDate.of(2024, 3, 15);
// Prima/ultima zi din lună
LocalDate primaZi = data.with(TemporalAdjusters.firstDayOfMonth());
LocalDate ultimaZi = data.with(TemporalAdjusters.lastDayOfMonth());
// Prima/ultima zi din an
LocalDate primaZiAn = data.with(TemporalAdjusters.firstDayOfYear());
LocalDate ultimaZiAn = data.with(TemporalAdjusters.lastDayOfYear());
// Următoarea zi specifică
LocalDate urmatorulVineri = data.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
LocalDate urmatorulSauAcestaVineri = data.with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY));
// Prima zi de luni din lună
LocalDate primaLuni = data.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
LocalDate ultimaLuni = data.with(TemporalAdjusters.lastInMonth(DayOfWeek.MONDAY));
System.out.println("Data originală: " + data);
System.out.println("Prima zi din lună: " + primaZi);
System.out.println("Ultima zi din lună: " + ultimaZi);
System.out.println("Următorul vineri: " + urmatorulVineri);
System.out.println("Prima luni din lună: " + primaLuni);
Comparații între Date
LocalDate data1 = LocalDate.of(2024, 3, 15);
LocalDate data2 = LocalDate.of(2024, 3, 20);
LocalDate data3 = LocalDate.of(2024, 3, 15);
// Comparații de bază
boolean esteInainte = data1.isBefore(data2);
boolean esteDupa = data1.isAfter(data2);
boolean esteEgal = data1.isEqual(data3);
System.out.println(data1 + " este înainte de " + data2 + "? " + esteInainte);
System.out.println(data1 + " este după " + data2 + "? " + esteDupa);
System.out.println(data1 + " este egal cu " + data3 + "? " + esteEgal);
// Comparație cu compareTo
int comparatie = data1.compareTo(data2);
if (comparatie < 0) {
System.out.println(data1 + " este mai devreme");
} else if (comparatie > 0) {
System.out.println(data1 + " este mai târziu");
} else {
System.out.println("Datele sunt egale");
}
// Verificare an bisect
boolean bisect = Year.of(2024).isLeap();
System.out.println("2024 este an bisect? " + bisect);
Conversii și Integrare
Conversii între Tipuri
// LocalDate -> LocalDateTime
LocalDate data = LocalDate.of(2024, 3, 15);
LocalDateTime dataOraStart = data.atStartOfDay();
LocalDateTime dataOraCustom = data.atTime(14, 30);
LocalDateTime dataOraTime = data.atTime(LocalTime.of(14, 30, 0));
// LocalDateTime -> LocalDate/LocalTime
LocalDateTime dataOra = LocalDateTime.now();
LocalDate doar Data = dataOra.toLocalDate();
LocalTime doarOra = dataOra.toLocalTime();
// Conversie cu Date (legacy)
Date oldDate = new Date();
LocalDateTime fromOldDate = LocalDateTime.ofInstant(
oldDate.toInstant(), ZoneId.systemDefault()
);
// LocalDateTime -> Date
LocalDateTime ldt = LocalDateTime.now();
Date toOldDate = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
System.out.println("LocalDate: " + data);
System.out.println("La început de zi: " + dataOraStart);
System.out.println("La ora specifică: " + dataOraCustom);
Exemple Practice
Calculator Vârstă
public static int calculeazaVarsta(LocalDate dataNasterii) {
return Period.between(dataNasterii, LocalDate.now()).getYears();
}
// Utilizare
LocalDate nastere = LocalDate.of(1990, 5, 15);
int varsta = calculeazaVarsta(nastere);
System.out.println("Vârsta: " + varsta + " ani");
Zile Lucrătoare
public static long zileLucratoare(LocalDate start, LocalDate end) {
return start.datesUntil(end)
.filter(data -> {
DayOfWeek zi = data.getDayOfWeek();
return zi != DayOfWeek.SATURDAY && zi != DayOfWeek.SUNDAY;
})
.count();
}
// Utilizare
LocalDate inceput = LocalDate.of(2024, 3, 1);
LocalDate sfarsit = LocalDate.of(2024, 3, 31);
long zile = zileLucratoare(inceput, sfarsit);
System.out.println("Zile lucrătoare: " + zile);
Următoarea Zi de Plată
public static LocalDate urmatoareaPlata(int ziuaDinLuna) {
LocalDate azi = LocalDate.now();
LocalDate plata = azi.withDayOfMonth(
Math.min(ziuaDinLuna, azi.lengthOfMonth())
);
if (plata.isBefore(azi) || plata.isEqual(azi)) {
plata = plata.plusMonths(1);
plata = plata.withDayOfMonth(
Math.min(ziuaDinLuna, plata.lengthOfMonth())
);
}
return plata;
}
// Utilizare
LocalDate plata = urmatoareaPlata(25);
System.out.println("Următoarea plată: " + plata);
Formatare Avansată - Exemple Multiple
LocalDateTime acum = LocalDateTime.now();
// Formatări pentru diferite scopuri
Map formate = new HashMap<>();
formate.put("Log", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
formate.put("Factura", DateTimeFormatter.ofPattern("dd.MM.yyyy"));
formate.put("Email", DateTimeFormatter.ofPattern("EEEE, d MMMM yyyy 'la ora' HH:mm"));
formate.put("API", DateTimeFormatter.ISO_LOCAL_DATE_TIME);
formate.put("Filename", DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
formate.put("Raport", DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"));
formate.put("Simplu", DateTimeFormatter.ofPattern("dd-MM-yyyy"));
formate.put("Complet", DateTimeFormatter.ofPattern("EEEE, d MMMM yyyy HH:mm:ss"));
System.out.println("Exemple de formatare pentru: " + acum);
System.out.println("-".repeat(50));
formate.forEach((nume, formatter) -> {
System.out.println(nume + ": " + acum.format(formatter));
});
Atenție la Timezone!
LocalDate și LocalDateTime nu conțin informații despre fus orar. Pentru lucrul cu fusuri orare, folosiți ZonedDateTime.
Validare Date
public static boolean esteDataValida(String data, String format) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
LocalDate.parse(data, formatter);
return true;
} catch (DateTimeParseException e) {
return false;
}
}
// Exemple de utilizare
String[] dateTest = {"29/02/2024", "30/02/2024", "31/04/2024", "15/03/2024"};
String format = "dd/MM/yyyy";
for (String data : dateTest) {
boolean valida = esteDataValida(data, format);
System.out.println(data + " este validă? " + valida);
}
Lucrul cu Sărbători
public class CalculatorSarbatori {
private static final Map SARBATORI = Map.of(
MonthDay.of(1, 1), "Anul Nou",
MonthDay.of(5, 1), "Ziua Muncii",
MonthDay.of(12, 25), "Crăciun",
MonthDay.of(12, 26), "A doua zi de Crăciun"
);
public static boolean esteSarbatoare(LocalDate data) {
return SARBATORI.containsKey(MonthDay.from(data));
}
public static String numeSarbatoare(LocalDate data) {
return SARBATORI.getOrDefault(MonthDay.from(data), "Zi normală");
}
public static LocalDate urmatoareaSarbatoare(LocalDate de la) {
return SARBATORI.keySet().stream()
.map(md -> md.atYear(de la.getYear()))
.filter(data -> data.isAfter(de la))
.min(LocalDate::compareTo)
.orElse(SARBATORI.keySet().stream()
.map(md -> md.atYear(de la.getYear() + 1))
.min(LocalDate::compareTo)
.orElse(null));
}
}
// Utilizare
LocalDate azi = LocalDate.now();
System.out.println("Este sărbătoare azi? " + CalculatorSarbatori.esteSarbatoare(azi));
LocalDate urmatoarea = CalculatorSarbatori.urmatoareaSarbatoare(azi);
System.out.println("Următoarea sărbătoare: " + urmatoarea);
Generator Calendar
public static void afiseazaCalendar(int an, int luna) {
YearMonth lunaAn = YearMonth.of(an, luna);
LocalDate primaZi = lunaAn.atDay(1);
LocalDate ultimaZi = lunaAn.atEndOfMonth();
System.out.println("\n" + lunaAn.getMonth() + " " + an);
System.out.println("Lu Ma Mi Jo Vi Sâ Du");
// Spații pentru prima săptămână
int spatii = primaZi.getDayOfWeek().getValue() - 1;
for (int i = 0; i < spatii; i++) {
System.out.print(" ");
}
// Afișare zile
LocalDate data = primaZi;
while (!data.isAfter(ultimaZi)) {
System.out.printf("%2d ", data.getDayOfMonth());
if (data.getDayOfWeek() == DayOfWeek.SUNDAY) {
System.out.println();
}
data = data.plusDays(1);
}
System.out.println();
}
// Utilizare
afiseazaCalendar(2024, 3);
Best Practices:
- Folosiți întotdeauna noul API (java.time) în loc de Date/Calendar
- Preferați LocalDate/LocalDateTime pentru majoritatea cazurilor
- Folosiți ZonedDateTime doar când aveți nevoie de timezone
- Creați constante pentru formatele folosite frecvent
- Tratați întotdeauna excepțiile de parsare
- Folosiți Period pentru diferențe între date, Duration pentru timp
Exemple Complexe de Formatare
// Formatare cu Locale diferite
LocalDateTime data = LocalDateTime.now();
Locale[] locales = {
Locale.US,
Locale.FRANCE,
Locale.GERMANY,
new Locale("ro", "RO")
};
for (Locale locale : locales) {
DateTimeFormatter formatter = DateTimeFormatter
.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.SHORT)
.withLocale(locale);
System.out.println(locale.getDisplayName() + ": " + data.format(formatter));
}
// Formatare customizată cu text
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern(
"'Data:' dd MMMM yyyy 'Ora:' HH:mm:ss"
);
System.out.println(data.format(customFormatter));
// Formatare condiționată
DateTimeFormatter smartFormatter = new DateTimeFormatterBuilder()
.appendPattern("dd/MM/yyyy")
.optionalStart()
.appendPattern(" HH:mm")
.optionalEnd()
.toFormatter();
LocalDate doar Data = LocalDate.now();
LocalDateTime dataOra = LocalDateTime.now();
System.out.println("Doar data: " + doarData.format(smartFormatter));
System.out.println("Data și ora: " + dataOra.format(smartFormatter));
Utilități Practice
public class DateTimeUtils {
// Verifică dacă o dată este în weekend
public static boolean esteWeekend(LocalDate data) {
DayOfWeek zi = data.getDayOfWeek();
return zi == DayOfWeek.SATURDAY || zi == DayOfWeek.SUNDAY;
}
// Calculează următoarea zi lucrătoare
public static LocalDate urmatoareaZiLucratoare(LocalDate data) {
LocalDate rezultat = data;
do {
rezultat = rezultat.plusDays(1);
} while (esteWeekend(rezultat));
return rezultat;
}
// Găsește toate zilele de vineri dintr-o lună
public static List toateVinerile(YearMonth luna) {
List vineri = new ArrayList<>();
LocalDate data = luna.atDay(1);
LocalDate ultima = luna.atEndOfMonth();
// Găsește prima vineri
data = data.with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY));
while (!data.isAfter(ultima)) {
vineri.add(data);
data = data.plusWeeks(1);
}
return vineri;
}
// Calculează timpul rămas până la un eveniment
public static String timpRamas(LocalDateTime eveniment) {
LocalDateTime acum = LocalDateTime.now();
if (eveniment.isBefore(acum)) {
return "Evenimentul a trecut";
}
Duration durata = Duration.between(acum, eveniment);
long zile = durata.toDays();
long ore = durata.toHoursPart();
long minute = durata.toMinutesPart();
return String.format("%d zile, %d ore, %d minute", zile, ore, minute);
}
}
// Exemple de utilizare
LocalDate azi = LocalDate.now();
System.out.println("Este weekend? " + DateTimeUtils.esteWeekend(azi));
System.out.println("Următoarea zi lucrătoare: " +
DateTimeUtils.urmatoareaZiLucratoare(azi));
YearMonth lunaCurenta = YearMonth.now();
System.out.println("Vineri în această lună: " +
DateTimeUtils.toateVinerile(lunaCurenta));
LocalDateTime eveniment = LocalDateTime.of(2024, 12, 25, 0, 0);
System.out.println("Timp până la Crăciun: " +
DateTimeUtils.timpRamas(eveniment));
Exemple Avansate și Cazuri Reale
Sistem de Rezervări
public class SistemRezervari {
private static final LocalTime ORA_DESCHIDERE = LocalTime.of(9, 0);
private static final LocalTime ORA_INCHIDERE = LocalTime.of(18, 0);
private static final Duration DURATA_SLOT = Duration.ofMinutes(30);
public static List getSloturiDisponibile(LocalDate data) {
List sloturi = new ArrayList<>();
LocalDateTime start = data.atTime(ORA_DESCHIDERE);
LocalDateTime end = data.atTime(ORA_INCHIDERE);
while (start.isBefore(end)) {
if (!esteWeekend(start.toLocalDate())) {
sloturi.add(start);
}
start = start.plus(DURATA_SLOT);
}
return sloturi;
}
public static boolean esteSlotValid(LocalDateTime slot) {
LocalTime ora = slot.toLocalTime();
return !ora.isBefore(ORA_DESCHIDERE) &&
!ora.isAfter(ORA_INCHIDERE.minus(DURATA_SLOT)) &&
!esteWeekend(slot.toLocalDate()) &&
slot.isAfter(LocalDateTime.now());
}
private static boolean esteWeekend(LocalDate data) {
DayOfWeek zi = data.getDayOfWeek();
return zi == DayOfWeek.SATURDAY || zi == DayOfWeek.SUNDAY;
}
}
// Utilizare
LocalDate maine = LocalDate.now().plusDays(1);
List sloturi = SistemRezervari.getSloturiDisponibile(maine);
System.out.println("Sloturi disponibile pentru " + maine + ":");
sloturi.forEach(slot -> System.out.println(
slot.format(DateTimeFormatter.ofPattern("HH:mm"))
));
Calculator Rate și Scadențe
public class CalculatorRate {
public static List genereazaScadente(
LocalDate dataStart, int numarRate, String frecventa) {
List scadente = new ArrayList<>();
LocalDate data = dataStart;
for (int i = 0; i < numarRate; i++) {
switch (frecventa.toLowerCase()) {
case "lunar":
data = data.plusMonths(1);
break;
case "trimestrial":
data = data.plusMonths(3);
break;
case "semestrial":
data = data.plusMonths(6);
break;
case "anual":
data = data.plusYears(1);
break;
case "saptamanal":
data = data.plusWeeks(1);
break;
}
// Ajustare pentru weekend
if (data.getDayOfWeek() == DayOfWeek.SATURDAY) {
data = data.plusDays(2);
} else if (data.getDayOfWeek() == DayOfWeek.SUNDAY) {
data = data.plusDays(1);
}
scadente.add(data);
}
return scadente;
}
public static Map analizeazaScadente(List scadente) {
Map analiza = new HashMap<>();
LocalDate azi = LocalDate.now();
long scadenteRestante = scadente.stream()
.filter(data -> data.isBefore(azi))
.count();
Optional urmatoareaScadenta = scadente.stream()
.filter(data -> !data.isBefore(azi))
.findFirst();
long zileRamase = urmatoareaScadenta
.map(data -> ChronoUnit.DAYS.between(azi, data))
.orElse(-1L);
analiza.put("scadenteRestante", scadenteRestante);
analiza.put("urmatoareaScadenta", urmatoareaScadenta.orElse(null));
analiza.put("zileRamase", zileRamase);
analiza.put("totalScadente", scadente.size());
return analiza;
}
}
// Utilizare
LocalDate start = LocalDate.of(2024, 1, 15);
List scadente = CalculatorRate.genereazaScadente(start, 12, "lunar");
Map analiza = CalculatorRate.analizeazaScadente(scadente);
System.out.println("Analiza scadențe:");
analiza.forEach((key, value) -> System.out.println(key + ": " + value));
Planificator Evenimente Recurente
public class PlanificatorEvenimente {
public enum TipRecurenta {
ZILNIC, SAPTAMANAL, LUNAR, ANUAL, ZILE_LUCRATOARE
}
public static List genereazaEvenimente(
LocalDateTime start,
TipRecurenta tip,
int numarAparitii,
Set zileSelectate) {
List evenimente = new ArrayList<>();
LocalDateTime current = start;
int contor = 0;
while (contor < numarAparitii) {
switch (tip) {
case ZILNIC:
evenimente.add(current);
current = current.plusDays(1);
contor++;
break;
case SAPTAMANAL:
if (zileSelectate == null || zileSelectate.contains(current.getDayOfWeek())) {
evenimente.add(current);
contor++;
}
current = current.plusDays(1);
break;
case LUNAR:
evenimente.add(current);
current = current.plusMonths(1);
// Ajustare pentru ultima zi din lună
if (current.getDayOfMonth() != start.getDayOfMonth()) {
current = current.withDayOfMonth(
Math.min(start.getDayOfMonth(),
current.toLocalDate().lengthOfMonth())
);
}
contor++;
break;
case ANUAL:
evenimente.add(current);
current = current.plusYears(1);
contor++;
break;
case ZILE_LUCRATOARE:
DayOfWeek zi = current.getDayOfWeek();
if (zi != DayOfWeek.SATURDAY && zi != DayOfWeek.SUNDAY) {
evenimente.add(current);
contor++;
}
current = current.plusDays(1);
break;
}
}
return evenimente;
}
public static String genereazaDescriere(List evenimente) {
if (evenimente.isEmpty()) return "Nu există evenimente";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
StringBuilder sb = new StringBuilder();
sb.append("Serie de ").append(evenimente.size()).append(" evenimente:\n");
sb.append("Prima dată: ").append(evenimente.get(0).format(formatter)).append("\n");
sb.append("Ultima dată: ").append(evenimente.get(evenimente.size()-1).format(formatter)).append("\n");
// Calculare interval mediu
if (evenimente.size() > 1) {
Duration totalDuration = Duration.between(
evenimente.get(0),
evenimente.get(evenimente.size()-1)
);
long intervalMediu = totalDuration.toDays() / (evenimente.size() - 1);
sb.append("Interval mediu: ").append(intervalMediu).append(" zile");
}
return sb.toString();
}
}
// Exemple de utilizare
LocalDateTime startMeeting = LocalDateTime.of(2024, 3, 15, 10, 0);
// Evenimente zilnice
List zilnic = PlanificatorEvenimente.genereazaEvenimente(
startMeeting, TipRecurenta.ZILNIC, 7, null
);
// Evenimente săptămânale (luni și joi)
Set zileSelectate = Set.of(DayOfWeek.MONDAY, DayOfWeek.THURSDAY);
List saptamanal = PlanificatorEvenimente.genereazaEvenimente(
startMeeting, TipRecurenta.SAPTAMANAL, 8, zileSelectate
);
System.out.println(PlanificatorEvenimente.genereazaDescriere(zilnic));
System.out.println(PlanificatorEvenimente.genereazaDescriere(saptamanal));
Analizator Log-uri cu Timestamp
public class AnalizatorLoguri {
public static class EntryLog {
LocalDateTime timestamp;
String nivel;
String mesaj;
public EntryLog(String linie) {
// Format: 2024-03-15 14:30:45.123 [ERROR] Mesaj eroare
String[] parti = linie.split(" ", 4);
this.timestamp = LocalDateTime.parse(
parti[0] + "T" + parti[1].substring(0, 8)
);
this.nivel = parti[2].replace("[", "").replace("]", "");
this.mesaj = parti[3];
}
}
public static Map analizeazaLoguri(List linii) {
List loguri = linii.stream()
.map(EntryLog::new)
.collect(Collectors.toList());
Map rezultat = new HashMap<>();
// Grupare pe nivel
Map peNivel = loguri.stream()
.collect(Collectors.groupingBy(
log -> log.nivel,
Collectors.counting()
));
// Grupare pe oră
Map peOra = loguri.stream()
.collect(Collectors.groupingBy(
log -> log.timestamp.getHour(),
Collectors.counting()
));
// Găsire perioade cu multe erori
List perioadeProblematice = new ArrayList<>();
for (int i = 0; i < loguri.size() - 10; i++) {
List fereastra = loguri.subList(i, i + 10);
long erori = fereastra.stream()
.filter(log -> "ERROR".equals(log.nivel))
.count();
if (erori > 5) {
perioadeProblematice.add(fereastra.get(0).timestamp);
}
}
// Calculare timp mediu între erori
List timpuriErori = loguri.stream()
.filter(log -> "ERROR".equals(log.nivel))
.map(log -> log.timestamp)
.sorted()
.collect(Collectors.toList());
Duration timpMediuIntreErori = null;
if (timpuriErori.size() > 1) {
long totalMinute = 0;
for (int i = 1; i < timpuriErori.size(); i++) {
totalMinute += Duration.between(
timpuriErori.get(i-1),
timpuriErori.get(i)
).toMinutes();
}
timpMediuIntreErori = Duration.ofMinutes(
totalMinute / (timpuriErori.size() - 1)
);
}
rezultat.put("totalLoguri", loguri.size());
rezultat.put("distributieNivel", peNivel);
rezultat.put("distributieOra", peOra);
rezultat.put("perioadeProblematice", perioadeProblematice);
rezultat.put("timpMediuIntreErori", timpMediuIntreErori);
return rezultat;
}
}
// Exemplu de utilizare
List loguri = Arrays.asList(
"2024-03-15 14:30:45.123 [INFO] Aplicație pornită",
"2024-03-15 14:31:12.456 [ERROR] Conexiune eșuată",
"2024-03-15 14:31:15.789 [ERROR] Reîncercare conexiune",
"2024-03-15 14:32:00.123 [INFO] Conexiune restabilită",
"2024-03-15 14:35:30.456 [WARNING] Memorie aproape plină"
);
Map analiza = AnalizatorLoguri.analizeazaLoguri(loguri);
analiza.forEach((key, value) -> System.out.println(key + ": " + value));
Manager Timezone-uri
import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
public class ManagerTimezone {
public static void afiseazaOraInMultipleTimezone(LocalDateTime ora) {
List timezones = Arrays.asList(
"Europe/Bucharest",
"Europe/London",
"America/New_York",
"Asia/Tokyo",
"Australia/Sydney"
);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
"dd/MM/yyyy HH:mm:ss z"
);
System.out.println("Ora locală: " + ora);
System.out.println("-".repeat(50));
for (String tzId : timezones) {
ZoneId zone = ZoneId.of(tzId);
ZonedDateTime zdtLocal = ora.atZone(ZoneId.systemDefault());
ZonedDateTime zdtTarget = zdtLocal.withZoneSameInstant(zone);
System.out.printf("%-20s: %s%n",
zone.getId(),
zdtTarget.format(formatter)
);
}
}
public static Duration diferentaFusOrar(String timezone1, String timezone2) {
ZonedDateTime now1 = ZonedDateTime.now(ZoneId.of(timezone1));
ZonedDateTime now2 = ZonedDateTime.now(ZoneId.of(timezone2));
return Duration.between(
now1.toLocalDateTime(),
now2.toLocalDateTime()
);
}
public static LocalDateTime convertesteIntreFusuri(
LocalDateTime ora, String fusOrigine, String fusDestinatie) {
ZonedDateTime zdtOrigine = ora.atZone(ZoneId.of(fusOrigine));
ZonedDateTime zdtDestinatie = zdtOrigine.withZoneSameInstant(
ZoneId.of(fusDestinatie)
);
return zdtDestinatie.toLocalDateTime();
}
}
// Utilizare
LocalDateTime meeting = LocalDateTime.of(2024, 3, 15, 14, 0);
ManagerTimezone.afiseazaOraInMultipleTimezone(meeting);
Duration diferenta = ManagerTimezone.diferentaFusOrar(
"Europe/Bucharest",
"America/New_York"
);
System.out.println("\nDiferența de fus: " + diferenta.toHours() + " ore");
LocalDateTime oraNewYork = ManagerTimezone.convertesteIntreFusuri(
meeting, "Europe/Bucharest", "America/New_York"
);
System.out.println("Ora în New York: " + oraNewYork);
Generator Rapoarte Periodice
public class GeneratorRapoarte {
public static class PerioadaRaport {
LocalDate inceput;
LocalDate sfarsit;
String tip;
public PerioadaRaport(LocalDate inceput, LocalDate sfarsit, String tip) {
this.inceput = inceput;
this.sfarsit = sfarsit;
this.tip = tip;
}
public String toString() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
return String.format("%s: %s - %s",
tip,
inceput.format(formatter),
sfarsit.format(formatter)
);
}
}
public static List genereazaPerioadeRaport(
int an, String tipRaport) {
List perioade = new ArrayList<>();
switch (tipRaport.toLowerCase()) {
case "lunar":
for (int luna = 1; luna <= 12; luna++) {
YearMonth ym = YearMonth.of(an, luna);
perioade.add(new PerioadaRaport(
ym.atDay(1),
ym.atEndOfMonth(),
ym.getMonth().toString()
));
}
break;
case "trimestrial":
for (int trim = 0; trim < 4; trim++) {
LocalDate inceput = LocalDate.of(an, trim * 3 + 1, 1);
LocalDate sfarsit = inceput.plusMonths(3).minusDays(1);
perioade.add(new PerioadaRaport(
inceput,
sfarsit,
"Trimestrul " + (trim + 1)
));
}
break;
case "saptamanal":
LocalDate start = LocalDate.of(an, 1, 1);
// Ajustare la luni
start = start.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
LocalDate end = LocalDate.of(an, 12, 31);
int saptamana = 1;
while (start.isBefore(end)) {
LocalDate sfarsitSapt = start.plusDays(6);
if (sfarsitSapt.isAfter(end)) sfarsitSapt = end;
perioade.add(new PerioadaRaport(
start,
sfarsitSapt,
"Săptămâna " + saptamana
));
start = start.plusWeeks(1);
saptamana++;
}
break;
}
return perioade;
}
public static Map statisticiPerioada(
LocalDate inceput, LocalDate sfarsit) {
Map stats = new HashMap<>();
long zileTotale = ChronoUnit.DAYS.between(inceput, sfarsit) + 1;
long zileLucratoare = inceput.datesUntil(sfarsit.plusDays(1))
.filter(data -> {
DayOfWeek zi = data.getDayOfWeek();
return zi != DayOfWeek.SATURDAY && zi != DayOfWeek.SUNDAY;
})
.count();
long weekenduri = zileTotale - zileLucratoare;
long saptamaniComplete = zileTotale / 7;
stats.put("zileTotale", zileTotale);
stats.put("zileLucratoare", zileLucratoare);
stats.put("weekenduri", weekenduri);
stats.put("saptamaniComplete", saptamaniComplete);
return stats;
}
}
// Utilizare
List rapoarteTrim = GeneratorRapoarte.genereazaPerioadeRaport(
2024, "trimestrial"
);
rapoarteTrim.forEach(System.out::println);
System.out.println("\nStatistici Q1 2024:");
Map stats = GeneratorRapoarte.statisticiPerioada(
LocalDate.of(2024, 1, 1),
LocalDate.of(2024, 3, 31)
);
stats.forEach((key, value) -> System.out.println(key + ": " + value));
Calculator Business Days cu Sărbători
public class BusinessDayCalculator {
private static final Set SARBATORI_2024 = Set.of(
LocalDate.of(2024, 1, 1), // Anul Nou
LocalDate.of(2024, 1, 2), // A doua zi
LocalDate.of(2024, 4, 28), // Paște Ortodox
LocalDate.of(2024, 4, 29), // A doua zi de Paște
LocalDate.of(2024, 5, 1), // Ziua Muncii
LocalDate.of(2024, 6, 16), // Rusalii
LocalDate.of(2024, 6, 17), // A doua zi
LocalDate.of(2024, 8, 15), // Adormirea Maicii Domnului
LocalDate.of(2024, 11, 30), // Sf. Andrei
LocalDate.of(2024, 12, 1), // Ziua Națională
LocalDate.of(2024, 12, 25), // Crăciun
LocalDate.of(2024, 12, 26) // A doua zi
);
public static boolean esteZiLucratoare(LocalDate data) {
DayOfWeek zi = data.getDayOfWeek();
return zi != DayOfWeek.SATURDAY &&
zi != DayOfWeek.SUNDAY &&
!SARBATORI_2024.contains(data);
}
public static LocalDate adaugaZileLucratoare(LocalDate start, int zile) {
LocalDate rezultat = start;
int zileAdaugate = 0;
while (zileAdaugate < zile) {
rezultat = rezultat.plusDays(1);
if (esteZiLucratoare(rezultat)) {
zileAdaugate++;
}
}
return rezultat;
}
public static long calculeazaZileLucratoare(
LocalDate start, LocalDate end) {
return start.datesUntil(end.plusDays(1))
.filter(BusinessDayCalculator::esteZiLucratoare)
.count();
}
public static List getUrmatoareleSarbatori(
LocalDate de la, int numar) {
return SARBATORI_2024.stream()
.filter(data -> data.isAfter(de la))
.sorted()
.limit(numar)
.collect(Collectors.toList());
}
public static Map zileLucratoarePeLuna(int an) {
Map rezultat = new EnumMap<>(Month.class);
for (Month luna : Month.values()) {
YearMonth ym = YearMonth.of(an, luna);
LocalDate start = ym.atDay(1);
LocalDate end = ym.atEndOfMonth();
long zileLucr = calculeazaZileLucratoare(start, end);
rezultat.put(luna, zileLucr);
}
return rezultat;
}
}
// Utilizare
LocalDate azi = LocalDate.now();
LocalDate deadline = BusinessDayCalculator.adaugaZileLucratoare(azi, 10);
System.out.println("Deadline (10 zile lucrătoare): " + deadline);
long zileLucr = BusinessDayCalculator.calculeazaZileLucratoare(
LocalDate.of(2024, 3, 1),
LocalDate.of(2024, 3, 31)
);
System.out.println("Zile lucrătoare în martie 2024: " + zileLucr);
System.out.println("\nUrmătoarele sărbători:");
BusinessDayCalculator.getUrmatoareleSarbatori(azi, 3)
.forEach(System.out::println);
System.out.println("\nZile lucrătoare pe lună în 2024:");
BusinessDayCalculator.zileLucratoarePeLuna(2024)
.forEach((luna, zile) -> System.out.printf("%s: %d zile%n", luna, zile));