Generovanie náhodných dátumov v Jave

1. Prehľad

V tomto tutoriáli sa dozvieme, ako generovať náhodné dátumy a časy v ohraničenej a neobmedzenej móde.

Pozrime sa na to, ako tieto hodnoty vygenerovať pomocou pôvodného odkazu java.util.Date API a tiež nová knižnica dátumu a času z Java 8.

2. Náhodný dátum a čas

Dátumy a časy nie sú ničím iným ako 32-bitovými celými číslami v porovnaní s obdobím epochy, takže môžeme generovať náhodné časové hodnoty podľa tohto jednoduchého algoritmu:

  1. Vygenerujte náhodné 32-bitové číslo, an int
  2. Odošlite vygenerovanú náhodnú hodnotu príslušnému konštruktoru alebo staviteľovi vhodného dátumu a času

2.1. Ohraničený Okamžité

java.time.Iokamžité je jedným z nových prírastkov dátumu a času v Jave 8. Predstavujú okamžité body na časovej osi.

Za účelom vygenerovania náhodného Okamžité medzi dvoma ďalšími môžeme:

  1. Vytvorte náhodné číslo medzi epochami daného času Okamžité
  2. Vytvorte náhodný Okamžité odovzdaním náhodného čísla do ofEpochSecond () metóda
public static Okamžité medzi (Instant startInclusive, Instant endExclusive) {long startSeconds = startInclusive.getEpochSecond (); long endSeconds = endExclusive.getEpochSecond (); long random = ThreadLocalRandom .current () .nextLong (startSeconds, endSeconds); return Instant.ofEpochSecond (random); }

Na dosiahnutie vyššej priepustnosti v prostrediach s viacerými vláknami používame ThreadLocalRandom generovať naše náhodné čísla.

Môžeme overiť, že vygenerované Okamžité je vždy väčšie alebo rovné prvému Okamžité a je menej ako druhá Okamžité:

Okamžité stoRokov = Okamžité.now (). Mínus (Trvanie.dní (100 * 365)); Okamžité tenDaysAgo = Instant.now (). Mínus (Duration.ofDays (10)); Okamžité náhodné = RandomDateTimes.b Between (setYearsAgo, tenDaysAgo); assertThat (random) .isB Between (setYearsAgo, tenDaysAgo);

Pamätajte, samozrejme, že testovanie náhodnosti je vo svojej podstate nedeterministické a v reálnej aplikácii sa všeobecne neodporúča.

Podobne je tiež možné vygenerovať náhodný údaj Okamžité po alebo pred iným:

public static Okamžité po (Instant startInclusive) {návrat medzi (startInclusive, Instant.MAX); } public static Instant before (Instant upperExclusive) {návrat medzi (Instant.MIN, upperExclusive); }

2.2. Ohraničený Dátum

Jeden z java.util.Date konštruktéri počítajú počet milisekúnd po epoche. Rovnaký algoritmus teda môžeme použiť na generovanie náhodného výberu Dátum medzi dvoma ďalšími:

public static Dátum medzi (Date startInclusive, Date endExclusive) {long startMillis = startInclusive.getTime (); long endMillis = endExclusive.getTime (); long randomMillisSinceEpoch = ThreadLocalRandom .current () .nextLong (startMillis, endMillis); vrátiť nový dátum (randomMillisSinceEpoch); }

Podobne by sme mali byť schopní overiť toto správanie:

long aDay = TimeUnit.DAYS.toMillis (1); long now = new Date (). getTime (); Dátum setYearsAgo = nový Dátum (teraz - aDay * 365 * 100); Dátum tenDaysAgo = nový Dátum (teraz - aDay * 10); Dátum náhodne = LegacyRandomDateTimes.b Between (setYearsAgo, tenDaysAgo); assertThat (random) .isB Between (setYearsAgo, tenDaysAgo);

2.3. Bez obmedzenia Okamžité

Za účelom vygenerovania úplne náhodného Okamžité, môžeme jednoducho vygenerovať náhodné celé číslo a preniesť ho do ofEpochSecond () metóda:

public static Instant timestamp () {return Instant.ofEpochSecond (ThreadLocalRandom.current (). nextInt ()); }

Použitie 32-bitových sekúnd od času epochy generuje rozumnejšie náhodné časy, teda používame nextInt () metóda tu.

Táto hodnota by mala byť stále medzi minimom a maximom, ktoré sú možné Okamžité hodnoty, ktoré dokáže Java spracovať:

Okamžité náhodné = RandomDateTimes.timestamp (); assertThat (random) .isB Between (Instant.MIN, Instant.MAX);

2.4. Bez obmedzenia Dátum

Podobne ako v obmedzenom príklade, aj my môžeme odovzdať náhodnú hodnotu Termíny konštruktor na vygenerovanie náhodného Dátum:

public static Date timestamp () {return new Date (ThreadLocalRandom.current (). nextInt () * 1000L); }

Keďžečasová jednotka konštruktora je milisekundy, prevedieme 32-bitové epochové sekundy na milisekundy vynásobením číslom 1000.

Táto hodnota je určite stále medzi minimom a maximom, ktoré sú možné Dátum hodnoty:

Dátum MIN_DATE = nový Dátum (Long.MIN_VALUE); Dátum MAX_DATE = nový Dátum (Long.MAX_VALUE); Dátum náhodne = LegacyRandomDateTimes.timestamp (); assertThat (náhodne). je medzi (MIN_DATE, MAX_DATE);

3. Náhodný dátum

Doteraz sme generovali náhodné časové útvary, ktoré obsahovali zložky dátumu aj času. Podobne môžeme použiť koncept epochálnych dní na generovanie náhodných dočasných častí iba s komponentami dátumu.

Epochálny deň sa rovná počtu dní od 1. januára 1970. Aby sme teda vygenerovali náhodný dátum, Musíme vygenerovať náhodné číslo a použiť ho ako epochálny deň.

3.1. Ohraničený

Potrebujeme časovú abstrakciu obsahujúcu iba komponenty dátumu, takže java.time.LocalDate sa javí ako dobrý kandidát:

public static LocalDate between (LocalDate startInclusive, LocalDate endExclusive) {long startEpochDay = startInclusive.toEpochDay (); long endEpochDay = endExclusive.toEpochDay (); long randomDay = ThreadLocalRandom .current () .nextLong (startEpochDay, endEpochDay); return LocalDate.ofEpochDay (randomDay); }

Tu používame toEpochDay () spôsob prevodu každého LocalDate na zodpovedajúcu epochu. Podobne môžeme overiť, či je tento prístup správny:

LocalDate start = LocalDate.of (1989, Month.OCTOBER, 14); LocalDate end = LocalDate.now (); LocalDate random = RandomDates.b Between (začiatok, koniec); assertThat (random) .isB Between (start, end);

3.2. Bez obmedzenia

Aby sme mohli generovať náhodné dátumy bez ohľadu na akýkoľvek rozsah, môžeme jednoducho vygenerovať náhodný epochálny deň:

public static LocalDate date () {int setYears = 100 * 365; return LocalDate.ofEpochDay (ThreadLocalRandom .current (). nextInt (-hundredYears, setYears)); }

Náš generátor náhodných dátumov si vyberie náhodný deň 100 rokov pred a po epoche. Dôvodom je opäť generovanie primeraných hodnôt dátumu:

LocalDate randomDay = RandomDates.date (); assertThat (randomDay) .isB Between (LocalDate.MIN, LocalDate.MAX);

4. Náhodný čas

Podobne ako sme to urobili s dátumami, môžeme generovať náhodné časové úseky len s časovými zložkami. Za týmto účelom môžeme použiť koncept druhého dňa. To znamená, náhodný čas sa rovná náhodnému číslu predstavujúcemu sekundy od začiatku dňa.

4.1. Ohraničený

The java.time.LocalTime trieda je časová abstrakcia, ktorá nezahŕňa nič iné ako časové komponenty:

public static LocalTime medzi (LocalTime startTime, LocalTime endTime) {int startSeconds = startTime.toSecondOfDay (); int endSeconds = endTime.toSecondOfDay (); int randomTime = ThreadLocalRandom .current () .nextInt (startSeconds, endSeconds); návrat LocalTime.ofSecondOfDay (randomTime); }

Aby sme vygenerovali náhodný čas medzi dvoma ďalšími, môžeme:

  1. Medzi druhým dňom daného času vygenerujte náhodné číslo
  2. Vytvorte náhodný čas pomocou tohto náhodného čísla

Chovanie tohto algoritmu generovania náhodného času môžeme ľahko overiť:

LocalTime ráno = LocalTime.of (8, 30); LocalTime randomTime = RandomTimes.b Between (LocalTime.MIDNIGHT, ráno); assertThat (randomTime) .isB Between (LocalTime.MIDNIGHT, ráno) .isB Between (LocalTime.MIN, LocalTime.MAX);

4.2. Bez obmedzenia

Aj neobmedzené časové hodnoty by mali byť v rozsahu 00:00:00 až 23:59:59, takže túto logiku môžeme jednoducho implementovať delegovaním:

public static LocalTime time () {návrat medzi (LocalTime.MIN, LocalTime.MAX); }

5. Záver

V tomto tutoriáli sme obmedzili definíciu náhodných dátumov a časov na náhodné čísla. Potom sme videli, ako nám táto redukcia pomohla vygenerovať náhodné časové hodnoty, ktoré sa správajú ako časové značky, dátumy alebo časy.

Ako obvykle je vzorový kód k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found