time.mojo (1576B)
1 from std.collections import Optional 2 3 4 @fieldwise_init 5 struct DateOnly(Copyable, Movable): 6 var year: Int 7 var month: Int 8 var day: Int 9 10 11 @fieldwise_init 12 struct Timestamp(Copyable, Movable): 13 var epoch_seconds: Int 14 var timezone: Optional[String] 15 16 17 @fieldwise_init 18 struct TimeContext(Copyable, Movable): 19 var source_time: Timestamp 20 var ingestion_time: Timestamp 21 var evaluation_time: Timestamp 22 23 24 def date_only(year: Int, month: Int, day: Int) raises -> DateOnly: 25 if month < 1 or month > 12: 26 raise Error("date month must be between 1 and 12") 27 if day < 1 or day > 31: 28 raise Error("date day must be between 1 and 31") 29 return DateOnly(year=year, month=month, day=day) 30 31 32 def timestamp(epoch_seconds: Int, timezone: String) raises -> Timestamp: 33 if timezone.strip() == "": 34 raise Error("timestamp timezone must not be empty") 35 return Timestamp( 36 epoch_seconds=epoch_seconds, 37 timezone=Optional[String](String(timezone)), 38 ) 39 40 41 def zoneless_timestamp(epoch_seconds: Int) -> Timestamp: 42 return Timestamp(epoch_seconds=epoch_seconds, timezone=None) 43 44 45 def timestamp_has_zone(value: Timestamp) -> Bool: 46 return value.timezone is not None 47 48 49 def time_context( 50 source: Timestamp, ingestion: Timestamp, evaluation: Timestamp 51 ) raises -> TimeContext: 52 if not timestamp_has_zone(source): 53 raise Error("source time requires a known timezone") 54 return TimeContext( 55 source_time=source.copy(), 56 ingestion_time=ingestion.copy(), 57 evaluation_time=evaluation.copy(), 58 )