יצירת תאריכים אקראיים בג'אווה

1. סקירה כללית

במדריך זה, נראה כיצד ליצור תאריכים ושעות אקראיים באופנות מוגבלות ובלתי מוגבלות.

נבדוק כיצד לייצר ערכים אלה באמצעות המורשת java.util.Date API וגם ספריית זמן התאריך החדשה מבית Java 8.

2. תאריך ושעה אקראיים

תאריכים וזמנים הם לא יותר ממספרים שלמים של 32 סיביות בהשוואה לתקופת עידןכך שנוכל ליצור ערכים זמניים אקראיים על ידי ביצוע אלגוריתם פשוט זה:

  1. צור מספר 32 סיביות אקראי, an int
  2. העבר את הערך האקראי שנוצר לבנאי תאריך ושעה או בונה מתאימים

2.1. חָסוּם רֶגַע

java.time.Iנסטנט הוא אחד מתוספות התאריך והשעה החדשות ב- Java 8. הם מייצגים נקודות רגעיות על קו הזמן.

על מנת ליצור אקראי רֶגַע בין שני אחרים, אנו יכולים:

  1. צור מספר אקראי בין עידן השניות של הנתון רגעים
  2. צור את האקראי רֶגַע על ידי העברת המספר האקראי הזה ל ofEpochSecond () שיטה
סטטי ציבורי מיידי בין (Instant startInclusive, Instant endExclusive) {long startSeconds = startInclusive.getEpochSecond (); long endSeconds = endExclusive.getEpochSecond (); ארוך אקראי = ThreadLocalRandom .current () .nextLong (startSeconds, endSeconds); החזר Instant.ofEpochSecond (אקראי); }

על מנת להשיג תפוקה רבה יותר בסביבות מרובות הליכי משנה, אנו משתמשים ב- ThreadLocalRandom כדי ליצור את המספרים האקראיים שלנו.

אנו יכולים לאמת שהנוצר רֶגַע תמיד גדול או שווה לראשון מיידי ו הוא פחות מהשנייה רֶגַע:

מיידי מאה שנים - = Instant.now (). מינוס (Duration.ofDays (100 * 365)); TenDaysAgo מיידי = Instant.now (). מינוס (Duration.ofDays (10)); אקראי מיידי = RandomDateTimes.between (hundredYearsAgo, tenDaysAgo); assertThat (אקראי) .isBetween (hundredYearsAgo, tenDaysAgo);

זכור, כמובן, שבדיקת אקראיות אינה מטבע הדברים דטרמיניסטית ובדרך כלל אינה מומלצת ביישום אמיתי.

באופן דומה, ניתן גם ליצור אקראי רֶגַע אחרי או לפני עוד אחד:

סטטי ציבורי מיידי אחרי (Instant startInclusive) {לחזור בין (startInclusive, Instant.MAX); } סטטי ציבורי מיידי לפני (Instant upperExclusive) {return between (Instant.MIN, upperExclusive); }

2.2. חָסוּם תַאֲרִיך

אחד מ java.util.Date בונים לוקחים את מספר האלפיות השנייה לאחר התקופה. אז נוכל להשתמש באותו אלגוריתם כדי ליצור אקראי תַאֲרִיך בין שניים אחרים:

תאריך סטטי ציבורי בין (תאריך startInclusive, תאריך endExclusive) {long startMillis = startInclusive.getTime (); long endMillis = endExclusive.getTime (); long randomMillisSinceEpoch = ThreadLocalRandom .current () .nextLong (startMillis, endMillis); להחזיר תאריך חדש (randomMillisSinceEpoch); }

באופן דומה, עלינו להיות מסוגלים לאמת התנהגות זו:

aDay ארוך = TimeUnit.DAYS.toMillis (1); זמן רב עכשיו = תאריך חדש (). getTime (); תאריך hundredYearsAgo = תאריך חדש (עכשיו - יום * 365 * 100); תאריך tenDaysAgo = תאריך חדש (עכשיו - יום * 10); תאריך אקראי = LegacyRandomDateTimes.between (hundredYearsAgo, tenDaysAgo); assertThat (אקראי) .isBetween (hundredYearsAgo, tenDaysAgo);

2.3. בִּלתִי מוּגבָּל רֶגַע

על מנת ליצור אקראי לחלוטין רֶגַע, אנחנו יכולים פשוט ליצור מספר שלם אקראי ולהעביר אותו אל ה- ofEpochSecond () שיטה:

חותמת זמן מיידית ציבורית סטטית () {החזרה Instant.ofEpochSecond (ThreadLocalRandom.current (). nextInt ()); }

שימוש בשניות של 32 סיביות מאז תקופת הזמן מייצר זמנים אקראיים סבירים יותר, לפיכך אנו משתמשים ב- nextInt () השיטה כאן.

כמו כן, ערך זה צריך להיות דומם בין המינימום למקסימום האפשרי רֶגַע ערכים שג'אווה יכולה לטפל בהם:

אקראי מיידי = RandomDateTimes.timestamp (); assertThat (אקראי) .isBetween (Instant.MIN, Instant.MAX);

2.4. בִּלתִי מוּגבָּל תַאֲרִיך

בדומה לדוגמא התוחמת, אנו יכולים להעביר ערך אקראי ל- תאריכים בונה לייצר אקראי תַאֲרִיך:

חותמת זמן תאריך סטטי ציבורית () {החזר תאריך חדש (ThreadLocalRandom.current (). nextInt () * 1000L); }

מאזיחידת הזמן של הקונסטרוקטור היא אלפיות השנייה, אנו ממירים את שניות העידן של 32 סיביות לאלפיות השנייה על ידי הכפלתה ב- 1000.

בהחלט, ערך זה עדיין בין המינימום למקסימום האפשרי תַאֲרִיך ערכים:

תאריך MIN_DATE = תאריך חדש (ארוך.MIN_VALUE); תאריך MAX_DATE = תאריך חדש (Long.MAX_VALUE); תאריך אקראי = LegacyRandomDateTimes.timestamp (); assertThat (אקראי) .isBetween (MIN_DATE, MAX_DATE);

3. תאריך אקראי

עד עכשיו יצרנו זמניים אקראיים המכילים רכיבי תאריך ושעה. בדומה לכך, אנו יכולים להשתמש במושג ימי עידן כדי ליצור זמניים אקראיים עם רכיבי תאריך בלבד.

יום עידן שווה למספר הימים מאז ה- 1 בינואר 1970. אז כדי ליצור תאריך אקראי, עלינו רק ליצור מספר אקראי ולהשתמש במספר הזה בתור יום העידן.

3.1. חָסוּם

אנו זקוקים להפשטה זמנית המכילה רכיבי תאריך בלבד, כך java.time.LocalDate נראה כמועמד טוב:

סטטי ציבורי LocalDate בין (LocalDate startInclusive, LocalDate endExclusive) {long startEpochDay = startInclusive.toEpochDay (); endEpochDay = endExclusive.toEpochDay (); long randomDay = ThreadLocalRandom .current () .nextLong (startEpochDay, endEpochDay); החזר LocalDate.ofEpochDay (randomDay); }

כאן אנו משתמשים ב- toEpochDay () שיטה להמיר כל אחת מהן LocalDate ליום העידן המקביל. באופן דומה, אנו יכולים לוודא שגישה זו נכונה:

התחלה LocalDate = LocalDate.of (1989, חודש. OCTOBER, 14); LocalDate end = LocalDate.now (); LocalDate אקראי = RandomDates.between (התחלה, סוף); assertThat (אקראי) .isBetween (התחלה, סוף);

3.2. בִּלתִי מוּגבָּל

על מנת ליצור תאריכים אקראיים ללא קשר לטווח כלשהו, ​​אנו יכולים פשוט ליצור יום עידן אקראי:

תאריך סטטי ציבורי LocalDate () {int hundredYears = 100 * 365; החזר LocalDate.ofEpochDay (ThreadLocalRandom .current (). nextInt (-hundredYears, hundredYears)); }

מחולל התאריכים האקראי שלנו בוחר ביום אקראי מ- 100 שנה לפני ואחרי העידן. שוב, הרציונל שעומד מאחורי זה הוא ליצור ערכי תאריך סבירים:

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

4. זמן אקראי

בדומה למה שעשינו עם תאריכים, אנו יכולים ליצור זמניים אקראיים עם רכיבי זמן בלבד. על מנת לעשות זאת, אנו יכולים להשתמש במושג השני של היום. זה, זמן אקראי שווה למספר אקראי המייצג את השניות מתחילת היום.

4.1. חָסוּם

ה java.time.LocalTime הכיתה היא הפשטה זמנית שאינה מכסה אלא מרכיבי זמן:

סטטי ציבורי LocalTime בין (LocalTime startTime, LocalTime endTime) {int startSeconds = startTime.toSecondOfDay (); int endSeconds = endTime.toSecondOfDay (); int randomTime = ThreadLocalRandom .current () .nextInt (startSeconds, endSeconds); להחזיר LocalTime.ofSecondOfDay (randomTime); }

על מנת ליצור זמן אקראי בין שניים אחרים אנו יכולים:

  1. צור מספר אקראי בין השני ביום של הזמנים הנתונים
  2. צור זמן אקראי באמצעות המספר האקראי הזה

אנו יכולים לאמת בקלות את התנהגות האלגוריתם האקראי הזה לייצור זמן:

בוקר LocalTime = LocalTime.of (8, 30); LocalTime randomTime = RandomTimes.between (LocalTime.MIDNIGHT, בוקר); assertThat (randomTime) .isBetween (LocalTime.MIDNIGHT, בוקר) .isBetween (LocalTime.MIN, LocalTime.MAX);

4.2. בִּלתִי מוּגבָּל

אפילו ערכי זמן בלתי מוגבלים צריכים להיות בטווח של 00:00:00 עד 23:59:59, כך שנוכל פשוט ליישם את ההיגיון הזה על ידי האצלה:

זמן סטטי ציבורי LocalTime () {לחזור בין (LocalTime.MIN, LocalTime.MAX); }

5. מסקנה

במדריך זה צמצמנו את הגדרת התאריכים והשעות האקראיים למספרים אקראיים. ואז ראינו כיצד הפחתה זו עזרה לנו ליצור ערכים זמניים אקראיים המתנהגים כמו חותמות זמן, תאריכים או זמנים.

כרגיל, קוד הדוגמה זמין ב- GitHub.


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