Skip to content

Utilities

Human-readable value types and ID generators for common programming tasks.

ULID

Universally Unique Lexicographically Sortable Identifiers — 128-bit IDs that are time-ordered and encoded as 26-character strings using Crockford Base32.

scala
import wvlet.uni.util.ULID

// Generate a new ULID
val id = ULID.newULID
println(id)  // e.g., "01arz3ndektsv4rrffq69g5fav"

// Generate as string directly
val idStr: String = ULID.newULIDString

ULID strings use lowercase Crockford Base32 encoding (digits 0-9 and letters a-z excluding i, l, o, u).

Parsing and Validation

scala
// Parse from string (case-insensitive)
val parsed = ULID.fromString("01arz3ndektsv4rrffq69g5fav")

// Validate
ULID.isValid("01arz3ndektsv4rrffq69g5fav")  // true
ULID.isValid("invalid")                      // false

Extracting Timestamps

scala
val id = ULID.newULID

// Timestamp in milliseconds
val millis: Long = id.epochMillis

// Convert to Instant
val instant: java.time.Instant = id.toInstant

// Create from a specific timestamp
val historical = ULID.ofMillis(1609459200000L)

Converting to/from UUID

scala
import java.util.UUID

val ulid = ULID.newULID
val uuid: UUID = ulid.toUUID
val back: ULID = ULID.fromUUID(uuid)

// Binary representation
val bytes: Array[Byte] = ulid.toBytes  // 16 bytes
val fromBytes: ULID = ULID.fromBytes(bytes)

DataSize

Human-readable data size representation with parsing and unit conversion.

scala
import wvlet.uni.util.DataSize

// Parse from string
val size = DataSize("128MB")

// Create from bytes
val fromBytes = DataSize(1073741824L)  // 1GB

// Auto-select best unit
val succinct = DataSize.succinct(1536000L)
println(succinct)  // "1.46MB"

Unit Conversion

scala
val size = DataSize("2.5GB")

size.toBytes                              // 2684354560L
size.valueOf(DataSizeUnit.MEGABYTE)       // 2560.0
size.convertTo(DataSizeUnit.MEGABYTE)     // DataSize(2560.0, MEGABYTE)
size.mostSuccinctDataSize                 // DataSize(2.5, GIGABYTE)

Units

UnitSymbolBytes
BYTEB1
KILOBYTEkB1,024
MEGABYTEMB1,048,576
GIGABYTEGB1,073,741,824
TERABYTETB1,099,511,627,776
PETABYTEPB1,125,899,906,842,624

Count

Human-readable large number representation.

scala
import wvlet.uni.util.Count

// Parse from string
val count = Count("1.5M")

// Auto-select best unit
val succinct = Count.succinct(1500000L)
println(succinct)  // "1.50M"

// Raw value
count.toLong  // 1500000L

Unit Conversion

scala
val count = Count(2500000L)

count.mostSuccinctCount                // Count(2.50, MILLION)
count.convertTo(CountUnit.THOUSAND)    // Count(2500, THOUSAND)
count.valueOf(CountUnit.MILLION)       // 2.5

Units

UnitSymbolValue
ONE(none)1
THOUSANDK1,000
MILLIONM1,000,000
BILLIONB1,000,000,000
TRILLIONT1,000,000,000,000
QUADRILLIONQ1,000,000,000,000,000

ElapsedTime

Human-readable duration representation with unit conversion.

scala
import wvlet.uni.util.ElapsedTime

// Parse from string
val duration = ElapsedTime("5ms")
val timeout  = ElapsedTime("30s")
val window   = ElapsedTime("2.5h")

// Create from measurements
val fromNanos  = ElapsedTime.succinctNanos(1500000L)
println(fromNanos)   // "1.50ms"

val fromMillis = ElapsedTime.succinctMillis(3600000L)
println(fromMillis)  // "1.00h"

// Measure elapsed time
val start = System.nanoTime()
// ... do work ...
val elapsed = ElapsedTime.nanosSince(start)
println(elapsed)  // e.g., "42.30ms"

Unit Conversion

scala
val duration = ElapsedTime("90s")

duration.toMillis                                       // 90000.0
duration.valueIn(java.util.concurrent.TimeUnit.MINUTES) // 1.5
duration.convertToMostSuccinctTimeUnit                  // ElapsedTime(1.50, MINUTES)

Units

UnitSymbolExample
NANOSECONDSns"500ns"
MICROSECONDSus"100us"
MILLISECONDSms"5ms"
SECONDSs"30s"
MINUTESm"5m"
HOURSh"2.5h"
DAYSd"1d"

Best Practices

  1. Use ULID for distributed IDs — they are time-ordered, URL-safe, and monotonic
  2. Use succinct formatting in logs and UIs for readability (DataSize.succinct, Count.succinct)
  3. Parse user input with the string constructors — they handle common formats ("128MB", "1.5M", "30s")
  4. All value types implement Comparable for sorting and comparison

Released under the Apache 2.0 License.