Véletlen dátumok generálása Java-ban

1. Áttekintés

Ebben az oktatóanyagban azt fogjuk megtudni, hogyan lehet véletlen dátumokat és időpontokat generálni korlátozott és korlátlan divatban.

Megvizsgáljuk, hogyan lehet ezeket az értékeket előállítani a örökség segítségével java.util.Dátum API, valamint a Java 8 új dátum-idő könyvtár.

2. Véletlenszerű dátum és idő

A dátumok és idők nem több, mint 32 bites egész számok egy korszakhoz képest, így véletlenszerű időbeli értékeket generálhatunk az egyszerű algoritmus követésével:

  1. Generáljon véletlenszerű 32 bites számot, egy int
  2. Adja át a generált véletlenértéket egy megfelelő dátum- és időszerkesztőnek vagy készítőnek

2.1. Megkötve Azonnali

java.time.Instant a Java 8 egyik új dátum- és idő-kiegészítése. Az idősor pillanatnyi pontjait képviselik.

Egy véletlen generálása érdekében Azonnali két másik között:

  1. Generáljon véletlenszerű számot az adott korszak másodpercei között Azonnali
  2. Hozza létre a véletlenszerűt Azonnali a véletlen szám átadásával a ofEpochSecond () módszer
public static Azonnali (Instant startInclusive, Instant endExclusive) {long startSeconds = startInclusive.getEpochSecond (); long endSeconds = endExclusive.getEpochSecond (); hosszú véletlenszerű = ThreadLocalRandom .current () .nextLong (startSeconds, endSeconds); return Instant.ofEpochSecond (véletlenszerű); }

Annak érdekében, hogy több szálú környezetben nagyobb teljesítményt érjünk el, a ThreadLocalRandom hogy előállítsuk a véletlenszerű számainkat.

Ellenőrizhetjük, hogy a létrehozott Azonnali mindig nagyobb vagy egyenlő az elsővel Azonnali és kevesebb, mint a második Azonnali:

Azonnali száz évAgo = Azonnali most (). Mínusz (Napok időtartama (100 * 365)); Instant tenDaysAgo = Instant.now (). Mínusz (Durations.ofDays (10)); Azonnali véletlenszerű = RandomDateTimes.between (százYearsAgo, tenDaysAgo); assertThat (véletlenszerű) .isBetween (százYearsAgo, tenDaysAgo);

Ne feledje, természetesen, hogy a véletlenszerűség tesztelése eleve nem determinisztikus, és általában nem ajánlott egy valós alkalmazásban.

Hasonlóképpen lehetséges véletlenszerű generálás is Azonnali egy másik után vagy előtt:

public static Azonnali (Instant startInclusive) {visszatérés között (startInclusive, Instant.MAX); } public static Instant before (Instant upperExclusive) {visszatérés között (Instant.MIN, upperExclusive); }

2.2. Megkötve Dátum

Az egyik java.util.Dátum a kivitelezők a korszak után milliszekundumok számát veszik fel. Tehát ugyanazt az algoritmust használhatjuk véletlenszerű generálására Dátum két másik között:

public static Dátum között (Date startInclusive, Date endExclusive) {long startMillis = startInclusive.getTime (); long endMillis = endExclusive.getTime (); hosszú randomMillisSinceEpoch = ThreadLocalRandom .current () .nextLong (startMillis, endMillis); return new Date (randomMillisSinceEpoch); }

Hasonlóképpen képesnek kell lennünk ellenőrizni ezt a viselkedést:

hosszú aDay = TimeUnit.DAYS.toMillis (1); régóta = új dátum (). getTime (); Dátum százYearsAgo = új dátum (most - nap * 365 * 100); Dátum tenDaysAgo = új dátum (most - aDay * 10); Dátum véletlenszerű = LegacyRandomDateTimes.between (százYearsAgo, tenDaysAgo); assertThat (véletlenszerű) .isBetween (százYearsAgo, tenDaysAgo);

2.3. Határtalan Azonnali

Teljesen véletlenszerű generálás érdekében Azonnali, egyszerűen létrehozhatunk egy véletlenszerű egész számot, és átadhatjuk a ofEpochSecond () módszer:

public static Azonnali időbélyeg () {return Instant.ofEpochSecond (ThreadLocalRandom.current (). nextInt ()); }

32 bites másodpercek használata, mivel a korszak ideje ésszerűbb véletlenszerű időket generál, ezért használjuk a nextInt () módszer itt.

Ezen értéknek továbbra is a lehető legkisebb és maximális között kell lennie Azonnali a Java által kezelhető értékek:

Instant random = RandomDateTimes.timestamp (); assertThat (véletlenszerű) .isBetween (Instant.MIN, Instant.MAX);

2.4. Határtalan Dátum

A behatárolt példához hasonlóan véletlenszerű értéket is átadhatunk Dátum konstruktor véletlenszerű generálásához Dátum:

public static Dátum időbélyeg () {return new Date (ThreadLocalRandom.current (). nextInt () * 1000L); }

Mivel aa konstruktor időegysége ezredmásodperc, a 32 bites korszak másodperceket milliszekundummá konvertáljuk, megszorozva 1000-vel.

Természetesen ez az érték még mindig a lehetséges minimum és maximum között van Dátum értékek:

Dátum MIN_DATE = új dátum (Long.MIN_VALUE); Dátum MAX_DATE = új dátum (Long.MAX_VALUE); Dátum véletlenszerű = LegacyRandomDateTimes.timestamp (); assertThat (véletlenszerű) .isBetween (MIN_DATE, MAX_DATE);

3. Véletlenszerű dátum

Eddig véletlenszerű időbeli adatokat generáltunk, amelyek dátum és idő komponenseket egyaránt tartalmaznak. Hasonlóképpen, használhatjuk a korszakos napok fogalmát véletlenszerű időbeli adatok előállításához, csak dátumösszetevőkkel.

Egy korszak napja megegyezik az 1970. január 1-je óta eltelt napok számával. Tehát egy véletlenszerű dátum generálása érdekében csak generálnunk kell egy véletlen számot, és ezt a számot használjuk korszakként.

3.1. Megkötve

Szükségünk van egy időbeli absztrakcióra, amely csak dátumkomponenseket tartalmaz, tehát java.time.LocalDate jó jelöltnek tűnik:

public static LocalDate között (LocalDate startInclusive, LocalDate endExclusive) {long startEpochDay = startInclusive.toEpochDay (); long endEpochDay = endExclusive.toEpochDay (); hosszú randomDay = ThreadLocalRandom .current () .nextLong (startEpochDay, endEpochDay); return LocalDate.ofEpochDay (randomDay); }

Itt használjuk a toEpochDay () módszer az egyes konvertálására LocalDate annak megfelelő korszakának napjáig. Hasonlóképpen ellenőrizhetjük, hogy ez a megközelítés helyes-e:

LocalDate start = LocalDate.of (1989, Month.OCTOBER, 14); LocalDate end = LocalDate.now (); LocalDate random = RandomDates.between (kezdet, vég); assertThat (véletlenszerű) .isBetween (kezdet, vég);

3.2. Határtalan

Annak érdekében, hogy véletlen dátumokat generáljunk bármilyen tartománytól függetlenül, egyszerűen generálhatunk egy véletlenszerű korszakot:

public static LocalDate date () {int száz év = 100 * 365; return LocalDate.ofEpochDay (ThreadLocalRandom .current (). nextInt (-száz év, száz év)); }

Véletlen dátumgenerátorunk véletlenszerű napot választ a korszak előtti és utáni 100 év közül. Ismét ennek oka az ésszerű dátumértékek létrehozása:

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

4. Véletlenszerű idő

Hasonlóan ahhoz, amit a dátumokkal tettünk, véletlenszerű időbeli idők generálására is csak időösszetevőket használunk. Ennek érdekében használhatjuk a nap második fogalmát. Vagyis egy véletlenszerű idő megegyezik egy véletlenszerű számmal, amely a nap eleje óta eltelt másodperceket képviseli.

4.1. Megkötve

A java.time.LocalTime osztály egy időbeli absztrakció, amely csak az idő összetevőit foglalja magában:

public static LocalTime között (LocalTime startTime, LocalTime endTime) {int startSeconds = startTime.toSecondOfDay (); int endSeconds = endTime.toSecondOfDay (); int randomTime = ThreadLocalRandom .current () .nextInt (startSeconds, endSeconds); return LocalTime.ofSecondOfDay (randomTime); }

Két másik között véletlenszerű idő előállításához:

  1. Generáljon véletlenszerű számot a megadott idők napjának második napja között
  2. Hozzon létre egy véletlenszerű időpontot a véletlenszám felhasználásával

Könnyen ellenőrizhetjük ennek a véletlenszerű időgenerációs algoritmusnak a viselkedését:

LocalTime morning = LocalTime.of (8, 30); LocalTime randomTime = RandomTimes.between (LocalTime.MIDNIGHT, reggel); assertThat (randomTime) .isBetween (LocalTime.MIDNIGHT, reggel) .isBetween (LocalTime.MIN, LocalTime.MAX);

4.2. Határtalan

Még a korlátlan időértékeknek is 00:00:00 és 23:59:59 között kell lenniük, így ezt a logikát egyszerűen meghatalmazással tudjuk végrehajtani:

public static LocalTime time () {return between (LocalTime.MIN, LocalTime.MAX); }

5. Következtetés

Ebben az oktatóanyagban a véletlen dátumok és idők meghatározását véletlenszámokra redukáltuk. Aztán láttuk, hogy ez a redukció hogyan segített nekünk véletlenszerű időbeli értékeket létrehozni, úgy viselkedve, mint az időbélyegek, dátumok vagy idők.

Szokás szerint a mintakód elérhető a GitHubon.


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